Skip to content

Commit 87a1187

Browse files
LiBaokun96gregkh
authored andcommitted
ext4: avoid overflow when setting values via sysfs
commit 9e8e819 upstream. When setting values of type unsigned int through sysfs, we use kstrtoul() to parse it and then truncate part of it as the final set value, when the set value is greater than UINT_MAX, the set value will not match what we see because of the truncation. As follows: $ echo 4294967296 > /sys/fs/ext4/sda/mb_max_linear_groups $ cat /sys/fs/ext4/sda/mb_max_linear_groups 0 So we use kstrtouint() to parse the attr_pointer_ui type to avoid the inconsistency described above. In addition, a judgment is added to avoid setting s_resv_clusters less than 0. Signed-off-by: Baokun Li <libaokun1@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20240319113325.3110393-2-libaokun1@huawei.com Signed-off-by: Theodore Ts'o <tytso@mit.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 9750135 commit 87a1187

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

fs/ext4/sysfs.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ static ssize_t reserved_clusters_store(struct ext4_sb_info *sbi,
104104
int ret;
105105

106106
ret = kstrtoull(skip_spaces(buf), 0, &val);
107-
if (ret || val >= clusters)
107+
if (ret || val >= clusters || (s64)val < 0)
108108
return -EINVAL;
109109

110110
atomic64_set(&sbi->s_resv_clusters, val);
@@ -451,7 +451,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj,
451451
s_kobj);
452452
struct ext4_attr *a = container_of(attr, struct ext4_attr, attr);
453453
void *ptr = calc_ptr(a, sbi);
454-
unsigned long t;
454+
unsigned int t;
455+
unsigned long lt;
455456
int ret;
456457

457458
switch (a->attr_id) {
@@ -460,7 +461,7 @@ static ssize_t ext4_attr_store(struct kobject *kobj,
460461
case attr_pointer_ui:
461462
if (!ptr)
462463
return 0;
463-
ret = kstrtoul(skip_spaces(buf), 0, &t);
464+
ret = kstrtouint(skip_spaces(buf), 0, &t);
464465
if (ret)
465466
return ret;
466467
if (a->attr_ptr == ptr_ext4_super_block_offset)
@@ -471,10 +472,10 @@ static ssize_t ext4_attr_store(struct kobject *kobj,
471472
case attr_pointer_ul:
472473
if (!ptr)
473474
return 0;
474-
ret = kstrtoul(skip_spaces(buf), 0, &t);
475+
ret = kstrtoul(skip_spaces(buf), 0, &lt);
475476
if (ret)
476477
return ret;
477-
*((unsigned long *) ptr) = t;
478+
*((unsigned long *) ptr) = lt;
478479
return len;
479480
case attr_inode_readahead:
480481
return inode_readahead_blks_store(sbi, buf, len);

0 commit comments

Comments
 (0)