From patchwork Fri Mar 27 16:50:10 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: 6110611 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 23E6CBF90F for ; Fri, 27 Mar 2015 17:04:00 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4F5B1203DA for ; Fri, 27 Mar 2015 17:03:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 4AC60203AD for ; Fri, 27 Mar 2015 17:03:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753745AbbC0RCt (ORCPT ); Fri, 27 Mar 2015 13:02:49 -0400 Received: from mail-wi0-f178.google.com ([209.85.212.178]:37390 "EHLO mail-wi0-f178.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753412AbbC0Qv4 (ORCPT ); Fri, 27 Mar 2015 12:51:56 -0400 Received: by wiaa2 with SMTP id a2so39195411wia.0; Fri, 27 Mar 2015 09:51:54 -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=1v8wPeFYcUeSBuT4hba4rEH/bKs+aSL6pnVMqNX5zOY=; b=y4DSljRbLI6mvYoFa/jI3tnvpWgDvaOXDiTJjcwhBU5s+Rje2sKOXu1rIkKXH93kXy BIVbSI+3v4S/69PrzOFYzjXfizKrGnSV2N90g5PJdwhh2WbtEEiOsr3KYDrXZLokLvqL GNQXC6fIifxSenxs0d+88Qf8G0ZBezS1zPNgDfEocaibvrMX3s6Ajd5toqUGKM+IjIXz mgC3Wd5lXCVmMoVp1aVQ1B4XkFos5Vfnx8Pw35JEnTxWQe1k+b0izlH110XasrrVxy7P Kep2tDYi4sfgFA7PBrwujNHTAna3zWJ5Ke3jqyy8QFmv9fQBCLXoi3XZCTfQ69tRMHVs s/ww== X-Received: by 10.180.102.130 with SMTP id fo2mr57951985wib.30.1427475114442; Fri, 27 Mar 2015 09:51:54 -0700 (PDT) Received: from nuc.home.com (80-110-94-70.cgn.dynamic.surfer.at. [80.110.94.70]) by mx.google.com with ESMTPSA id j7sm3592306wix.4.2015.03.27.09.51.53 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 27 Mar 2015 09:51:53 -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 12/39] richacl: Update the file masks in chmod() Date: Fri, 27 Mar 2015 17:50:10 +0100 Message-Id: <24cc0c8e1765aac080448a711e9719dd0551bbbc.1427471526.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 Doing a chmod() sets the file mode, which includes the file permission bits. When a file has a richacl, the permissions that the richacl grants need to be limited to what the new file permission bits allow. This is done by setting the file masks in the richacl to what the file permission bits map to. The richacl access check algorithm takes the file masks into account, which ensures that the richacl cannot grant too many permissions. It is possible to explicitly add permissions to the file masks which go beyond what the file permission bits can grant (like the ACE4_WRITE_ACL permission). The POSIX.1 standard calls this an alternate file access control mechanism. A subsequent chmod() would ensure that those permissions are disabled again. Signed-off-by: Andreas Gruenbacher --- fs/richacl_base.c | 40 ++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 41 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index d9e557a..a52316b 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -301,3 +301,43 @@ restart: acl->a_flags &= ~RICHACL_MASKED; } EXPORT_SYMBOL_GPL(richacl_compute_max_masks); + +/** + * richacl_chmod - update the file masks to reflect the new mode + * @mode: new file permission bits + * + * Return a copy of @acl where the file masks have been replaced by the file + * masks corresponding to the file permission bits in @mode, or returns @acl + * itself if the file masks are already up to date. Takes over a reference + * to @acl. + */ +struct richacl * +richacl_chmod(struct richacl *acl, mode_t mode) +{ + unsigned int owner_mask, group_mask, other_mask; + struct richacl *clone; + + owner_mask = richacl_mode_to_mask(mode >> 6) | + RICHACE_POSIX_OWNER_ALLOWED; + group_mask = richacl_mode_to_mask(mode >> 3); + other_mask = richacl_mode_to_mask(mode); + + if (acl->a_owner_mask == owner_mask && + acl->a_group_mask == group_mask && + acl->a_other_mask == other_mask && + (acl->a_flags & RICHACL_MASKED)) + return acl; + + clone = richacl_clone(acl, GFP_KERNEL); + richacl_put(acl); + if (!clone) + return ERR_PTR(-ENOMEM); + + clone->a_flags |= RICHACL_MASKED; + clone->a_owner_mask = owner_mask; + clone->a_group_mask = group_mask; + clone->a_other_mask = other_mask; + + return clone; +} +EXPORT_SYMBOL_GPL(richacl_chmod); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 25f45f7..5f5ac81 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -289,5 +289,6 @@ extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(mode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +extern struct richacl *richacl_chmod(struct richacl *, mode_t); #endif /* __RICHACL_H */