Linux nfsd any user can set a file's ACL over NFS and grant access to it

2016.06.25
Credit: David Sinquin
Risk: Medium
Local: Yes
Remote: No
CWE: N/A


CVSS Base Score: 4.9/10
Impact Subscore: 6.9/10
Exploitability Subscore: 3.9/10
Exploit range: Local
Attack complexity: Low
Authentication: No required
Confidentiality impact: Complete
Integrity impact: None
Availability impact: None

Hi David Sinquin reported that anyone may be able to grant themselves permissions to a file by setting the ACL. nfsd did not check permissions when setting ACLs. CVE-2016-1237 was assigned by the Debian security team for this issue were David Singuin initially reported the issue. The permission checks and inode locking were lost in a refactoring with commit 4ac7249ea5a0ceef9f8269f63f33cc873c3fac61 which was in v3.14-rc1. The issue is fixed with commit 999653786df6954a31044528ac3f7a5dadca08f4 in Linus' tree. Introduced in: https://git.kernel.org/linus/4ac7249ea5a0ceef9f8269f63f33cc873c3fac61 (v3.14-rc1) Prerequisite: https://git.kernel.org/linus/485e71e8fb6356c08c7fc6bcce4bf02c9a9a663f Fixed by https://git.kernel.org/linus/999653786df6954a31044528ac3f7a5dadca08f4 diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 8a4a266..edc452c 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -820,39 +820,43 @@ posix_acl_xattr_get(const struct xattr_handler *handler, return error; } -static int -posix_acl_xattr_set(const struct xattr_handler *handler, - struct dentry *unused, struct inode *inode, - const char *name, const void *value, - size_t size, int flags) +int +set_posix_acl(struct inode *inode, int type, struct posix_acl *acl) { - struct posix_acl *acl = NULL; - int ret; - if (!IS_POSIXACL(inode)) return -EOPNOTSUPP; if (!inode->i_op->set_acl) return -EOPNOTSUPP; - if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) - return value ? -EACCES : 0; + if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) + return acl ? -EACCES : 0; if (!inode_owner_or_capable(inode)) return -EPERM; + if (acl) { + int ret = posix_acl_valid(acl); + if (ret) + return ret; + } + return inode->i_op->set_acl(inode, acl, type); +} +EXPORT_SYMBOL(set_posix_acl); + +static int +posix_acl_xattr_set(const struct xattr_handler *handler, + struct dentry *unused, struct inode *inode, + const char *name, const void *value, + size_t size, int flags) +{ + struct posix_acl *acl = NULL; + int ret; + if (value) { acl = posix_acl_from_xattr(&init_user_ns, value, size); if (IS_ERR(acl)) return PTR_ERR(acl); - - if (acl) { - ret = posix_acl_valid(acl); - if (ret) - goto out; - } } - - ret = inode->i_op->set_acl(inode, acl, handler->flags); -out: + ret = set_posix_acl(inode, handler->flags, acl); posix_acl_release(acl); return ret; }

References:

https://git.kernel.org/linus/999653786df6954a31044528ac3f7a5dadca08f4
https://git.kernel.org/linus/485e71e8fb6356c08c7fc6bcce4bf02c9a9a663f


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top