diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-02-07 18:39:12 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-05-15 17:59:26 -0400 |
commit | b8a9f9e183229d163d8ace855cbbb63c209fba3c (patch) | |
tree | bbc939ff827c9ec3220bc5c6177c9964d45cc1e6 /fs/ext2 | |
parent | f04c6ce2cfaff4b982a6c8ad37e07c14379c111c (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.c | 5 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 8 | ||||
-rw-r--r-- | fs/ext2/inode.c | 20 | ||||
-rw-r--r-- | fs/ext2/super.c | 31 |
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 | */ |
638 | struct ext2_mount_options { | 638 | struct 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 | ||