aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-07 18:41:24 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-05-15 17:59:27 -0400
commit1523299d5817773e344d135d4b1c485f269400bc (patch)
treeeef0768f5418facb1d37dbe99f346b9d77223f9f /fs/ext3
parentb8a9f9e183229d163d8ace855cbbb63c209fba3c (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.c5
-rw-r--r--fs/ext3/ext3.h8
-rw-r--r--fs/ext3/inode.c32
-rw-r--r--fs/ext3/super.c35
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 */
244struct ext3_mount_options { 244struct 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
3072again: 3078again:
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);