aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-07 18:39:12 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-05-15 17:59:26 -0400
commitb8a9f9e183229d163d8ace855cbbb63c209fba3c (patch)
treebbc939ff827c9ec3220bc5c6177c9964d45cc1e6 /fs/ext2
parentf04c6ce2cfaff4b982a6c8ad37e07c14379c111c (diff)
userns: Convert ext2 to use kuid/kgid where appropriate.
Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
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/super.c31
4 files changed, 42 insertions, 22 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index a8cbe1bc6ad4..030c6d277e14 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -1193,8 +1193,9 @@ static int ext2_has_free_blocks(struct ext2_sb_info *sbi)
1193 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); 1193 free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
1194 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); 1194 root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
1195 if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && 1195 if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
1196 sbi->s_resuid != current_fsuid() && 1196 !uid_eq(sbi->s_resuid, current_fsuid()) &&
1197 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { 1197 (gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) ||
1198 !in_group_p (sbi->s_resgid))) {
1198 return 0; 1199 return 0;
1199 } 1200 }
1200 return 1; 1201 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/super.c b/fs/ext2/super.c
index e1025c7a437a..38f816071ddb 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -228,13 +228,15 @@ static int ext2_show_options(struct seq_file *seq, struct dentry *root)
228 seq_puts(seq, ",grpid"); 228 seq_puts(seq, ",grpid");
229 if (!test_opt(sb, GRPID) && (def_mount_opts & EXT2_DEFM_BSDGROUPS)) 229 if (!test_opt(sb, GRPID) && (def_mount_opts & EXT2_DEFM_BSDGROUPS))
230 seq_puts(seq, ",nogrpid"); 230 seq_puts(seq, ",nogrpid");
231 if (sbi->s_resuid != EXT2_DEF_RESUID || 231 if (!uid_eq(sbi->s_resuid, make_kuid(&init_user_ns, EXT2_DEF_RESUID)) ||
232 le16_to_cpu(es->s_def_resuid) != EXT2_DEF_RESUID) { 232 le16_to_cpu(es->s_def_resuid) != EXT2_DEF_RESUID) {
233 seq_printf(seq, ",resuid=%u", sbi->s_resuid); 233 seq_printf(seq, ",resuid=%u",
234 from_kuid_munged(&init_user_ns, sbi->s_resuid));
234 } 235 }
235 if (sbi->s_resgid != EXT2_DEF_RESGID || 236 if (!gid_eq(sbi->s_resgid, make_kgid(&init_user_ns, EXT2_DEF_RESGID)) ||
236 le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) { 237 le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) {
237 seq_printf(seq, ",resgid=%u", sbi->s_resgid); 238 seq_printf(seq, ",resgid=%u",
239 from_kgid_munged(&init_user_ns, sbi->s_resgid));
238 } 240 }
239 if (test_opt(sb, ERRORS_RO)) { 241 if (test_opt(sb, ERRORS_RO)) {
240 int def_errors = le16_to_cpu(es->s_errors); 242 int def_errors = le16_to_cpu(es->s_errors);
@@ -436,6 +438,8 @@ static int parse_options(char *options, struct super_block *sb)
436 struct ext2_sb_info *sbi = EXT2_SB(sb); 438 struct ext2_sb_info *sbi = EXT2_SB(sb);
437 substring_t args[MAX_OPT_ARGS]; 439 substring_t args[MAX_OPT_ARGS];
438 int option; 440 int option;
441 kuid_t uid;
442 kgid_t gid;
439 443
440 if (!options) 444 if (!options)
441 return 1; 445 return 1;
@@ -462,12 +466,23 @@ static int parse_options(char *options, struct super_block *sb)
462 case Opt_resuid: 466 case Opt_resuid:
463 if (match_int(&args[0], &option)) 467 if (match_int(&args[0], &option))
464 return 0; 468 return 0;
465 sbi->s_resuid = option; 469 uid = make_kuid(current_user_ns(), option);
470 if (!uid_valid(uid)) {
471 ext2_msg(sb, KERN_ERR, "Invalid uid value %d", option);
472 return -1;
473
474 }
475 sbi->s_resuid = uid;
466 break; 476 break;
467 case Opt_resgid: 477 case Opt_resgid:
468 if (match_int(&args[0], &option)) 478 if (match_int(&args[0], &option))
469 return 0; 479 return 0;
470 sbi->s_resgid = option; 480 gid = make_kgid(current_user_ns(), option);
481 if (!gid_valid(gid)) {
482 ext2_msg(sb, KERN_ERR, "Invalid gid value %d", option);
483 return -1;
484 }
485 sbi->s_resgid = gid;
471 break; 486 break;
472 case Opt_sb: 487 case Opt_sb:
473 /* handled by get_sb_block() instead of here */ 488 /* handled by get_sb_block() instead of here */
@@ -841,8 +856,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
841 else 856 else
842 set_opt(sbi->s_mount_opt, ERRORS_RO); 857 set_opt(sbi->s_mount_opt, ERRORS_RO);
843 858
844 sbi->s_resuid = le16_to_cpu(es->s_def_resuid); 859 sbi->s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid));
845 sbi->s_resgid = le16_to_cpu(es->s_def_resgid); 860 sbi->s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid));
846 861
847 set_opt(sbi->s_mount_opt, RESERVATION); 862 set_opt(sbi->s_mount_opt, RESERVATION);
848 863