From patchwork Wed Feb 25 23:41:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Andreas_Gr=C3=BCnbacher?= X-Patchwork-Id: 5885471 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6CDA49F373 for ; Wed, 25 Feb 2015 23:43:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6CF6E20374 for ; Wed, 25 Feb 2015 23:43:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5769120268 for ; Wed, 25 Feb 2015 23:43:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753937AbbBYXme (ORCPT ); Wed, 25 Feb 2015 18:42:34 -0500 Received: from mail-we0-f181.google.com ([74.125.82.181]:44035 "EHLO mail-we0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932150AbbBYXmb (ORCPT ); Wed, 25 Feb 2015 18:42:31 -0500 Received: by wesk11 with SMTP id k11so6732360wes.11; Wed, 25 Feb 2015 15:42:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references:in-reply-to :references; bh=X7LSlKmCQgqPZprNtRkk4k1OkoRyMRUyti1afTfJOfQ=; b=UN8XTqKRbHEyGI52TaL0cMWEjgkc/LxuZw5InYcqkDeYMnCZEBmk8pAdRWONr6kTi4 QJXuuq+Vz72U2YWpitdptxkjFE1hF0GHQGvivq7gRQOpeLFxFFguzhEUNQyvKJguosD+ FS3xtLET/rbRuvt7Qe8eo+6MOWjtLakSa2jgdZoOhRznu9XWloMgUBczv6yFtPG1Z85R 74p2ybITYs9BDiao3dlMille6qzC5bT544Q41fDLJbso/vNKv+cJIirZ2CkjUne4QlU9 wYblWqY5grTG2mmTl1KhNtfSff/i78Q0TbY7MCFssrRXhZDLOIie1DCjW0csTAsKEGZj 7Bpg== X-Received: by 10.180.211.235 with SMTP id nf11mr11377645wic.52.1424907749235; Wed, 25 Feb 2015 15:42:29 -0800 (PST) Received: from nuc.home.com (80-110-112-196.cgn.dynamic.surfer.at. [80.110.112.196]) by mx.google.com with ESMTPSA id vh8sm66946337wjc.12.2015.02.25.15.42.27 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Feb 2015 15:42:28 -0800 (PST) From: Andreas Gruenbacher X-Google-Original-From: Andreas Gruenbacher To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org Subject: [RFC 16/21] richacl: xattr mapping functions Date: Thu, 26 Feb 2015 00:41:37 +0100 Message-Id: <38f525822b15ec67c337cc90659fecb3737a0767.1424907511.git.agruenba@redhat.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: References: In-Reply-To: References: Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher --- fs/Makefile | 2 +- fs/richacl_xattr.c | 131 ++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 47 +++++++++++++++ 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index bb96ad7..6155cc4 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -48,7 +48,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 0000000..05e5e97 --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(struct richacl_xattr) || + xattr_acl->a_version != ACL4_XATTR_VERSION || + (xattr_acl->a_flags & ~ACL4_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + + count = le16_to_cpu(xattr_acl->a_count); + if (count > ACL4_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~ACE4_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~ACE4_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~ACE4_VALID_MASK) + goto fail_einval; + + if (((void *)xattr_ace + count * sizeof(*xattr_ace)) > (value + size)) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + ace->e_id = le32_to_cpu(xattr_ace->e_id); + + if (ace->e_flags & ~ACE4_VALID_FLAGS) + goto fail_einval; + if (ace->e_type > ACE4_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~ACE4_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer of size richacl_xattr_size(@acl) for the result + */ +void +richacl_to_xattr(const struct richacl *acl, void *buffer) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + + xattr_acl->a_version = ACL4_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags & + ACE4_VALID_FLAGS); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + xattr_ace->e_id = cpu_to_le32(ace->e_id); + xattr_ace++; + } +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 0000000..32ae512 --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include + +#define RICHACL_XATTR "system.richacl" + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define ACL4_XATTR_VERSION 0 +#define ACL4_XATTR_MAX_COUNT 1024 + +extern struct richacl *richacl_from_xattr(const void *, size_t); +extern size_t richacl_xattr_size(const struct richacl *acl); +extern void richacl_to_xattr(const struct richacl *, void *); + +#endif /* __RICHACL_XATTR_H */