summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2018-02-22 04:28:52 -0500
committerJan Kara <jack@suse.cz>2018-02-27 04:25:33 -0500
commit0c9850f4d4c5d645125869fe0fa206fb662bd98b (patch)
tree441eb17e805ce00a37c008c4a63372ee087f4e53
parentecd10aa42819cd5dcf639d25575e95a5bda8d08a (diff)
udf: Clean up handling of invalid uid/gid
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>
-rw-r--r--fs/udf/inode.c21
-rw-r--r--fs/udf/udfdecl.h2
2 files changed, 15 insertions, 8 deletions
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 9021c15cec17..c80765d62f7e 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1275,6 +1275,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
1275 unsigned int indirections = 0; 1275 unsigned int indirections = 0;
1276 int bs = inode->i_sb->s_blocksize; 1276 int bs = inode->i_sb->s_blocksize;
1277 int ret = -EIO; 1277 int ret = -EIO;
1278 uint32_t uid, gid;
1278 1279
1279reread: 1280reread:
1280 if (iloc->partitionReferenceNum >= sbi->s_partitions) { 1281 if (iloc->partitionReferenceNum >= sbi->s_partitions) {
@@ -1400,15 +1401,19 @@ reread:
1400 1401
1401 ret = -EIO; 1402 ret = -EIO;
1402 read_lock(&sbi->s_cred_lock); 1403 read_lock(&sbi->s_cred_lock);
1403 i_uid_write(inode, le32_to_cpu(fe->uid)); 1404 uid = le32_to_cpu(fe->uid);
1404 if (!uid_valid(inode->i_uid) || 1405 if (uid == UDF_INVALID_ID ||
1405 UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET)) 1406 UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_SET))
1406 inode->i_uid = UDF_SB(inode->i_sb)->s_uid; 1407 inode->i_uid = sbi->s_uid;
1408 else
1409 i_uid_write(inode, uid);
1407 1410
1408 i_gid_write(inode, le32_to_cpu(fe->gid)); 1411 gid = le32_to_cpu(fe->gid);
1409 if (!gid_valid(inode->i_gid) || 1412 if (gid == UDF_INVALID_ID ||
1410 UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) 1413 UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET))
1411 inode->i_gid = UDF_SB(inode->i_sb)->s_gid; 1414 inode->i_gid = sbi->s_gid;
1415 else
1416 i_gid_write(inode, gid);
1412 1417
1413 if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && 1418 if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY &&
1414 sbi->s_fmode != UDF_INVALID_MODE) 1419 sbi->s_fmode != UDF_INVALID_MODE)
@@ -1653,12 +1658,12 @@ static int udf_update_inode(struct inode *inode, int do_sync)
1653 } 1658 }
1654 1659
1655 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) 1660 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
1656 fe->uid = cpu_to_le32(-1); 1661 fe->uid = cpu_to_le32(UDF_INVALID_ID);
1657 else 1662 else
1658 fe->uid = cpu_to_le32(i_uid_read(inode)); 1663 fe->uid = cpu_to_le32(i_uid_read(inode));
1659 1664
1660 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) 1665 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
1661 fe->gid = cpu_to_le32(-1); 1666 fe->gid = cpu_to_le32(UDF_INVALID_ID);
1662 else 1667 else
1663 fe->gid = cpu_to_le32(i_gid_read(inode)); 1668 fe->gid = cpu_to_le32(i_gid_read(inode));
1664 1669
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index f5e0fe78979e..68e8a64d22e0 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -48,6 +48,8 @@ extern __printf(3, 4) void _udf_warn(struct super_block *sb,
48#define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF 48#define UDF_EXTENT_LENGTH_MASK 0x3FFFFFFF
49#define UDF_EXTENT_FLAG_MASK 0xC0000000 49#define UDF_EXTENT_FLAG_MASK 0xC0000000
50 50
51#define UDF_INVALID_ID ((uint32_t)-1)
52
51#define UDF_NAME_PAD 4 53#define UDF_NAME_PAD 4
52#define UDF_NAME_LEN 254 54#define UDF_NAME_LEN 254
53#define UDF_NAME_LEN_CS0 255 55#define UDF_NAME_LEN_CS0 255