udf: Apply uid/gid mount options also to new inodes & chown
authorJan Kara <jack@suse.cz>
Wed, 21 Feb 2018 16:59:31 +0000 (17:59 +0100)
committerJan Kara <jack@suse.cz>
Tue, 27 Feb 2018 09:25:33 +0000 (10:25 +0100)
Currently newly created files belong to current user despite
uid=<number> / gid=<number> mount options. This is confusing to users
(as owner of the file will change after remount / eviction from cache)
and also inconsistent with e.g. FAT with the same mount option. So apply
uid=<number> and gid=<number> also to newly created inodes and similarly
as FAT disallow to change owner of the file in this case.

Reported-by: Steve Kenton <skenton@ou.edu>
Reviewed-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/udf/file.c
fs/udf/ialloc.c

index 356c2bf148a5d0932f3813ee91966902ee633dbf..cd31e4f6d6da95a84cfebb629e3c890519d6f431 100644 (file)
@@ -257,12 +257,22 @@ const struct file_operations udf_file_operations = {
 static int udf_setattr(struct dentry *dentry, struct iattr *attr)
 {
        struct inode *inode = d_inode(dentry);
+       struct super_block *sb = inode->i_sb;
        int error;
 
        error = setattr_prepare(dentry, attr);
        if (error)
                return error;
 
+       if ((attr->ia_valid & ATTR_UID) &&
+           UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET) &&
+           !uid_eq(attr->ia_uid, UDF_SB(sb)->s_uid))
+               return -EPERM;
+       if ((attr->ia_valid & ATTR_GID) &&
+           UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET) &&
+           !gid_eq(attr->ia_gid, UDF_SB(sb)->s_gid))
+               return -EPERM;
+
        if ((attr->ia_valid & ATTR_SIZE) &&
            attr->ia_size != i_size_read(inode)) {
                error = udf_setsize(inode, attr->ia_size);
index b6e420c1bfebbc5972bb8a98eda85cf55c672a29..b7a0d4b4bda144015c5f59ce42108b1d2660c07f 100644 (file)
@@ -104,6 +104,10 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode)
        }
 
        inode_init_owner(inode, dir, mode);
+       if (UDF_QUERY_FLAG(sb, UDF_FLAG_UID_SET))
+               inode->i_uid = sbi->s_uid;
+       if (UDF_QUERY_FLAG(sb, UDF_FLAG_GID_SET))
+               inode->i_gid = sbi->s_gid;
 
        iinfo->i_location.logicalBlockNum = block;
        iinfo->i_location.partitionReferenceNum =