udf: Clean up handling of invalid uid/gid
authorJan Kara <jack@suse.cz>
Thu, 22 Feb 2018 09:28:52 +0000 (10:28 +0100)
committerJan Kara <jack@suse.cz>
Tue, 27 Feb 2018 09:25:33 +0000 (10:25 +0100)
Current code relies on the fact that invalid uid/gid as defined by UDF
2.60 3.3.3.1 and 3.3.3.2 coincides with invalid uid/gid as used by the
user namespaces implementation. Since this is only lucky coincidence,
clean this up to avoid future surprises in case user namespaces
implementation changes. Also this is more robust in presence of valid
(from UDF point of view) uids / gids which do not map into current user
namespace.

Reviewed-by: Pali Rohár <pali.rohar@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/udf/inode.c
fs/udf/udfdecl.h

index 9021c15cec17478a9fbff806fddb5caa6e61e9b3..c80765d62f7e9028a3ba2ac282ba2d8c615acbaa 100644 (file)
@@ -1275,6 +1275,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
        unsigned int indirections = 0;
        int bs = inode->i_sb->s_blocksize;
        int ret = -EIO;
+       uint32_t uid, gid;
 
 reread:
        if (iloc->partitionReferenceNum >= sbi->s_partitions) {
@@ -1400,15 +1401,19 @@ reread:
 
        ret = -EIO;
        read_lock(&sbi->s_cred_lock);
-       i_uid_write(inode, le32_to_cpu(fe->uid));
-       if (!uid_valid(inode->i_uid) ||
+       uid = le32_to_cpu(fe->uid);
+       if (uid == UDF_INVALID_ID ||
            UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET))
-               inode->i_uid = UDF_SB(inode->i_sb)->s_uid;
+               inode->i_uid = sbi->s_uid;
+       else
+               i_uid_write(inode, uid);
 
-       i_gid_write(inode, le32_to_cpu(fe->gid));
-       if (!gid_valid(inode->i_gid) ||
+       gid = le32_to_cpu(fe->gid);
+       if (gid == UDF_INVALID_ID ||
            UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
-               inode->i_gid = UDF_SB(inode->i_sb)->s_gid;
+               inode->i_gid = sbi->s_gid;
+       else
+               i_gid_write(inode, gid);
 
        if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
                        sbi->s_fmode != UDF_INVALID_MODE)
@@ -1653,12 +1658,12 @@ static int udf_update_inode(struct inode *inode, int do_sync)
        }
 
        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
-               fe->uid = cpu_to_le32(-1);
+               fe->uid = cpu_to_le32(UDF_INVALID_ID);
        else
                fe->uid = cpu_to_le32(i_uid_read(inode));
 
        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
-               fe->gid = cpu_to_le32(-1);
+               fe->gid = cpu_to_le32(UDF_INVALID_ID);
        else
                fe->gid = cpu_to_le32(i_gid_read(inode));
 
index f5e0fe78979e14940d01d62d2bd8db85c0e14646..68e8a64d22e08a1561516485b45c2a36d622fa40 100644 (file)
@@ -48,6 +48,8 @@ extern __printf(3, 4) void _udf_warn(struct super_block *sb,
 #define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF
 #define UDF_EXTENT_FLAG_MASK   0xC0000000
 
+#define UDF_INVALID_ID ((uint32_t)-1)
+
 #define UDF_NAME_PAD           4
 #define UDF_NAME_LEN           254
 #define UDF_NAME_LEN_CS0       255