lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 16 Aug 2016 13:03:00 +0200 From: Andreas Gruenbacher <agruenba@...hat.com> To: Alexander Viro <viro@...iv.linux.org.uk> Cc: Andreas Gruenbacher <agruenba@...hat.com>, Christoph Hellwig <hch@...radead.org>, "Theodore Ts'o" <tytso@....edu>, Andreas Dilger <adilger.kernel@...ger.ca>, "J. Bruce Fields" <bfields@...ldses.org>, Jeff Layton <jlayton@...chiereds.net>, Trond Myklebust <trond.myklebust@...marydata.com>, Anna Schumaker <anna.schumaker@...app.com>, Dave Chinner <david@...morbit.com>, linux-ext4@...r.kernel.org, xfs@....sgi.com, linux-kernel@...r.kernel.org, linux-fsdevel@...r.kernel.org, linux-nfs@...r.kernel.org, linux-cifs@...r.kernel.org, linux-api@...r.kernel.org Subject: [PATCH v25 19/22] vfs: Add richacl permission checking Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher <agruenba@...hat.com> Reviewed-by: Jeff Layton <jlayton@...hat.com> --- fs/namei.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index ae205ea..63feb3c 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -34,6 +34,7 @@ #include <linux/device_cgroup.h> #include <linux/fs_struct.h> #include <linux/posix_acl.h> +#include <linux/richacl.h> #include <linux/hash.h> #include <linux/bitops.h> #include <linux/init_task.h> @@ -257,7 +258,43 @@ 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 + if (mask & MAY_NOT_BLOCK) { + struct base_acl *base_acl; + + base_acl = rcu_dereference(inode->i_acl); + if (!base_acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (is_uncached_acl(base_acl)) + return -ECHILD; + return richacl_permission(inode, richacl(base_acl), + mask & ~MAY_NOT_BLOCK); + } else { + struct richacl *acl; + + 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 if (mask & MAY_NOT_BLOCK) { @@ -295,11 +332,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; } -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists