Commit c03cad241af63445b751781a09faf08b3a5b77c1
1 parent
949f4a7c08
Exists in
master
and in
4 other branches
udf: Protect default inode credentials by rwlock
Superblock carries credentials (uid, gid, etc.) which are used as default values in __udf_read_inode() when media does not provide these. These credentials can change during remount so we protect them by a rwlock so that each inode gets a consistent set of credentials. Signed-off-by: Jan Kara <jack@suse.cz>
Showing 3 changed files with 14 additions and 7 deletions Side-by-side Diff
fs/udf/inode.c
... | ... | @@ -1201,6 +1201,7 @@ |
1201 | 1201 | return; |
1202 | 1202 | } |
1203 | 1203 | |
1204 | + read_lock(&sbi->s_cred_lock); | |
1204 | 1205 | inode->i_uid = le32_to_cpu(fe->uid); |
1205 | 1206 | if (inode->i_uid == -1 || |
1206 | 1207 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_IGNORE) || |
... | ... | @@ -1213,13 +1214,6 @@ |
1213 | 1214 | UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_SET)) |
1214 | 1215 | inode->i_gid = UDF_SB(inode->i_sb)->s_gid; |
1215 | 1216 | |
1216 | - inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | |
1217 | - if (!inode->i_nlink) | |
1218 | - inode->i_nlink = 1; | |
1219 | - | |
1220 | - inode->i_size = le64_to_cpu(fe->informationLength); | |
1221 | - iinfo->i_lenExtents = inode->i_size; | |
1222 | - | |
1223 | 1217 | if (fe->icbTag.fileType != ICBTAG_FILE_TYPE_DIRECTORY && |
1224 | 1218 | sbi->s_fmode != UDF_INVALID_MODE) |
1225 | 1219 | inode->i_mode = sbi->s_fmode; |
... | ... | @@ -1229,6 +1223,14 @@ |
1229 | 1223 | else |
1230 | 1224 | inode->i_mode = udf_convert_permissions(fe); |
1231 | 1225 | inode->i_mode &= ~sbi->s_umask; |
1226 | + read_unlock(&sbi->s_cred_lock); | |
1227 | + | |
1228 | + inode->i_nlink = le16_to_cpu(fe->fileLinkCount); | |
1229 | + if (!inode->i_nlink) | |
1230 | + inode->i_nlink = 1; | |
1231 | + | |
1232 | + inode->i_size = le64_to_cpu(fe->informationLength); | |
1233 | + iinfo->i_lenExtents = inode->i_size; | |
1232 | 1234 | |
1233 | 1235 | if (iinfo->i_efe == 0) { |
1234 | 1236 | inode->i_blocks = le64_to_cpu(fe->logicalBlocksRecorded) << |
fs/udf/super.c
... | ... | @@ -568,12 +568,14 @@ |
568 | 568 | return -EINVAL; |
569 | 569 | |
570 | 570 | lock_kernel(); |
571 | + write_lock(&sbi->s_cred_lock); | |
571 | 572 | sbi->s_flags = uopt.flags; |
572 | 573 | sbi->s_uid = uopt.uid; |
573 | 574 | sbi->s_gid = uopt.gid; |
574 | 575 | sbi->s_umask = uopt.umask; |
575 | 576 | sbi->s_fmode = uopt.fmode; |
576 | 577 | sbi->s_dmode = uopt.dmode; |
578 | + write_unlock(&sbi->s_cred_lock); | |
577 | 579 | |
578 | 580 | if (sbi->s_lvid_bh) { |
579 | 581 | int write_rev = le16_to_cpu(udf_sb_lvidiu(sbi)->minUDFWriteRev); |
... | ... | @@ -1960,6 +1962,7 @@ |
1960 | 1962 | sbi->s_fmode = uopt.fmode; |
1961 | 1963 | sbi->s_dmode = uopt.dmode; |
1962 | 1964 | sbi->s_nls_map = uopt.nls_map; |
1965 | + rwlock_init(&sbi->s_cred_lock); | |
1963 | 1966 | |
1964 | 1967 | if (uopt.session == 0xFFFFFFFF) |
1965 | 1968 | sbi->s_session = udf_get_last_session(sb); |
fs/udf/udf_sb.h