diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-02-07 18:41:24 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-05-15 17:59:27 -0400 |
commit | 1523299d5817773e344d135d4b1c485f269400bc (patch) | |
tree | eef0768f5418facb1d37dbe99f346b9d77223f9f /fs/ext3 | |
parent | b8a9f9e183229d163d8ace855cbbb63c209fba3c (diff) |
userns: Convert ext3 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/ext3')
-rw-r--r-- | fs/ext3/balloc.c | 5 | ||||
-rw-r--r-- | fs/ext3/ext3.h | 8 | ||||
-rw-r--r-- | fs/ext3/inode.c | 32 | ||||
-rw-r--r-- | fs/ext3/super.c | 35 |
4 files changed, 52 insertions, 28 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index baac1b129fba..25cd60892116 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -1439,8 +1439,9 @@ static int ext3_has_free_blocks(struct ext3_sb_info *sbi, int use_reservation) | |||
1439 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); | 1439 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
1440 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); | 1440 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
1441 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && | 1441 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
1442 | !use_reservation && sbi->s_resuid != current_fsuid() && | 1442 | !use_reservation && !uid_eq(sbi->s_resuid, current_fsuid()) && |
1443 | (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { | 1443 | (gid_eq(sbi->s_resgid, GLOBAL_ROOT_GID) || |
1444 | !in_group_p (sbi->s_resgid))) { | ||
1444 | return 0; | 1445 | return 0; |
1445 | } | 1446 | } |
1446 | return 1; | 1447 | return 1; |
diff --git a/fs/ext3/ext3.h b/fs/ext3/ext3.h index b6515fd7e56c..7977973a24f0 100644 --- a/fs/ext3/ext3.h +++ b/fs/ext3/ext3.h | |||
@@ -243,8 +243,8 @@ struct ext3_new_group_data { | |||
243 | */ | 243 | */ |
244 | struct ext3_mount_options { | 244 | struct ext3_mount_options { |
245 | unsigned long s_mount_opt; | 245 | unsigned long s_mount_opt; |
246 | uid_t s_resuid; | 246 | kuid_t s_resuid; |
247 | gid_t s_resgid; | 247 | kgid_t s_resgid; |
248 | unsigned long s_commit_interval; | 248 | unsigned long s_commit_interval; |
249 | #ifdef CONFIG_QUOTA | 249 | #ifdef CONFIG_QUOTA |
250 | int s_jquota_fmt; | 250 | int s_jquota_fmt; |
@@ -637,8 +637,8 @@ struct ext3_sb_info { | |||
637 | struct buffer_head ** s_group_desc; | 637 | struct buffer_head ** s_group_desc; |
638 | unsigned long s_mount_opt; | 638 | unsigned long s_mount_opt; |
639 | ext3_fsblk_t s_sb_block; | 639 | ext3_fsblk_t s_sb_block; |
640 | uid_t s_resuid; | 640 | kuid_t s_resuid; |
641 | gid_t s_resgid; | 641 | kgid_t s_resgid; |
642 | unsigned short s_mount_state; | 642 | unsigned short s_mount_state; |
643 | unsigned short s_pad; | 643 | unsigned short s_pad; |
644 | int s_addr_per_block_bits; | 644 | int s_addr_per_block_bits; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 10d7812f6021..a09790a412b1 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -2891,6 +2891,8 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) | |||
2891 | transaction_t *transaction; | 2891 | transaction_t *transaction; |
2892 | long ret; | 2892 | long ret; |
2893 | int block; | 2893 | int block; |
2894 | uid_t i_uid; | ||
2895 | gid_t i_gid; | ||
2894 | 2896 | ||
2895 | inode = iget_locked(sb, ino); | 2897 | inode = iget_locked(sb, ino); |
2896 | if (!inode) | 2898 | if (!inode) |
@@ -2907,12 +2909,14 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino) | |||
2907 | bh = iloc.bh; | 2909 | bh = iloc.bh; |
2908 | raw_inode = ext3_raw_inode(&iloc); | 2910 | raw_inode = ext3_raw_inode(&iloc); |
2909 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); | 2911 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
2910 | inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); | 2912 | i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
2911 | inode->i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); | 2913 | i_gid = (gid_t)le16_to_cpu(raw_inode->i_gid_low); |
2912 | if(!(test_opt (inode->i_sb, NO_UID32))) { | 2914 | if(!(test_opt (inode->i_sb, NO_UID32))) { |
2913 | inode->i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; | 2915 | i_uid |= le16_to_cpu(raw_inode->i_uid_high) << 16; |
2914 | inode->i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; | 2916 | i_gid |= le16_to_cpu(raw_inode->i_gid_high) << 16; |
2915 | } | 2917 | } |
2918 | i_uid_write(inode, i_uid); | ||
2919 | i_gid_write(inode, i_gid); | ||
2916 | set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); | 2920 | set_nlink(inode, le16_to_cpu(raw_inode->i_links_count)); |
2917 | inode->i_size = le32_to_cpu(raw_inode->i_size); | 2921 | inode->i_size = le32_to_cpu(raw_inode->i_size); |
2918 | inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); | 2922 | inode->i_atime.tv_sec = (signed)le32_to_cpu(raw_inode->i_atime); |
@@ -3068,6 +3072,8 @@ static int ext3_do_update_inode(handle_t *handle, | |||
3068 | struct ext3_inode_info *ei = EXT3_I(inode); | 3072 | struct ext3_inode_info *ei = EXT3_I(inode); |
3069 | struct buffer_head *bh = iloc->bh; | 3073 | struct buffer_head *bh = iloc->bh; |
3070 | int err = 0, rc, block; | 3074 | int err = 0, rc, block; |
3075 | uid_t i_uid; | ||
3076 | gid_t i_gid; | ||
3071 | 3077 | ||
3072 | again: | 3078 | again: |
3073 | /* we can't allow multiple procs in here at once, its a bit racey */ | 3079 | /* we can't allow multiple procs in here at once, its a bit racey */ |
@@ -3080,27 +3086,29 @@ again: | |||
3080 | 3086 | ||
3081 | ext3_get_inode_flags(ei); | 3087 | ext3_get_inode_flags(ei); |
3082 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); | 3088 | raw_inode->i_mode = cpu_to_le16(inode->i_mode); |
3089 | i_uid = i_uid_read(inode); | ||
3090 | i_gid = i_gid_read(inode); | ||
3083 | if(!(test_opt(inode->i_sb, NO_UID32))) { | 3091 | if(!(test_opt(inode->i_sb, NO_UID32))) { |
3084 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); | 3092 | raw_inode->i_uid_low = cpu_to_le16(low_16_bits(i_uid)); |
3085 | raw_inode->i_gid_low = cpu_to_le16(low_16_bits(inode->i_gid)); | 3093 | raw_inode->i_gid_low = cpu_to_le16(low_16_bits(i_gid)); |
3086 | /* | 3094 | /* |
3087 | * Fix up interoperability with old kernels. Otherwise, old inodes get | 3095 | * Fix up interoperability with old kernels. Otherwise, old inodes get |
3088 | * re-used with the upper 16 bits of the uid/gid intact | 3096 | * re-used with the upper 16 bits of the uid/gid intact |
3089 | */ | 3097 | */ |
3090 | if(!ei->i_dtime) { | 3098 | if(!ei->i_dtime) { |
3091 | raw_inode->i_uid_high = | 3099 | raw_inode->i_uid_high = |
3092 | cpu_to_le16(high_16_bits(inode->i_uid)); | 3100 | cpu_to_le16(high_16_bits(i_uid)); |
3093 | raw_inode->i_gid_high = | 3101 | raw_inode->i_gid_high = |
3094 | cpu_to_le16(high_16_bits(inode->i_gid)); | 3102 | cpu_to_le16(high_16_bits(i_gid)); |
3095 | } else { | 3103 | } else { |
3096 | raw_inode->i_uid_high = 0; | 3104 | raw_inode->i_uid_high = 0; |
3097 | raw_inode->i_gid_high = 0; | 3105 | raw_inode->i_gid_high = 0; |
3098 | } | 3106 | } |
3099 | } else { | 3107 | } else { |
3100 | raw_inode->i_uid_low = | 3108 | raw_inode->i_uid_low = |
3101 | cpu_to_le16(fs_high2lowuid(inode->i_uid)); | 3109 | cpu_to_le16(fs_high2lowuid(i_uid)); |
3102 | raw_inode->i_gid_low = | 3110 | raw_inode->i_gid_low = |
3103 | cpu_to_le16(fs_high2lowgid(inode->i_gid)); | 3111 | cpu_to_le16(fs_high2lowgid(i_gid)); |
3104 | raw_inode->i_uid_high = 0; | 3112 | raw_inode->i_uid_high = 0; |
3105 | raw_inode->i_gid_high = 0; | 3113 | raw_inode->i_gid_high = 0; |
3106 | } | 3114 | } |
@@ -3262,8 +3270,8 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
3262 | 3270 | ||
3263 | if (is_quota_modification(inode, attr)) | 3271 | if (is_quota_modification(inode, attr)) |
3264 | dquot_initialize(inode); | 3272 | dquot_initialize(inode); |
3265 | if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) || | 3273 | if ((ia_valid & ATTR_UID && !uid_eq(attr->ia_uid, inode->i_uid)) || |
3266 | (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) { | 3274 | (ia_valid & ATTR_GID && !gid_eq(attr->ia_gid, inode->i_gid))) { |
3267 | handle_t *handle; | 3275 | handle_t *handle; |
3268 | 3276 | ||
3269 | /* (user+group)*(old+new) structure, inode write (sb, | 3277 | /* (user+group)*(old+new) structure, inode write (sb, |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index cf0b5921cf0f..94ef7e616129 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -617,13 +617,15 @@ static int ext3_show_options(struct seq_file *seq, struct dentry *root) | |||
617 | seq_puts(seq, ",grpid"); | 617 | seq_puts(seq, ",grpid"); |
618 | if (!test_opt(sb, GRPID) && (def_mount_opts & EXT3_DEFM_BSDGROUPS)) | 618 | if (!test_opt(sb, GRPID) && (def_mount_opts & EXT3_DEFM_BSDGROUPS)) |
619 | seq_puts(seq, ",nogrpid"); | 619 | seq_puts(seq, ",nogrpid"); |
620 | if (sbi->s_resuid != EXT3_DEF_RESUID || | 620 | if (!uid_eq(sbi->s_resuid, make_kuid(&init_user_ns, EXT3_DEF_RESUID)) || |
621 | le16_to_cpu(es->s_def_resuid) != EXT3_DEF_RESUID) { | 621 | le16_to_cpu(es->s_def_resuid) != EXT3_DEF_RESUID) { |
622 | seq_printf(seq, ",resuid=%u", sbi->s_resuid); | 622 | seq_printf(seq, ",resuid=%u", |
623 | from_kuid_munged(&init_user_ns, sbi->s_resuid)); | ||
623 | } | 624 | } |
624 | if (sbi->s_resgid != EXT3_DEF_RESGID || | 625 | if (!gid_eq(sbi->s_resgid, make_kgid(&init_user_ns, EXT3_DEF_RESGID)) || |
625 | le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) { | 626 | le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) { |
626 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); | 627 | seq_printf(seq, ",resgid=%u", |
628 | from_kgid_munged(&init_user_ns, sbi->s_resgid)); | ||
627 | } | 629 | } |
628 | if (test_opt(sb, ERRORS_RO)) { | 630 | if (test_opt(sb, ERRORS_RO)) { |
629 | int def_errors = le16_to_cpu(es->s_errors); | 631 | int def_errors = le16_to_cpu(es->s_errors); |
@@ -967,6 +969,8 @@ static int parse_options (char *options, struct super_block *sb, | |||
967 | substring_t args[MAX_OPT_ARGS]; | 969 | substring_t args[MAX_OPT_ARGS]; |
968 | int data_opt = 0; | 970 | int data_opt = 0; |
969 | int option; | 971 | int option; |
972 | kuid_t uid; | ||
973 | kgid_t gid; | ||
970 | #ifdef CONFIG_QUOTA | 974 | #ifdef CONFIG_QUOTA |
971 | int qfmt; | 975 | int qfmt; |
972 | #endif | 976 | #endif |
@@ -1000,12 +1004,23 @@ static int parse_options (char *options, struct super_block *sb, | |||
1000 | case Opt_resuid: | 1004 | case Opt_resuid: |
1001 | if (match_int(&args[0], &option)) | 1005 | if (match_int(&args[0], &option)) |
1002 | return 0; | 1006 | return 0; |
1003 | sbi->s_resuid = option; | 1007 | uid = make_kuid(current_user_ns(), option); |
1008 | if (!uid_valid(uid)) { | ||
1009 | ext3_msg(sb, KERN_ERR, "Invalid uid value %d", option); | ||
1010 | return -1; | ||
1011 | |||
1012 | } | ||
1013 | sbi->s_resuid = uid; | ||
1004 | break; | 1014 | break; |
1005 | case Opt_resgid: | 1015 | case Opt_resgid: |
1006 | if (match_int(&args[0], &option)) | 1016 | if (match_int(&args[0], &option)) |
1007 | return 0; | 1017 | return 0; |
1008 | sbi->s_resgid = option; | 1018 | gid = make_kgid(current_user_ns(), option); |
1019 | if (!gid_valid(gid)) { | ||
1020 | ext3_msg(sb, KERN_ERR, "Invalid gid value %d", option); | ||
1021 | return -1; | ||
1022 | } | ||
1023 | sbi->s_resgid = gid; | ||
1009 | break; | 1024 | break; |
1010 | case Opt_sb: | 1025 | case Opt_sb: |
1011 | /* handled by get_sb_block() instead of here */ | 1026 | /* handled by get_sb_block() instead of here */ |
@@ -1651,8 +1666,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1651 | } | 1666 | } |
1652 | sb->s_fs_info = sbi; | 1667 | sb->s_fs_info = sbi; |
1653 | sbi->s_mount_opt = 0; | 1668 | sbi->s_mount_opt = 0; |
1654 | sbi->s_resuid = EXT3_DEF_RESUID; | 1669 | sbi->s_resuid = make_kuid(&init_user_ns, EXT3_DEF_RESUID); |
1655 | sbi->s_resgid = EXT3_DEF_RESGID; | 1670 | sbi->s_resgid = make_kgid(&init_user_ns, EXT3_DEF_RESGID); |
1656 | sbi->s_sb_block = sb_block; | 1671 | sbi->s_sb_block = sb_block; |
1657 | 1672 | ||
1658 | blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE); | 1673 | blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE); |
@@ -1716,8 +1731,8 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1716 | else | 1731 | else |
1717 | set_opt(sbi->s_mount_opt, ERRORS_RO); | 1732 | set_opt(sbi->s_mount_opt, ERRORS_RO); |
1718 | 1733 | ||
1719 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); | 1734 | sbi->s_resuid = make_kuid(&init_user_ns, le16_to_cpu(es->s_def_resuid)); |
1720 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); | 1735 | sbi->s_resgid = make_kgid(&init_user_ns, le16_to_cpu(es->s_def_resgid)); |
1721 | 1736 | ||
1722 | /* enable barriers by default */ | 1737 | /* enable barriers by default */ |
1723 | set_opt(sbi->s_mount_opt, BARRIER); | 1738 | set_opt(sbi->s_mount_opt, BARRIER); |