Mercurial > illumos > illumos-gate
changeset 9866:ddc5f1d8eb4e
6848431 zfs with rstchown=0 or file_chown_self privilege allows user to "take" ownership
author | Mark Shellenbaum <Mark.Shellenbaum@Sun.COM> |
---|---|
date | Mon, 15 Jun 2009 12:42:25 -0600 |
parents | 60ebbe46c54a |
children | e368ccc44b16 |
files | usr/src/uts/common/fs/zfs/zfs_acl.c usr/src/uts/common/os/policy.c usr/src/uts/common/sys/policy.h |
diffstat | 3 files changed, 25 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/zfs_acl.c Mon Jun 15 12:04:28 2009 -0700 +++ b/usr/src/uts/common/fs/zfs/zfs_acl.c Mon Jun 15 12:42:25 2009 -0600 @@ -2366,8 +2366,7 @@ secpolicy_vnode_access(cr, ZTOV(zp), owner, VREAD) == 0 || secpolicy_vnode_access(cr, ZTOV(zp), owner, VWRITE) == 0 || secpolicy_vnode_access(cr, ZTOV(zp), owner, VEXEC) == 0 || - secpolicy_vnode_chown(cr, B_TRUE) == 0 || - secpolicy_vnode_chown(cr, B_FALSE) == 0 || + secpolicy_vnode_chown(cr, owner) == 0 || secpolicy_vnode_setdac(cr, owner) == 0 || secpolicy_vnode_remove(cr) == 0); } @@ -2515,7 +2514,7 @@ owner, checkmode); if (error == 0 && (working_mode & ACE_WRITE_OWNER)) - error = secpolicy_vnode_chown(cr, B_TRUE); + error = secpolicy_vnode_chown(cr, owner); if (error == 0 && (working_mode & ACE_WRITE_ACL)) error = secpolicy_vnode_setdac(cr, owner); @@ -2524,7 +2523,7 @@ error = secpolicy_vnode_remove(cr); if (error == 0 && (working_mode & ACE_SYNCHRONIZE)) { - error = secpolicy_vnode_chown(cr, B_FALSE); + error = secpolicy_vnode_chown(cr, owner); } if (error == 0) { /*
--- a/usr/src/uts/common/os/policy.c Mon Jun 15 12:04:28 2009 -0700 +++ b/usr/src/uts/common/os/policy.c Mon Jun 15 12:42:25 2009 -0600 @@ -929,16 +929,21 @@ */ int -secpolicy_vnode_chown(const cred_t *cred, boolean_t check_self) +secpolicy_vnode_chown(const cred_t *cred, uid_t owner) { - if (HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN)) - return (PRIV_POLICY(cred, PRIV_FILE_CHOWN, B_FALSE, EPERM, - NULL)); - else if (check_self) - return (PRIV_POLICY(cred, PRIV_FILE_CHOWN_SELF, B_FALSE, EPERM, - NULL)); - else - return (EPERM); + boolean_t is_owner = (owner == crgetuid(cred)); + boolean_t allzone = B_FALSE; + int priv; + + if (!is_owner) { + allzone = (owner == 0); + priv = PRIV_FILE_CHOWN; + } else { + priv = HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN) ? + PRIV_FILE_CHOWN : PRIV_FILE_CHOWN_SELF; + } + + return (PRIV_POLICY(cred, priv, allzone, EPERM, NULL)); } /* @@ -951,7 +956,12 @@ int secpolicy_vnode_create_gid(const cred_t *cred) { - return (secpolicy_vnode_chown(cred, B_TRUE)); + if (HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN)) + return (PRIV_POLICY(cred, PRIV_FILE_CHOWN, B_FALSE, EPERM, + NULL)); + else + return (PRIV_POLICY(cred, PRIV_FILE_CHOWN_SELF, B_FALSE, EPERM, + NULL)); } /* @@ -1211,8 +1221,6 @@ if (mask & (AT_UID|AT_GID)) { boolean_t checkpriv = B_FALSE; - int priv; - boolean_t allzone = B_FALSE; /* * Chowning files. @@ -1232,23 +1240,18 @@ */ if (cr->cr_uid != ovap->va_uid) { checkpriv = B_TRUE; - allzone = (ovap->va_uid == 0); - priv = PRIV_FILE_CHOWN; } else { if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) || ((mask & AT_GID) && vap->va_gid != ovap->va_gid && !groupmember(vap->va_gid, cr))) { checkpriv = B_TRUE; - priv = HAS_PRIVILEGE(cr, PRIV_FILE_CHOWN) ? - PRIV_FILE_CHOWN : PRIV_FILE_CHOWN_SELF; } } /* * If necessary, check privilege to see if update can be done. */ if (checkpriv && - (error = PRIV_POLICY(cr, priv, allzone, EPERM, NULL)) - != 0) { + (error = secpolicy_vnode_chown(cr, ovap->va_uid)) != 0) { goto out; }
--- a/usr/src/uts/common/sys/policy.h Mon Jun 15 12:04:28 2009 -0700 +++ b/usr/src/uts/common/sys/policy.h Mon Jun 15 12:42:25 2009 -0600 @@ -144,7 +144,7 @@ int secpolicy_systeminfo(const cred_t *); int secpolicy_tasksys(const cred_t *); int secpolicy_vnode_access(const cred_t *, vnode_t *, uid_t, mode_t); -int secpolicy_vnode_chown(const cred_t *, boolean_t); +int secpolicy_vnode_chown(const cred_t *, uid_t); int secpolicy_vnode_create_gid(const cred_t *); int secpolicy_vnode_owner(const cred_t *, uid_t); int secpolicy_vnode_remove(const cred_t *);