From 64aefee1b847b747147016c039f5b0e276a9e1b7 Mon Sep 17 00:00:00 2001 From: Nikolay Borisov Date: Thu, 4 Aug 2016 00:31:08 +0300 Subject: [PATCH] Fix interaction between userns uid/gid and SA * When the uid/gid change is handled in zfs_setattr we want to actually adjust the user passed uid to a KUID and write that to disk. * In trace points use the i_uid member without doing translation, since it has already been performed. * Use kuid in zfs_aclset_common Signed-off-by: Nikolay Borisov Signed-off-by: Chunwei Chen Signed-off-by: Brian Behlendorf Closes #4928 --- include/sys/trace_acl.h | 4 ++-- module/zfs/zfs_acl.c | 2 +- module/zfs/zfs_vnops.c | 22 ++++++++++++---------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/include/sys/trace_acl.h b/include/sys/trace_acl.h index bd19c5a16..a49e8b4c0 100644 --- a/include/sys/trace_acl.h +++ b/include/sys/trace_acl.h @@ -99,8 +99,8 @@ DECLARE_EVENT_CLASS(zfs_ace_class, __entry->z_is_ctldir = zn->z_is_ctldir; __entry->z_is_stale = zn->z_is_stale; - __entry->i_uid = zfs_uid_read(ZTOI(zn)); - __entry->i_gid = zfs_gid_read(ZTOI(zn)); + __entry->i_uid = KUID_TO_SUID(ZTOI(zn)->i_uid); + __entry->i_gid = KGID_TO_SGID(ZTOI(zn)->i_gid); __entry->i_ino = zn->z_inode.i_ino; __entry->i_nlink = zn->z_inode.i_nlink; __entry->i_version = zn->z_inode.i_version; diff --git a/module/zfs/zfs_acl.c b/module/zfs/zfs_acl.c index bbb731495..28ebfcc67 100644 --- a/module/zfs/zfs_acl.c +++ b/module/zfs/zfs_acl.c @@ -1326,7 +1326,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) mode = zp->z_mode; mode = zfs_mode_compute(mode, aclp, &zp->z_pflags, - zfs_uid_read(ZTOI(zp)), zfs_gid_read(ZTOI(zp))); + KUID_TO_SUID(ZTOI(zp)->i_uid), KGID_TO_SGID(ZTOI(zp)->i_gid)); zp->z_mode = mode; SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index bde2140d0..707a21114 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -2524,7 +2524,7 @@ zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr) uint_t saved_mask = 0; int trim_mask = 0; uint64_t new_mode; - uint64_t new_uid, new_gid; + uint64_t new_kuid = 0, new_kgid = 0, new_uid, new_gid; uint64_t xattr_obj; uint64_t mtime[2], ctime[2], atime[2]; znode_t *attrzp; @@ -2844,10 +2844,10 @@ top: goto out2; } if (mask & ATTR_UID) { - new_uid = zfs_fuid_create(zsb, + new_kuid = zfs_fuid_create(zsb, (uint64_t)vap->va_uid, cr, ZFS_OWNER, &fuidp); - if (new_uid != KUID_TO_SUID(ZTOI(zp)->i_uid) && - zfs_fuid_overquota(zsb, B_FALSE, new_uid)) { + if (new_kuid != KUID_TO_SUID(ZTOI(zp)->i_uid) && + zfs_fuid_overquota(zsb, B_FALSE, new_kuid)) { if (attrzp) iput(ZTOI(attrzp)); err = EDQUOT; @@ -2856,10 +2856,10 @@ top: } if (mask & ATTR_GID) { - new_gid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid, + new_kgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid, cr, ZFS_GROUP, &fuidp); - if (new_gid != KGID_TO_SGID(ZTOI(zp)->i_gid) && - zfs_fuid_overquota(zsb, B_TRUE, new_gid)) { + if (new_kgid != KGID_TO_SGID(ZTOI(zp)->i_gid) && + zfs_fuid_overquota(zsb, B_TRUE, new_kgid)) { if (attrzp) iput(ZTOI(attrzp)); err = EDQUOT; @@ -2950,9 +2950,10 @@ top: if (mask & (ATTR_UID|ATTR_GID)) { if (mask & ATTR_UID) { + ZTOI(zp)->i_uid = SUID_TO_KUID(new_kuid); + new_uid = zfs_uid_read(ZTOI(zp)); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &new_uid, sizeof (new_uid)); - ZTOI(zp)->i_uid = SUID_TO_KUID(new_uid); if (attrzp) { SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, SA_ZPL_UID(zsb), NULL, &new_uid, @@ -2962,14 +2963,15 @@ top: } if (mask & ATTR_GID) { + ZTOI(zp)->i_gid = SGID_TO_KGID(new_kgid); + new_gid = zfs_gid_read(ZTOI(zp)); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &new_gid, sizeof (new_gid)); - ZTOI(zp)->i_gid = SGID_TO_KGID(new_gid); if (attrzp) { SA_ADD_BULK_ATTR(xattr_bulk, xattr_count, SA_ZPL_GID(zsb), NULL, &new_gid, sizeof (new_gid)); - ZTOI(attrzp)->i_gid = SGID_TO_KGID(new_gid); + ZTOI(attrzp)->i_gid = SGID_TO_KGID(new_kgid); } } if (!(mask & ATTR_MODE)) { -- 2.40.0