aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext2')
-rw-r--r--fs/ext2/balloc.c5
-rw-r--r--fs/ext2/ext2.h8
-rw-r--r--fs/ext2/inode.c20
-rw-r--r--fs/ext2/namei.c2
-rw-r--r--fs/ext2/super.c31
5 files changed, 43 insertions, 23 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 89991ffb0062..1c3613998862 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -1191,8 +1191,9 @@ static int ext2_has_free_blocks(struct ext2_sb_info *sbi)
1191 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); 1191 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
1192 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); 1192 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
1193 if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && 1193 if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
1194 sbi->s_resuid != current_fsuid() && 1194 !uid_eq(sbi->s_resuid, current_fsuid()) &&
1195 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { 1195 (gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) ||
1196 !in_group_p (sbi->s_resgid))) {
1196 return 0; 1197 return 0;
1197 } 1198 }
1198 return 1; 1199 return 1;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 0b2b4db5bdcd..d9a17d0b124d 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -82,8 +82,8 @@ struct ext2_sb_info {
82 struct buffer_head ** s_group_desc; 82 struct buffer_head ** s_group_desc;
83 unsigned long s_mount_opt; 83 unsigned long s_mount_opt;
84 unsigned long s_sb_block; 84 unsigned long s_sb_block;
85 uid_t s_resuid; 85 kuid_t s_resuid;
86 gid_t s_resgid; 86 kgid_t s_resgid;
87 unsigned short s_mount_state; 87 unsigned short s_mount_state;
88 unsigned short s_pad; 88 unsigned short s_pad;
89 int s_addr_per_block_bits; 89 int s_addr_per_block_bits;
@@ -637,8 +637,8 @@ static inline void verify_offsets(void)
637 */ 637 */
638struct ext2_mount_options { 638struct ext2_mount_options {
639 unsigned long s_mount_opt; 639 unsigned long s_mount_opt;
640 uid_t s_resuid; 640 kuid_t s_resuid;
641 gid_t s_resgid; 641 kgid_t s_resgid;
642}; 642};
643 643
644/* 644/*
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 740cad8dcd8d..f9fa95f8443d 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1293,6 +1293,8 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
1293 struct inode *inode; 1293 struct inode *inode;
1294 long ret = -EIO; 1294 long ret = -EIO;
1295 int n; 1295 int n;
1296 uid_t i_uid;
1297 gid_t i_gid;
1296 1298
1297 inode = iget_locked(sb, ino); 1299 inode = iget_locked(sb, ino);
1298 if (!inode) 1300 if (!inode)
@@ -1310,12 +1312,14 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
1310 } 1312 }
1311 1313
1312 inode->i_mode = le16_to_cpu(raw_inode->i_mode); 1314 inode->i_mode = le16_to_cpu(raw_inode->i_mode);
1313 inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); 1315 i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
1314 inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); 1316 i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low);
1315 if (!(test_opt (inode->i_sb, NO_UID32))) { 1317 if (!(test_opt (inode->i_sb, NO_UID32))) {
1316 inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; 1318 i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16;
1317 inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; 1319 i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16;
1318 } 1320 }
1321 i_uid_write(inode, i_uid);
1322 i_gid_write(inode, i_gid);
1319 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); 1323 set_nlink(inode, le16_to_cpu(raw_inode->i_links_count));
1320 inode->i_size = le32_to_cpu(raw_inode->i_size); 1324 inode->i_size = le32_to_cpu(raw_inode->i_size);
1321 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); 1325 inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime);
@@ -1413,8 +1417,8 @@ static int __ext2_write_inode(struct inode *inode, int do_sync)
1413 struct ext2_inode_info *ei = EXT2_I(inode); 1417 struct ext2_inode_info *ei = EXT2_I(inode);
1414 struct super_block *sb = inode->i_sb; 1418 struct super_block *sb = inode->i_sb;
1415 ino_t ino = inode->i_ino; 1419 ino_t ino = inode->i_ino;
1416 uid_t uid = inode->i_uid; 1420 uid_t uid = i_uid_read(inode);
1417 gid_t gid = inode->i_gid; 1421 gid_t gid = i_gid_read(inode);
1418 struct buffer_head * bh; 1422 struct buffer_head * bh;
1419 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh); 1423 struct ext2_inode * raw_inode = ext2_get_inode(sb, ino, &bh);
1420 int n; 1424 int n;
@@ -1529,8 +1533,8 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
1529 1533
1530 if (is_quota_modification(inode, iattr)) 1534 if (is_quota_modification(inode, iattr))
1531 dquot_initialize(inode); 1535 dquot_initialize(inode);
1532 if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) || 1536 if ((iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)) ||
1533 (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) { 1537 (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid))) {
1534 error = dquot_transfer(inode, iattr); 1538 error = dquot_transfer(inode, iattr);
1535 if (error) 1539 if (error)
1536 return error; 1540 return error;
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index dffb86536285..f663a67d7bf0 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -79,7 +79,7 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str
79 79
80struct dentry *ext2_get_parent(struct dentry *child) 80struct dentry *ext2_get_parent(struct dentry *child)
81{ 81{
82 struct qstr dotdot = {.name = "..", .len = 2}; 82 struct qstr dotdot = QSTR_INIT("..", 2);
83 unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot); 83 unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot);
84 if (!ino) 84 if (!ino)
85 return ERR_PTR(-ENOENT); 85 return ERR_PTR(-ENOENT);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index c21f67f8854b..b3621cb7ea31 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -225,13 +225,15 @@ static int ext2_show_options(struct seq_file *seq, struct dentry *root)
225 seq_puts(seq, ",grpid"); 225 seq_puts(seq, ",grpid");
226 if (!test_opt(sb, GRPID) && (def_mount_opts & EXT2_DEFM_BSDGROUPS)) 226 if (!test_opt(sb, GRPID) && (def_mount_opts & EXT2_DEFM_BSDGROUPS))
227 seq_puts(seq, ",nogrpid"); 227 seq_puts(seq, ",nogrpid");
228 if (sbi->s_resuid != EXT2_DEF_RESUID || 228 if (!uid_eq(sbi->s_resuid, make_kuid(&init_user_ns, EXT2_DEF_RESUID)) ||
229 le16_to_cpu(es->s_def_resuid) != EXT2_DEF_RESUID) { 229 le16_to_cpu(es->s_def_resuid) != EXT2_DEF_RESUID) {
230 seq_printf(seq, ",resuid=%u", sbi->s_resuid); 230 seq_printf(seq, ",resuid=%u",
231 from_kuid_munged(&init_user_ns, sbi->s_resuid));
231 } 232 }
232 if (sbi->s_resgid != EXT2_DEF_RESGID || 233 if (!gid_eq(sbi->s_resgid, make_kgid(&init_user_ns, EXT2_DEF_RESGID)) ||
233 le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) { 234 le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) {
234 seq_printf(seq, ",resgid=%u", sbi->s_resgid); 235 seq_printf(seq, ",resgid=%u",
236 from_kgid_munged(&init_user_ns, sbi->s_resgid));
235 } 237 }
236 if (test_opt(sb, ERRORS_RO)) { 238 if (test_opt(sb, ERRORS_RO)) {
237 int def_errors = le16_to_cpu(es->s_errors); 239 int def_errors = le16_to_cpu(es->s_errors);
@@ -427,6 +429,8 @@ static int parse_options(char *options, struct super_block *sb)
427 struct ext2_sb_info *sbi = EXT2_SB(sb); 429 struct ext2_sb_info *sbi = EXT2_SB(sb);
428 substring_t args[MAX_OPT_ARGS]; 430 substring_t args[MAX_OPT_ARGS];
429 int option; 431 int option;
432 kuid_t uid;
433 kgid_t gid;
430 434
431 if (!options) 435 if (!options)
432 return 1; 436 return 1;
@@ -453,12 +457,23 @@ static int parse_options(char *options, struct super_block *sb)
453 case Opt_resuid: 457 case Opt_resuid:
454 if (match_int(&args[0], &option)) 458 if (match_int(&args[0], &option))
455 return 0; 459 return 0;
456 sbi->s_resuid = option; 460 uid = make_kuid(current_user_ns(), option);
461 if (!uid_valid(uid)) {
462 ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option);
463 return -1;
464
465 }
466 sbi->s_resuid = uid;
457 break; 467 break;
458 case Opt_resgid: 468 case Opt_resgid:
459 if (match_int(&args[0], &option)) 469 if (match_int(&args[0], &option))
460 return 0; 470 return 0;
461 sbi->s_resgid = option; 471 gid = make_kgid(current_user_ns(), option);
472 if (!gid_valid(gid)) {
473 ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option);
474 return -1;
475 }
476 sbi->s_resgid = gid;
462 break; 477 break;
463 case Opt_sb: 478 case Opt_sb:
464 /* handled by get_sb_block() instead of here */ 479 /* handled by get_sb_block() instead of here */
@@ -832,8 +847,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
832 else 847 else
833 set_opt(sbi->s_mount_opt, ERRORS_RO); 848 set_opt(sbi->s_mount_opt, ERRORS_RO);
834 849
835 sbi->s_resuid = le16_to_cpu(es->s_def_resuid); 850 sbi->s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid));
836 sbi->s_resgid = le16_to_cpu(es->s_def_resgid); 851 sbi->s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid));
837 852
838 set_opt(sbi->s_mount_opt, RESERVATION); 853 set_opt(sbi->s_mount_opt, RESERVATION);
839 854