From patchwork Fri Apr 24 11:04:19 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: 6267691 Return-Path: X-Original-To: patchwork-linux-nfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2820DBF4A7 for ; Fri, 24 Apr 2015 11:05:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3BCDF202F2 for ; Fri, 24 Apr 2015 11:05:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 45AD82022A for ; Fri, 24 Apr 2015 11:05:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932844AbbDXLF0 (ORCPT ); Fri, 24 Apr 2015 07:05:26 -0400 Received: from mail-wg0-f42.google.com ([74.125.82.42]:36299 "EHLO mail-wg0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932626AbbDXLFW (ORCPT ); Fri, 24 Apr 2015 07:05:22 -0400 Received: by wgen6 with SMTP id n6so46672784wge.3; Fri, 24 Apr 2015 04:05:20 -0700 (PDT) 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=+M060RmVKy6M18FjGJEknTufu1MjRjPA0jnYbAIOJKg=; b=VwDOeIuUKuQaoZSThyzqGt9kBuWI3e1LluQmc+UUZB2xzF/7qrhLvSqxsRzYTerlz0 hdl1YuNdpHxe372JkQMRR8+vFhwejcReJRSURXal4PAULg9TgvfDBDNAEd9G/IioGtUk ar6zFbyRAjR53ahy09W87Rjcn6EhY84uHbLZSLKiiARx1yuKeVCGpRxVuKWSJxo/vjHH FLCw8ILzDCm/gnd4ntlmcYm3QEjM8H3AxcPxdj6OIZavcrYNu6y+NGDLe23dRoSkRzvg YO7TAjFESuFvdDEkwK7OF71Hu3OFywaEHZLK74CV665ja9x8I+jLko/i14inZfmm2UwH xXkA== X-Received: by 10.180.88.8 with SMTP id bc8mr2768807wib.19.1429873520525; Fri, 24 Apr 2015 04:05:20 -0700 (PDT) Received: from nuc.home.com (80-110-112-232.cgn.dynamic.surfer.at. [80.110.112.232]) by mx.google.com with ESMTPSA id ch6sm16410648wjc.3.2015.04.24.04.05.19 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Apr 2015 04:05:19 -0700 (PDT) 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 v3 22/45] vfs: Add richacl permission checking Date: Fri, 24 Apr 2015 13:04:19 +0200 Message-Id: <5b2624871e0ac5f1d0e5c5da6d99ca7dc93158e3.1429868795.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=ham 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 Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher --- fs/namei.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- fs/posix_acl.c | 6 +++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index a8d1674..d5b4fcd 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -256,7 +257,40 @@ void putname(struct filename *name) __putname(name); } -static int check_acl(struct inode *inode, int mask) +static int check_richacl(struct inode *inode, int mask) +{ +#ifdef CONFIG_FS_RICHACL + struct richacl *acl; + + if (mask & MAY_NOT_BLOCK) { + acl = get_cached_richacl_rcu(inode); + if (!acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (acl == ACL_NOT_CACHED) + return -ECHILD; + return richacl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + } + + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + int error = richacl_permission(inode, acl, mask); + richacl_put(acl); + return error; + } +no_acl: +#endif + if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP | + MAY_CHMOD | MAY_SET_TIMES)) { + /* File permission bits cannot grant this. */ + return -EACCES; + } + return -EAGAIN; +} + +static int check_posix_acl(struct inode *inode, int mask) { #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; @@ -291,11 +325,24 @@ static int acl_permission_check(struct inode *inode, int mask) { unsigned int mode = inode->i_mode; + /* + * With POSIX ACLs, the (mode & S_IRWXU) bits exactly match the owner + * permissions, and we can skip checking posix acls for the owner. + * With richacls, the owner may be granted fewer permissions than the + * mode bits seem to suggest (for example, append but not write), and + * we always need to check the richacl. + */ + + if (IS_RICHACL(inode)) { + int error = check_richacl(inode, mask); + if (error != -EAGAIN) + return error; + } if (likely(uid_eq(current_fsuid(), inode->i_uid))) mode >>= 6; else { if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { - int error = check_acl(inode, mask); + int error = check_posix_acl(inode, mask); if (error != -EAGAIN) return error; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index ebf96b2..16464f0 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -100,13 +100,13 @@ struct posix_acl *get_acl(struct inode *inode, int type) { struct posix_acl *acl; + if (!IS_POSIXACL(inode)) + return NULL; + acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; - if (!IS_POSIXACL(inode)) - return NULL; - /* * A filesystem can force a ACL callback by just never filling the * ACL cache. But normally you'd fill the cache either at inode