Author: mav
Date: Thu Aug  2 21:12:52 2018
New Revision: 337182
URL: https://svnweb.freebsd.org/changeset/base/337182

Log:
  9330 stack overflow when creating a deeply nested dataset
  
  Datasets that are deeply nested (~100 levels) are impractical. We just put
  a limit of 50 levels to newly created datasets. Existing datasets should
  work without a problem.
  
  illumos/illumos-gate@5ac95da7d61660aa299c287a39277cb0372be959
  
  Reviewed by: John Kennedy <[email protected]>
  Reviewed by: Matt Ahrens <[email protected]>
  Approved by: Garrett D'Amore <[email protected]>
  Author:     Serapheim Dimitropoulos <[email protected]>

Modified:
  vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c
  vendor/illumos/dist/man/man1m/zfs.1m

Changes in other areas also in this revision:
Modified:
  vendor-sys/illumos/dist/common/zfs/zfs_namecheck.c
  vendor-sys/illumos/dist/common/zfs/zfs_namecheck.h
  vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_objset.c
  vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dir.c

Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c
==============================================================================
--- vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c      Thu Aug  2 
21:07:04 2018        (r337181)
+++ vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c      Thu Aug  2 
21:12:52 2018        (r337182)
@@ -3409,8 +3409,22 @@ zfs_create_ancestors(libzfs_handle_t *hdl, const char 
 {
        int prefix;
        char *path_copy;
+       char errbuf[1024];
        int rc = 0;
 
+       (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
+           "cannot create '%s'"), path);
+
+       /*
+        * Check that we are not passing the nesting limit
+        * before we start creating any ancestors.
+        */
+       if (dataset_nestcheck(path) != 0) {
+               zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+                   "maximum name nesting depth exceeded"));
+               return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+       }
+
        if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
                return (-1);
 
@@ -3446,6 +3460,12 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs
        if (!zfs_validate_name(hdl, path, type, B_TRUE))
                return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
 
+       if (dataset_nestcheck(path) != 0) {
+               zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+                   "maximum name nesting depth exceeded"));
+               return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
+       }
+
        /* validate parents exist */
        if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
                return (-1);
@@ -4233,6 +4253,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, bool
                                    errbuf));
                        }
                }
+
                if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
                        return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
        } else {

Modified: vendor/illumos/dist/man/man1m/zfs.1m
==============================================================================
--- vendor/illumos/dist/man/man1m/zfs.1m        Thu Aug  2 21:07:04 2018        
(r337181)
+++ vendor/illumos/dist/man/man1m/zfs.1m        Thu Aug  2 21:12:52 2018        
(r337182)
@@ -289,7 +289,8 @@ pool/{filesystem,volume,snapshot}
 .Pp
 where the maximum length of a dataset name is
 .Dv MAXNAMELEN
-.Pq 256 bytes .
+.Pq 256 bytes
+and the maximum amount of nesting allowed in a path is 50 levels deep.
 .Pp
 A dataset can be one of the following:
 .Bl -tag -width "file system"
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to