diff options
author | Wang Shilong <wangsl.fnst@cn.fujitsu.com> | 2013-07-23 22:29:05 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-09-01 08:04:28 -0400 |
commit | 2c334e87f31783ca80b7ce265b25ba5489bfad1a (patch) | |
tree | 42f7ab57507b523ef3adb9a553a4612efa069673 /fs/btrfs/super.c | |
parent | 3cd846d1d7640dd6b64d251cb9efd1a490d9a601 (diff) |
Btrfs: add sanity checks regarding to parsing mount options
I just notice the following commands succeed:
mount <dev> <mnt> -o thread_pool=-1
This is ridiculous, only positive thread_pool makes sense,this
patch adds sanity checks for them, and also catches the error of
ENOMEM if allocating memory fails.
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
Reviewed-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8eb6191d86da..cc002959493c 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -496,10 +496,15 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
496 | btrfs_set_opt(info->mount_opt, NOBARRIER); | 496 | btrfs_set_opt(info->mount_opt, NOBARRIER); |
497 | break; | 497 | break; |
498 | case Opt_thread_pool: | 498 | case Opt_thread_pool: |
499 | intarg = 0; | 499 | ret = match_int(&args[0], &intarg); |
500 | match_int(&args[0], &intarg); | 500 | if (ret) { |
501 | if (intarg) | 501 | goto out; |
502 | } else if (intarg > 0) { | ||
502 | info->thread_pool_size = intarg; | 503 | info->thread_pool_size = intarg; |
504 | } else { | ||
505 | ret = -EINVAL; | ||
506 | goto out; | ||
507 | } | ||
503 | break; | 508 | break; |
504 | case Opt_max_inline: | 509 | case Opt_max_inline: |
505 | num = match_strdup(&args[0]); | 510 | num = match_strdup(&args[0]); |
@@ -514,6 +519,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
514 | } | 519 | } |
515 | printk(KERN_INFO "btrfs: max_inline at %llu\n", | 520 | printk(KERN_INFO "btrfs: max_inline at %llu\n", |
516 | (unsigned long long)info->max_inline); | 521 | (unsigned long long)info->max_inline); |
522 | } else { | ||
523 | ret = -ENOMEM; | ||
524 | goto out; | ||
517 | } | 525 | } |
518 | break; | 526 | break; |
519 | case Opt_alloc_start: | 527 | case Opt_alloc_start: |
@@ -526,6 +534,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
526 | printk(KERN_INFO | 534 | printk(KERN_INFO |
527 | "btrfs: allocations start at %llu\n", | 535 | "btrfs: allocations start at %llu\n", |
528 | (unsigned long long)info->alloc_start); | 536 | (unsigned long long)info->alloc_start); |
537 | } else { | ||
538 | ret = -ENOMEM; | ||
539 | goto out; | ||
529 | } | 540 | } |
530 | break; | 541 | break; |
531 | case Opt_noacl: | 542 | case Opt_noacl: |
@@ -540,12 +551,16 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
540 | btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT); | 551 | btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT); |
541 | break; | 552 | break; |
542 | case Opt_ratio: | 553 | case Opt_ratio: |
543 | intarg = 0; | 554 | ret = match_int(&args[0], &intarg); |
544 | match_int(&args[0], &intarg); | 555 | if (ret) { |
545 | if (intarg) { | 556 | goto out; |
557 | } else if (intarg >= 0) { | ||
546 | info->metadata_ratio = intarg; | 558 | info->metadata_ratio = intarg; |
547 | printk(KERN_INFO "btrfs: metadata ratio %d\n", | 559 | printk(KERN_INFO "btrfs: metadata ratio %d\n", |
548 | info->metadata_ratio); | 560 | info->metadata_ratio); |
561 | } else { | ||
562 | ret = -EINVAL; | ||
563 | goto out; | ||
549 | } | 564 | } |
550 | break; | 565 | break; |
551 | case Opt_discard: | 566 | case Opt_discard: |
@@ -596,13 +611,17 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
596 | btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); | 611 | btrfs_set_opt(info->mount_opt, CHECK_INTEGRITY); |
597 | break; | 612 | break; |
598 | case Opt_check_integrity_print_mask: | 613 | case Opt_check_integrity_print_mask: |
599 | intarg = 0; | 614 | ret = match_int(&args[0], &intarg); |
600 | match_int(&args[0], &intarg); | 615 | if (ret) { |
601 | if (intarg) { | 616 | goto out; |
617 | } else if (intarg >= 0) { | ||
602 | info->check_integrity_print_mask = intarg; | 618 | info->check_integrity_print_mask = intarg; |
603 | printk(KERN_INFO "btrfs:" | 619 | printk(KERN_INFO "btrfs:" |
604 | " check_integrity_print_mask 0x%x\n", | 620 | " check_integrity_print_mask 0x%x\n", |
605 | info->check_integrity_print_mask); | 621 | info->check_integrity_print_mask); |
622 | } else { | ||
623 | ret = -EINVAL; | ||
624 | goto out; | ||
606 | } | 625 | } |
607 | break; | 626 | break; |
608 | #else | 627 | #else |
@@ -679,17 +698,25 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
679 | case Opt_subvol: | 698 | case Opt_subvol: |
680 | kfree(*subvol_name); | 699 | kfree(*subvol_name); |
681 | *subvol_name = match_strdup(&args[0]); | 700 | *subvol_name = match_strdup(&args[0]); |
701 | if (!*subvol_name) { | ||
702 | error = -ENOMEM; | ||
703 | goto out; | ||
704 | } | ||
682 | break; | 705 | break; |
683 | case Opt_subvolid: | 706 | case Opt_subvolid: |
684 | intarg = 0; | ||
685 | error = match_int(&args[0], &intarg); | 707 | error = match_int(&args[0], &intarg); |
686 | if (!error) { | 708 | if (!error) { |
709 | goto out; | ||
710 | } else if (intarg >= 0) { | ||
687 | /* we want the original fs_tree */ | 711 | /* we want the original fs_tree */ |
688 | if (!intarg) | 712 | if (!intarg) |
689 | *subvol_objectid = | 713 | *subvol_objectid = |
690 | BTRFS_FS_TREE_OBJECTID; | 714 | BTRFS_FS_TREE_OBJECTID; |
691 | else | 715 | else |
692 | *subvol_objectid = intarg; | 716 | *subvol_objectid = intarg; |
717 | } else { | ||
718 | error = -EINVAL; | ||
719 | goto out; | ||
693 | } | 720 | } |
694 | break; | 721 | break; |
695 | case Opt_subvolrootid: | 722 | case Opt_subvolrootid: |