aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2008-07-24 12:20:14 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:05 -0400
commit5516e5957f4b99b19fffffa53bf9fbe7cc793249 (patch)
treed5d0b0d3850fc37093300920a672b3b051c86a82
parent9652480bf48500885a30754b4a5c436b5b34456d (diff)
Btrfs: Null terminate strings passed in from userspace
The 'char name[BTRFS_PATH_NAME_MAX]' member of struct btrfs_ioctl_vol_args is passed directly to strlen() after being copied from user. I haven't verified this, but in theory a userspace program could pass in an unterminated string and cause a kernel crash as strlen walks off the end of the array. This patch terminates the ->name string in all btrfs ioctl functions which currently use a 'struct btrfs_ioctl_vol_args'. Since the string is now properly terminated, it's length will never be longer than BTRFS_PATH_NAME_MAX so that error check has been removed. By the way, it might be better overall to just have the ioctl pass an unterminated string + length structure but I didn't bother with that since it'd change the kernel/user interface. Signed-off-by: Mark Fasheh <mfasheh@suse.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ioctl.c13
1 files changed, 5 insertions, 8 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 7d40778a90e4..5e627746c4e8 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -310,11 +310,9 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
310 ret = -EFAULT; 310 ret = -EFAULT;
311 goto out; 311 goto out;
312 } 312 }
313
314 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
313 namelen = strlen(vol_args->name); 315 namelen = strlen(vol_args->name);
314 if (namelen > BTRFS_VOL_NAME_MAX) {
315 ret = -EINVAL;
316 goto out;
317 }
318 316
319 mutex_lock(&root->fs_info->volume_mutex); 317 mutex_lock(&root->fs_info->volume_mutex);
320 sizestr = vol_args->name; 318 sizestr = vol_args->name;
@@ -412,11 +410,8 @@ static noinline int btrfs_ioctl_snap_create(struct btrfs_root *root,
412 goto out; 410 goto out;
413 } 411 }
414 412
413 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
415 namelen = strlen(vol_args->name); 414 namelen = strlen(vol_args->name);
416 if (namelen > BTRFS_VOL_NAME_MAX) {
417 ret = -EINVAL;
418 goto out;
419 }
420 if (strchr(vol_args->name, '/')) { 415 if (strchr(vol_args->name, '/')) {
421 ret = -EINVAL; 416 ret = -EINVAL;
422 goto out; 417 goto out;
@@ -487,6 +482,7 @@ long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
487 ret = -EFAULT; 482 ret = -EFAULT;
488 goto out; 483 goto out;
489 } 484 }
485 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
490 ret = btrfs_init_new_device(root, vol_args->name); 486 ret = btrfs_init_new_device(root, vol_args->name);
491 487
492out: 488out:
@@ -508,6 +504,7 @@ long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg)
508 ret = -EFAULT; 504 ret = -EFAULT;
509 goto out; 505 goto out;
510 } 506 }
507 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
511 ret = btrfs_rm_device(root, vol_args->name); 508 ret = btrfs_rm_device(root, vol_args->name);
512 509
513out: 510out: