Whamcloud - gitweb
LU-2164 utils: mkfs.lustre segfaults if no "/" in dataset name
authorNed Bass <bass6@llnl.gov>
Wed, 7 Nov 2012 20:46:13 +0000 (12:46 -0800)
committerOleg Drokin <green@whamcloud.com>
Tue, 8 Jan 2013 06:17:12 +0000 (01:17 -0500)
mkfs.lustre incorrectly assumes that the libzfs function
zfs_name_valid() disallows filesystem names without a "/", and so uses
the result of strrchr(pool, '/') without a NULL check.  In fact
dataset names without a / are permitted, as in the case of commands
like

   zfs get all tank

where a pool tank is treated like a dataset.  The leads to a segfault
if mkfs.lustre is given a dataset name without a /.  Since lustre
datasets are always created as children of a pool, add a separate
check for a missing slash and print an error if it's missing.

Signed-off-by: Ned Bass <bass6@llnl.gov>
Change-Id: Ic7bede9ca19d646f64d2f166f189fa6822a70fe3
Reviewed-on: http://review.whamcloud.com/4490
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/utils/mount_utils_zfs.c

index 96f67fc..e9753b5 100644 (file)
@@ -441,7 +441,7 @@ int zfs_make_lustre(struct mkfs_opts *mop)
                goto out;
        }
 
                goto out;
        }
 
-       /* Due to zfs_name_valid() check the '/' must exist */
+       /* Due to zfs_prepare_lustre() check the '/' must exist */
        strchr(pool, '/')[0] = '\0';
 
        /* If --reformat was given attempt to destroy the previous dataset */
        strchr(pool, '/')[0] = '\0';
 
        /* If --reformat was given attempt to destroy the previous dataset */
@@ -536,18 +536,22 @@ int zfs_prepare_lustre(struct mkfs_opts *mop,
                char *default_mountopts, int default_len,
                char *always_mountopts, int always_len)
 {
                char *default_mountopts, int default_len,
                char *always_mountopts, int always_len)
 {
-       int ret;
-
        if (osd_check_zfs_setup() == 0)
                return EINVAL;
 
        if (osd_check_zfs_setup() == 0)
                return EINVAL;
 
-       ret = zfs_name_valid(mop->mo_device, ZFS_TYPE_FILESYSTEM);
-       if (!ret) {
+       if (zfs_name_valid(mop->mo_device, ZFS_TYPE_FILESYSTEM) == 0) {
                fatal();
                fprintf(stderr, "Invalid filesystem name %s\n", mop->mo_device);
                return EINVAL;
        }
 
                fatal();
                fprintf(stderr, "Invalid filesystem name %s\n", mop->mo_device);
                return EINVAL;
        }
 
+       if (strchr(mop->mo_device, '/') == NULL) {
+               fatal();
+               fprintf(stderr, "Missing pool in filesystem name %s\n",
+                       mop->mo_device);
+               return EINVAL;
+       }
+
        return 0;
 }
 
        return 0;
 }