summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorIgor Kozhukhov <[email protected]>2016-06-15 14:28:36 -0700
committerBrian Behlendorf <[email protected]>2016-06-28 13:47:03 -0700
commiteca7b76001a7d33f78bd98884aef8325bdbf98e7 (patch)
treebdcd0489c5a6c7840258c4c6063c9a4903bec256 /module
parent43e52eddb13d8accbd052fac9a242ce979531aa4 (diff)
OpenZFS 6314 - buffer overflow in dsl_dataset_name
Reviewed by: George Wilson <[email protected]> Reviewed by: Prakash Surya <[email protected]> Reviewed by: Igor Kozhukhov <[email protected]> Approved by: Dan McDonald <[email protected]> Ported-by: Brian Behlendorf <[email protected]> OpenZFS-issue: https://www.illumos.org/issues/6314 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/d6160ee
Diffstat (limited to 'module')
-rw-r--r--module/zcommon/zfs_namecheck.c46
-rw-r--r--module/zfs/dmu_objset.c14
-rw-r--r--module/zfs/dmu_send.c18
-rw-r--r--module/zfs/dsl_bookmark.c4
-rw-r--r--module/zfs/dsl_dataset.c51
-rw-r--r--module/zfs/dsl_deleg.c6
-rw-r--r--module/zfs/dsl_dir.c27
-rw-r--r--module/zfs/dsl_prop.c4
-rw-r--r--module/zfs/dsl_scan.c6
-rw-r--r--module/zfs/dsl_userhold.c6
-rw-r--r--module/zfs/spa.c6
-rw-r--r--module/zfs/spa_history.c6
-rw-r--r--module/zfs/zfs_ctldir.c56
-rw-r--r--module/zfs/zfs_ioctl.c23
-rw-r--r--module/zfs/zfs_vfsops.c2
-rw-r--r--module/zfs/zil.c2
-rw-r--r--module/zfs/zpl_inode.c2
17 files changed, 136 insertions, 143 deletions
diff --git a/module/zcommon/zfs_namecheck.c b/module/zcommon/zfs_namecheck.c
index ff724be58..b58071bed 100644
--- a/module/zcommon/zfs_namecheck.c
+++ b/module/zcommon/zfs_namecheck.c
@@ -69,7 +69,7 @@ zfs_component_namecheck(const char *path, namecheck_err_t *why, char *what)
{
const char *loc;
- if (strlen(path) >= MAXNAMELEN) {
+ if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) {
if (why)
*why = NAME_ERR_TOOLONG;
return (-1);
@@ -140,27 +140,8 @@ dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
/*
* Make sure the name is not too long.
- *
- * ZFS_MAXNAMELEN is the maximum dataset length used in the userland
- * which is the same as MAXNAMELEN used in the kernel.
- * If ZFS_MAXNAMELEN value is changed, make sure to cleanup all
- * places using MAXNAMELEN.
- *
- * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name
- * length is 20 bytes. This 20 bytes is broken down as follows to
- * provide a maximum safe <pool>/<dataset>[@snapshot] length of only
- * 18 bytes. To ensure bytes are left for <dataset>[@snapshot] the
- * <pool> portition is futher limited to 9 bytes. For 2.6.27 and
- * newer kernels this limit is set to MAXNAMELEN.
- *
- * <pool>/<dataset> + <partition> + <newline>
- * (18) + (1) + (1)
*/
-#ifdef HAVE_KOBJ_NAME_LEN
- if (strlen(path) > 18) {
-#else
- if (strlen(path) >= MAXNAMELEN) {
-#endif /* HAVE_KOBJ_NAME_LEN */
+ if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN) {
if (why)
*why = NAME_ERR_TOOLONG;
return (-1);
@@ -289,7 +270,7 @@ mountpoint_namecheck(const char *path, namecheck_err_t *why)
while (*end != '/' && *end != '\0')
end++;
- if (end - start >= MAXNAMELEN) {
+ if (end - start >= ZFS_MAX_DATASET_NAME_LEN) {
if (why)
*why = NAME_ERR_TOOLONG;
return (-1);
@@ -314,27 +295,8 @@ pool_namecheck(const char *pool, namecheck_err_t *why, char *what)
/*
* Make sure the name is not too long.
- *
- * ZPOOL_MAXNAMELEN is the maximum pool length used in the userland
- * which is the same as MAXNAMELEN used in the kernel.
- * If ZPOOL_MAXNAMELEN value is changed, make sure to cleanup all
- * places using MAXNAMELEN.
- *
- * When HAVE_KOBJ_NAME_LEN is defined the maximum safe kobject name
- * length is 20 bytes. This 20 bytes is broken down as follows to
- * provide a maximum safe <pool>/<dataset>[@snapshot] length of only
- * 18 bytes. To ensure bytes are left for <dataset>[@snapshot] the
- * <pool> portition is futher limited to 8 bytes. For 2.6.27 and
- * newer kernels this limit is set to MAXNAMELEN.
- *
- * <pool>/<dataset> + <partition> + <newline>
- * (18) + (1) + (1)
*/
-#ifdef HAVE_KOBJ_NAME_LEN
- if (strlen(pool) > 8) {
-#else
- if (strlen(pool) >= MAXNAMELEN) {
-#endif /* HAVE_KOBJ_NAME_LEN */
+ if (strlen(pool) >= ZFS_MAX_DATASET_NAME_LEN) {
if (why)
*why = NAME_ERR_TOOLONG;
return (-1);
diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c
index a9991aabb..22ca84d96 100644
--- a/module/zfs/dmu_objset.c
+++ b/module/zfs/dmu_objset.c
@@ -671,7 +671,7 @@ dmu_objset_refresh_ownership(objset_t *os, void *tag)
{
dsl_pool_t *dp;
dsl_dataset_t *ds, *newds;
- char name[MAXNAMELEN];
+ char name[ZFS_MAX_DATASET_NAME_LEN];
ds = os->os_dsl_dataset;
VERIFY3P(ds, !=, NULL);
@@ -895,6 +895,9 @@ dmu_objset_create_check(void *arg, dmu_tx_t *tx)
if (strchr(doca->doca_name, '@') != NULL)
return (SET_ERROR(EINVAL));
+ if (strlen(doca->doca_name) >= ZFS_MAX_DATASET_NAME_LEN)
+ return (SET_ERROR(ENAMETOOLONG));
+
error = dsl_dir_hold(dp, doca->doca_name, FTAG, &pdd, &tail);
if (error != 0)
return (error);
@@ -981,6 +984,9 @@ dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
if (strchr(doca->doca_clone, '@') != NULL)
return (SET_ERROR(EINVAL));
+ if (strlen(doca->doca_clone) >= ZFS_MAX_DATASET_NAME_LEN)
+ return (SET_ERROR(ENAMETOOLONG));
+
error = dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail);
if (error != 0)
return (error);
@@ -1020,7 +1026,7 @@ dmu_objset_clone_sync(void *arg, dmu_tx_t *tx)
const char *tail;
dsl_dataset_t *origin, *ds;
uint64_t obj;
- char namebuf[MAXNAMELEN];
+ char namebuf[ZFS_MAX_DATASET_NAME_LEN];
VERIFY0(dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail));
VERIFY0(dsl_dataset_hold(dp, doca->doca_origin, FTAG, &origin));
@@ -2047,7 +2053,7 @@ dmu_objset_get_user(objset_t *os)
/*
* Determine name of filesystem, given name of snapshot.
- * buf must be at least MAXNAMELEN bytes
+ * buf must be at least ZFS_MAX_DATASET_NAME_LEN bytes
*/
int
dmu_fsname(const char *snapname, char *buf)
@@ -2055,7 +2061,7 @@ dmu_fsname(const char *snapname, char *buf)
char *atp = strchr(snapname, '@');
if (atp == NULL)
return (SET_ERROR(EINVAL));
- if (atp - snapname >= MAXNAMELEN)
+ if (atp - snapname >= ZFS_MAX_DATASET_NAME_LEN)
return (SET_ERROR(ENAMETOOLONG));
(void) strlcpy(buf, snapname, atp - snapname + 1);
return (0);
diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c
index 2f4087a67..80f7dc1aa 100644
--- a/module/zfs/dmu_send.c
+++ b/module/zfs/dmu_send.c
@@ -1356,7 +1356,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
dsl_dataset_rele(ds, FTAG);
} else if (error == ENOENT) {
/* target fs does not exist; must be a full backup or clone */
- char buf[MAXNAMELEN];
+ char buf[ZFS_MAX_DATASET_NAME_LEN];
/*
* If it's a non-clone incremental, we are missing the
@@ -1376,7 +1376,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
return (SET_ERROR(EINVAL));
/* Open the parent of tofs */
- ASSERT3U(strlen(tofs), <, MAXNAMELEN);
+ ASSERT3U(strlen(tofs), <, sizeof (buf));
(void) strlcpy(buf, tofs, strrchr(tofs, '/') - tofs + 1);
error = dsl_dataset_hold(dp, buf, FTAG, &ds);
if (error != 0)
@@ -1533,9 +1533,11 @@ dmu_recv_resume_begin_check(void *arg, dmu_tx_t *tx)
uint64_t featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
dsl_dataset_t *ds;
const char *tofs = drba->drba_cookie->drc_tofs;
- char recvname[ZFS_MAXNAMELEN];
uint64_t val;
+ /* 6 extra bytes for /%recv */
+ char recvname[ZFS_MAX_DATASET_NAME_LEN + 6];
+
/* already checked */
ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);
ASSERT(featureflags & DMU_BACKUP_FEATURE_RESUMING);
@@ -1633,7 +1635,8 @@ dmu_recv_resume_begin_sync(void *arg, dmu_tx_t *tx)
const char *tofs = drba->drba_cookie->drc_tofs;
dsl_dataset_t *ds;
uint64_t dsobj;
- char recvname[ZFS_MAXNAMELEN];
+ /* 6 extra bytes for /%recv */
+ char recvname[ZFS_MAX_DATASET_NAME_LEN + 6];
(void) snprintf(recvname, sizeof (recvname), "%s/%s",
tofs, recv_clone_name);
@@ -2359,7 +2362,7 @@ dmu_recv_cleanup_ds(dmu_recv_cookie_t *drc)
txg_wait_synced(drc->drc_ds->ds_dir->dd_pool, 0);
dsl_dataset_disown(drc->drc_ds, dmu_recv_tag);
} else {
- char name[MAXNAMELEN];
+ char name[ZFS_MAX_DATASET_NAME_LEN];
dsl_dataset_name(drc->drc_ds, name);
dsl_dataset_disown(drc->drc_ds, dmu_recv_tag);
(void) dsl_destroy_head(name);
@@ -3191,16 +3194,13 @@ dmu_recv_existing_end(dmu_recv_cookie_t *drc)
int error;
#ifdef _KERNEL
- char *name;
-
/*
* We will be destroying the ds; make sure its origin is unmounted if
* necessary.
*/
- name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ char name[ZFS_MAX_DATASET_NAME_LEN];
dsl_dataset_name(drc->drc_ds, name);
zfs_destroy_unmount_origin(name);
- kmem_free(name, MAXNAMELEN);
#endif
error = dsl_sync_task(drc->drc_tofs,
diff --git a/module/zfs/dsl_bookmark.c b/module/zfs/dsl_bookmark.c
index 447a3a2dc..5a7f034ce 100644
--- a/module/zfs/dsl_bookmark.c
+++ b/module/zfs/dsl_bookmark.c
@@ -34,10 +34,10 @@ static int
dsl_bookmark_hold_ds(dsl_pool_t *dp, const char *fullname,
dsl_dataset_t **dsp, void *tag, char **shortnamep)
{
- char buf[MAXNAMELEN];
+ char buf[ZFS_MAX_DATASET_NAME_LEN];
char *hashp;
- if (strlen(fullname) >= MAXNAMELEN)
+ if (strlen(fullname) >= ZFS_MAX_DATASET_NAME_LEN)
return (SET_ERROR(ENAMETOOLONG));
hashp = strchr(fullname, '#');
if (hashp == NULL)
diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c
index 3d1115e31..5b7de74dc 100644
--- a/module/zfs/dsl_dataset.c
+++ b/module/zfs/dsl_dataset.c
@@ -670,22 +670,38 @@ dsl_dataset_name(dsl_dataset_t *ds, char *name)
dsl_dir_name(ds->ds_dir, name);
VERIFY0(dsl_dataset_get_snapname(ds));
if (ds->ds_snapname[0]) {
- (void) strcat(name, "@");
+ VERIFY3U(strlcat(name, "@", ZFS_MAX_DATASET_NAME_LEN),
+ <, ZFS_MAX_DATASET_NAME_LEN);
/*
* We use a "recursive" mutex so that we
* can call dprintf_ds() with ds_lock held.
*/
if (!MUTEX_HELD(&ds->ds_lock)) {
mutex_enter(&ds->ds_lock);
- (void) strcat(name, ds->ds_snapname);
+ VERIFY3U(strlcat(name, ds->ds_snapname,
+ ZFS_MAX_DATASET_NAME_LEN), <,
+ ZFS_MAX_DATASET_NAME_LEN);
mutex_exit(&ds->ds_lock);
} else {
- (void) strcat(name, ds->ds_snapname);
+ VERIFY3U(strlcat(name, ds->ds_snapname,
+ ZFS_MAX_DATASET_NAME_LEN), <,
+ ZFS_MAX_DATASET_NAME_LEN);
}
}
}
}
+int
+dsl_dataset_namelen(dsl_dataset_t *ds)
+{
+ int len;
+ VERIFY0(dsl_dataset_get_snapname(ds));
+ mutex_enter(&ds->ds_lock);
+ len = dsl_dir_namelen(ds->ds_dir) + 1 + strlen(ds->ds_snapname);
+ mutex_exit(&ds->ds_lock);
+ return (len);
+}
+
void
dsl_dataset_rele(dsl_dataset_t *ds, void *tag)
{
@@ -1255,10 +1271,10 @@ dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx)
int error = 0;
dsl_dataset_t *ds;
char *name, *atp;
- char dsname[MAXNAMELEN];
+ char dsname[ZFS_MAX_DATASET_NAME_LEN];
name = nvpair_name(pair);
- if (strlen(name) >= MAXNAMELEN)
+ if (strlen(name) >= ZFS_MAX_DATASET_NAME_LEN)
error = SET_ERROR(ENAMETOOLONG);
if (error == 0) {
atp = strchr(name, '@');
@@ -1431,7 +1447,7 @@ dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx)
pair != NULL; pair = nvlist_next_nvpair(ddsa->ddsa_snaps, pair)) {
dsl_dataset_t *ds;
char *name, *atp;
- char dsname[MAXNAMELEN];
+ char dsname[ZFS_MAX_DATASET_NAME_LEN];
name = nvpair_name(pair);
atp = strchr(name, '@');
@@ -1478,7 +1494,7 @@ dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors)
suspended = fnvlist_alloc();
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
pair = nvlist_next_nvpair(snaps, pair)) {
- char fsname[MAXNAMELEN];
+ char fsname[ZFS_MAX_DATASET_NAME_LEN];
char *snapname = nvpair_name(pair);
char *atp;
void *cookie;
@@ -1687,7 +1703,7 @@ get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
zap_cursor_retrieve(&zc, &za) == 0;
zap_cursor_advance(&zc)) {
dsl_dataset_t *clone;
- char buf[ZFS_MAXNAMELEN];
+ char buf[ZFS_MAX_DATASET_NAME_LEN];
VERIFY0(dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
za.za_first_integer, FTAG, &clone));
dsl_dir_name(clone->ds_dir, buf);
@@ -1797,7 +1813,7 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
get_clones_stat(ds, nv);
} else {
if (ds->ds_prev != NULL && ds->ds_prev != dp->dp_origin_snap) {
- char buf[MAXNAMELEN];
+ char buf[ZFS_MAX_DATASET_NAME_LEN];
dsl_dataset_name(ds->ds_prev, buf);
dsl_prop_nvlist_add_string(nv, ZFS_PROP_PREV_SNAP, buf);
}
@@ -1848,8 +1864,9 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
}
if (!dsl_dataset_is_snapshot(ds)) {
+ /* 6 extra bytes for /%recv */
+ char recvname[ZFS_MAX_DATASET_NAME_LEN + 6];
dsl_dataset_t *recv_ds;
- char recvname[ZFS_MAXNAMELEN];
/*
* A failed "newfs" (e.g. full) resumable receive leaves
@@ -1863,9 +1880,11 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
* for the prop.
*/
dsl_dataset_name(ds, recvname);
- (void) strcat(recvname, "/");
- (void) strcat(recvname, recv_clone_name);
- if (dsl_dataset_hold(dp, recvname, FTAG, &recv_ds) == 0) {
+ if (strlcat(recvname, "/", sizeof (recvname)) <
+ sizeof (recvname) &&
+ strlcat(recvname, recv_clone_name, sizeof (recvname)) <
+ sizeof (recvname) &&
+ dsl_dataset_hold(dp, recvname, FTAG, &recv_ds) == 0) {
get_receive_resume_stats(recv_ds, nv);
dsl_dataset_rele(recv_ds, FTAG);
}
@@ -1990,7 +2009,7 @@ dsl_dataset_rename_snapshot_check_impl(dsl_pool_t *dp,
/* dataset name + 1 for the "@" + the new snapshot name must fit */
if (dsl_dir_namelen(hds->ds_dir) + 1 +
- strlen(ddrsa->ddrsa_newsnapname) >= MAXNAMELEN)
+ strlen(ddrsa->ddrsa_newsnapname) >= ZFS_MAX_DATASET_NAME_LEN)
error = SET_ERROR(ENAMETOOLONG);
return (error);
@@ -2223,7 +2242,7 @@ dsl_dataset_rollback_sync(void *arg, dmu_tx_t *tx)
dsl_pool_t *dp = dmu_tx_pool(tx);
dsl_dataset_t *ds, *clone;
uint64_t cloneobj;
- char namebuf[ZFS_MAXNAMELEN];
+ char namebuf[ZFS_MAX_DATASET_NAME_LEN];
VERIFY0(dsl_dataset_hold(dp, ddra->ddra_fsname, FTAG, &ds));
@@ -2776,7 +2795,7 @@ promote_rele(dsl_dataset_promote_arg_t *ddpa, void *tag)
* Promote a clone.
*
* If it fails due to a conflicting snapshot name, "conflsnap" will be filled
- * in with the name. (It must be at least MAXNAMELEN bytes long.)
+ * in with the name. (It must be at least ZFS_MAX_DATASET_NAME_LEN bytes long.)
*/
int
dsl_dataset_promote(const char *name, char *conflsnap)
diff --git a/module/zfs/dsl_deleg.c b/module/zfs/dsl_deleg.c
index 952422be2..eb39cff57 100644
--- a/module/zfs/dsl_deleg.c
+++ b/module/zfs/dsl_deleg.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
*/
/*
@@ -330,7 +330,7 @@ dsl_deleg_get(const char *ddname, nvlist_t **nvp)
za = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
basezc = kmem_alloc(sizeof (zap_cursor_t), KM_SLEEP);
baseza = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
- source = kmem_alloc(MAXNAMELEN + strlen(MOS_DIR_NAME) + 1, KM_SLEEP);
+ source = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
for (dd = startdd; dd != NULL; dd = dd->dd_parent) {
@@ -370,7 +370,7 @@ dsl_deleg_get(const char *ddname, nvlist_t **nvp)
nvlist_free(sp_nvp);
}
- kmem_free(source, MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
+ kmem_free(source, ZFS_MAX_DATASET_NAME_LEN);
kmem_free(baseza, sizeof (zap_attribute_t));
kmem_free(basezc, sizeof (zap_cursor_t));
kmem_free(za, sizeof (zap_attribute_t));
diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c
index 8983e0793..ae67b362e 100644
--- a/module/zfs/dsl_dir.c
+++ b/module/zfs/dsl_dir.c
@@ -299,13 +299,14 @@ dsl_dir_async_rele(dsl_dir_t *dd, void *tag)
dmu_buf_rele(dd->dd_dbuf, tag);
}
-/* buf must be long enough (MAXNAMELEN + strlen(MOS_DIR_NAME) + 1 should do) */
+/* buf must be at least ZFS_MAX_DATASET_NAME_LEN bytes */
void
dsl_dir_name(dsl_dir_t *dd, char *buf)
{
if (dd->dd_parent) {
dsl_dir_name(dd->dd_parent, buf);
- (void) strcat(buf, "/");
+ VERIFY3U(strlcat(buf, "/", ZFS_MAX_DATASET_NAME_LEN), <,
+ ZFS_MAX_DATASET_NAME_LEN);
} else {
buf[0] = '\0';
}
@@ -315,10 +316,12 @@ dsl_dir_name(dsl_dir_t *dd, char *buf)
* dprintf_dd() with dd_lock held
*/
mutex_enter(&dd->dd_lock);
- (void) strcat(buf, dd->dd_myname);
+ VERIFY3U(strlcat(buf, dd->dd_myname, ZFS_MAX_DATASET_NAME_LEN),
+ <, ZFS_MAX_DATASET_NAME_LEN);
mutex_exit(&dd->dd_lock);
} else {
- (void) strcat(buf, dd->dd_myname);
+ VERIFY3U(strlcat(buf, dd->dd_myname, ZFS_MAX_DATASET_NAME_LEN),
+ <, ZFS_MAX_DATASET_NAME_LEN);
}
}
@@ -367,12 +370,12 @@ getcomponent(const char *path, char *component, const char **nextp)
if (p != NULL &&
(p[0] != '@' || strpbrk(path+1, "/@") || p[1] == '\0'))
return (SET_ERROR(EINVAL));
- if (strlen(path) >= MAXNAMELEN)
+ if (strlen(path) >= ZFS_MAX_DATASET_NAME_LEN)
return (SET_ERROR(ENAMETOOLONG));
(void) strcpy(component, path);
p = NULL;
} else if (p[0] == '/') {
- if (p - path >= MAXNAMELEN)
+ if (p - path >= ZFS_MAX_DATASET_NAME_LEN)
return (SET_ERROR(ENAMETOOLONG));
(void) strncpy(component, path, p - path);
component[p - path] = '\0';
@@ -384,7 +387,7 @@ getcomponent(const char *path, char *component, const char **nextp)
*/
if (strchr(path, '/'))
return (SET_ERROR(EINVAL));
- if (p - path >= MAXNAMELEN)
+ if (p - path >= ZFS_MAX_DATASET_NAME_LEN)
return (SET_ERROR(ENAMETOOLONG));
(void) strncpy(component, path, p - path);
component[p - path] = '\0';
@@ -412,7 +415,7 @@ dsl_dir_hold(dsl_pool_t *dp, const char *name, void *tag,
dsl_dir_t *dd;
uint64_t ddobj;
- buf = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ buf = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
err = getcomponent(name, buf, &next);
if (err != 0)
goto error;
@@ -479,7 +482,7 @@ dsl_dir_hold(dsl_pool_t *dp, const char *name, void *tag,
*tailp = next;
*ddp = dd;
error:
- kmem_free(buf, MAXNAMELEN);
+ kmem_free(buf, ZFS_MAX_DATASET_NAME_LEN);
return (err);
}
@@ -974,7 +977,7 @@ dsl_dir_stats(dsl_dir_t *dd, nvlist_t *nv)
if (dsl_dir_is_clone(dd)) {
dsl_dataset_t *ds;
- char buf[MAXNAMELEN];
+ char buf[ZFS_MAX_DATASET_NAME_LEN];
VERIFY0(dsl_dataset_hold_obj(dd->dd_pool,
dsl_dir_phys(dd)->dd_origin_obj, FTAG, &ds));
@@ -1691,11 +1694,11 @@ static int
dsl_valid_rename(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
{
int *deltap = arg;
- char namebuf[MAXNAMELEN];
+ char namebuf[ZFS_MAX_DATASET_NAME_LEN];
dsl_dataset_name(ds, namebuf);
- if (strlen(namebuf) + *deltap >= MAXNAMELEN)
+ if (strlen(namebuf) + *deltap >= ZFS_MAX_DATASET_NAME_LEN)
return (SET_ERROR(ENAMETOOLONG));
return (0);
}
diff --git a/module/zfs/dsl_prop.c b/module/zfs/dsl_prop.c
index 361473275..66e899a57 100644
--- a/module/zfs/dsl_prop.c
+++ b/module/zfs/dsl_prop.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 Martin Matuska. All rights reserved.
* Copyright 2015, Joyent, Inc.
*/
@@ -1095,7 +1095,7 @@ dsl_prop_get_all_ds(dsl_dataset_t *ds, nvlist_t **nvp,
dsl_pool_t *dp = dd->dd_pool;
objset_t *mos = dp->dp_meta_objset;
int err = 0;
- char setpoint[MAXNAMELEN];
+ char setpoint[ZFS_MAX_DATASET_NAME_LEN];
VERIFY(nvlist_alloc(nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
diff --git a/module/zfs/dsl_scan.c b/module/zfs/dsl_scan.c
index 72163521e..6c5f1f0b5 100644
--- a/module/zfs/dsl_scan.c
+++ b/module/zfs/dsl_scan.c
@@ -1115,7 +1115,7 @@ dsl_scan_visitds(dsl_scan_t *scn, uint64_t dsobj, dmu_tx_t *tx)
* rootbp's birth time is < cur_min_txg. Then we will
* add the next snapshots/clones to the work queue.
*/
- char *dsname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ char *dsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
dsl_dataset_name(ds, dsname);
zfs_dbgmsg("scanning dataset %llu (%s) is unnecessary because "
"cur_min_txg (%llu) >= max_txg (%llu)",
@@ -1146,7 +1146,7 @@ dsl_scan_visitds(dsl_scan_t *scn, uint64_t dsobj, dmu_tx_t *tx)
dmu_buf_will_dirty(ds->ds_dbuf, tx);
dsl_scan_visit_rootbp(scn, ds, &dsl_dataset_phys(ds)->ds_bp, tx);
- dsname = kmem_alloc(ZFS_MAXNAMELEN, KM_SLEEP);
+ dsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
dsl_dataset_name(ds, dsname);
zfs_dbgmsg("scanned dataset %llu (%s) with min=%llu max=%llu; "
"pausing=%u",
@@ -1154,7 +1154,7 @@ dsl_scan_visitds(dsl_scan_t *scn, uint64_t dsobj, dmu_tx_t *tx)
(longlong_t)scn->scn_phys.scn_cur_min_txg,
(longlong_t)scn->scn_phys.scn_cur_max_txg,
(int)scn->scn_pausing);
- kmem_free(dsname, ZFS_MAXNAMELEN);
+ kmem_free(dsname, ZFS_MAX_DATASET_NAME_LEN);
if (scn->scn_pausing)
goto out;
diff --git a/module/zfs/dsl_userhold.c b/module/zfs/dsl_userhold.c
index 1b234ed48..a6d1aa937 100644
--- a/module/zfs/dsl_userhold.c
+++ b/module/zfs/dsl_userhold.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
@@ -181,7 +181,7 @@ dsl_dataset_user_hold_sync_one_impl(nvlist_t *tmpholds, dsl_dataset_t *ds,
}
typedef struct zfs_hold_cleanup_arg {
- char zhca_spaname[MAXNAMELEN];
+ char zhca_spaname[ZFS_MAX_DATASET_NAME_LEN];
uint64_t zhca_spa_load_guid;
nvlist_t *zhca_holds;
} zfs_hold_cleanup_arg_t;
@@ -580,7 +580,7 @@ dsl_dataset_user_release_impl(nvlist_t *holds, nvlist_t *errlist,
error = dsl_dataset_hold_obj_string(tmpdp,
nvpair_name(pair), FTAG, &ds);
if (error == 0) {
- char name[MAXNAMELEN];
+ char name[ZFS_MAX_DATASET_NAME_LEN];
dsl_dataset_name(ds, name);
dsl_pool_config_exit(tmpdp, FTAG);
dsl_dataset_rele(ds, FTAG);
diff --git a/module/zfs/spa.c b/module/zfs/spa.c
index d1aefe585..9570204f4 100644
--- a/module/zfs/spa.c
+++ b/module/zfs/spa.c
@@ -361,8 +361,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
break;
}
- strval = kmem_alloc(
- MAXNAMELEN + strlen(MOS_DIR_NAME) + 1,
+ strval = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN,
KM_SLEEP);
dsl_dataset_name(ds, strval);
dsl_dataset_rele(ds, FTAG);
@@ -375,8 +374,7 @@ spa_prop_get(spa_t *spa, nvlist_t **nvp)
spa_prop_add_list(*nvp, prop, strval, intval, src);
if (strval != NULL)
- kmem_free(strval,
- MAXNAMELEN + strlen(MOS_DIR_NAME) + 1);
+ kmem_free(strval, ZFS_MAX_DATASET_NAME_LEN);
break;
diff --git a/module/zfs/spa_history.c b/module/zfs/spa_history.c
index 01aa4641e..cf6fc224a 100644
--- a/module/zfs/spa_history.c
+++ b/module/zfs/spa_history.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
*/
#include <sys/spa.h>
@@ -493,7 +493,7 @@ spa_history_log_internal_ds(dsl_dataset_t *ds, const char *operation,
dmu_tx_t *tx, const char *fmt, ...)
{
va_list adx;
- char namebuf[MAXNAMELEN];
+ char namebuf[ZFS_MAX_DATASET_NAME_LEN];
nvlist_t *nvl = fnvlist_alloc();
ASSERT(tx != NULL);
@@ -512,7 +512,7 @@ spa_history_log_internal_dd(dsl_dir_t *dd, const char *operation,
dmu_tx_t *tx, const char *fmt, ...)
{
va_list adx;
- char namebuf[MAXNAMELEN];
+ char namebuf[ZFS_MAX_DATASET_NAME_LEN];
nvlist_t *nvl = fnvlist_alloc();
ASSERT(tx != NULL);
diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c
index e47cfc878..d279d1828 100644
--- a/module/zfs/zfs_ctldir.c
+++ b/module/zfs/zfs_ctldir.c
@@ -749,12 +749,13 @@ zfsctl_snapshot_path_objset(zfs_sb_t *zsb, uint64_t objsetid,
return (ENOENT);
cookie = spl_fstrans_mark();
- snapname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ snapname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
while (error == 0) {
dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
- error = dmu_snapshot_list_next(zsb->z_os, MAXNAMELEN,
- snapname, &id, &pos, &case_conflict);
+ error = dmu_snapshot_list_next(zsb->z_os,
+ ZFS_MAX_DATASET_NAME_LEN, snapname, &id, &pos,
+ &case_conflict);
dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
if (error)
goto out;
@@ -767,7 +768,7 @@ zfsctl_snapshot_path_objset(zfs_sb_t *zsb, uint64_t objsetid,
snprintf(full_path, path_len - 1, "%s/.zfs/snapshot/%s",
zsb->z_mntopts->z_mntpoint, snapname);
out:
- kmem_free(snapname, MAXNAMELEN);
+ kmem_free(snapname, ZFS_MAX_DATASET_NAME_LEN);
spl_fstrans_unmark(cookie);
return (error);
@@ -854,14 +855,14 @@ zfsctl_snapdir_rename(struct inode *sdip, char *snm,
ZFS_ENTER(zsb);
- to = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- from = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- real = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- fsname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ to = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+ from = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+ real = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+ fsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
if (zsb->z_case == ZFS_CASE_INSENSITIVE) {
error = dmu_snapshot_realname(zsb->z_os, snm, real,
- MAXNAMELEN, NULL);
+ ZFS_MAX_DATASET_NAME_LEN, NULL);
if (error == 0) {
snm = real;
} else if (error != ENOTSUP) {
@@ -871,9 +872,11 @@ zfsctl_snapdir_rename(struct inode *sdip, char *snm,
dmu_objset_name(zsb->z_os, fsname);
- error = zfsctl_snapshot_name(ITOZSB(sdip), snm, MAXNAMELEN, from);
+ error = zfsctl_snapshot_name(ITOZSB(sdip), snm,
+ ZFS_MAX_DATASET_NAME_LEN, from);
if (error == 0)
- error = zfsctl_snapshot_name(ITOZSB(tdip), tnm, MAXNAMELEN, to);
+ error = zfsctl_snapshot_name(ITOZSB(tdip), tnm,
+ ZFS_MAX_DATASET_NAME_LEN, to);
if (error == 0)
error = zfs_secpolicy_rename_perms(from, to, cr);
if (error != 0)
@@ -903,10 +906,10 @@ zfsctl_snapdir_rename(struct inode *sdip, char *snm,
rw_exit(&zfs_snapshot_lock);
out:
- kmem_free(from, MAXNAMELEN);
- kmem_free(to, MAXNAMELEN);
- kmem_free(real, MAXNAMELEN);
- kmem_free(fsname, MAXNAMELEN);
+ kmem_free(from, ZFS_MAX_DATASET_NAME_LEN);
+ kmem_free(to, ZFS_MAX_DATASET_NAME_LEN);
+ kmem_free(real, ZFS_MAX_DATASET_NAME_LEN);
+ kmem_free(fsname, ZFS_MAX_DATASET_NAME_LEN);
ZFS_EXIT(zsb);
@@ -929,12 +932,12 @@ zfsctl_snapdir_remove(struct inode *dip, char *name, cred_t *cr, int flags)
ZFS_ENTER(zsb);
- snapname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- real = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ snapname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+ real = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
if (zsb->z_case == ZFS_CASE_INSENSITIVE) {
error = dmu_snapshot_realname(zsb->z_os, name, real,
- MAXNAMELEN, NULL);
+ ZFS_MAX_DATASET_NAME_LEN, NULL);
if (error == 0) {
name = real;
} else if (error != ENOTSUP) {
@@ -942,7 +945,8 @@ zfsctl_snapdir_remove(struct inode *dip, char *name, cred_t *cr, int flags)
}
}
- error = zfsctl_snapshot_name(ITOZSB(dip), name, MAXNAMELEN, snapname);
+ error = zfsctl_snapshot_name(ITOZSB(dip), name,
+ ZFS_MAX_DATASET_NAME_LEN, snapname);
if (error == 0)
error = zfs_secpolicy_destroy_perms(snapname, cr);
if (error != 0)
@@ -952,8 +956,8 @@ zfsctl_snapdir_remove(struct inode *dip, char *name, cred_t *cr, int flags)
if ((error == 0) || (error == ENOENT))
error = dsl_destroy_snapshot(snapname, B_FALSE);
out:
- kmem_free(snapname, MAXNAMELEN);
- kmem_free(real, MAXNAMELEN);
+ kmem_free(snapname, ZFS_MAX_DATASET_NAME_LEN);
+ kmem_free(real, ZFS_MAX_DATASET_NAME_LEN);
ZFS_EXIT(zsb);
@@ -975,7 +979,7 @@ zfsctl_snapdir_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
if (!zfs_admin_snapshot)
return (EACCES);
- dsname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ dsname = kmem_alloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
if (zfs_component_namecheck(dirname, NULL, NULL) != 0) {
error = SET_ERROR(EILSEQ);
@@ -997,7 +1001,7 @@ zfsctl_snapdir_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
0, cr, NULL, NULL);
}
out:
- kmem_free(dsname, MAXNAMELEN);
+ kmem_free(dsname, ZFS_MAX_DATASET_NAME_LEN);
return (error);
}
@@ -1075,11 +1079,11 @@ zfsctl_snapshot_mount(struct path *path, int flags)
zsb = ITOZSB(ip);
ZFS_ENTER(zsb);
- full_name = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
+ full_name = kmem_zalloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
full_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
error = zfsctl_snapshot_name(zsb, dname(dentry),
- MAXNAMELEN, full_name);
+ ZFS_MAX_DATASET_NAME_LEN, full_name);
if (error)
goto error;
@@ -1153,7 +1157,7 @@ zfsctl_snapshot_mount(struct path *path, int flags)
}
path_put(&spath);
error:
- kmem_free(full_name, MAXNAMELEN);
+ kmem_free(full_name, ZFS_MAX_DATASET_NAME_LEN);
kmem_free(full_path, MAXPATHLEN);
ZFS_EXIT(zsb);
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index 96f282201..09f83a5cf 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -604,7 +604,7 @@ zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
case ZFS_PROP_SNAPSHOT_LIMIT:
if (!INGLOBALZONE(curproc)) {
uint64_t zoned;
- char setpoint[MAXNAMELEN];
+ char setpoint[ZFS_MAX_DATASET_NAME_LEN];
/*
* Unprivileged users are allowed to modify the
* limit on things *under* (ie. contained by)
@@ -846,7 +846,7 @@ zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
int
zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
{
- char parentname[MAXNAMELEN];
+ char parentname[ZFS_MAX_DATASET_NAME_LEN];
int error;
if ((error = zfs_secpolicy_write_perms(from,
@@ -899,7 +899,7 @@ zfs_secpolicy_promote(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &clone);
if (error == 0) {
- char parentname[MAXNAMELEN];
+ char parentname[ZFS_MAX_DATASET_NAME_LEN];
dsl_dataset_t *origin = NULL;
dsl_dir_t *dd;
dd = clone->ds_dir;
@@ -1076,7 +1076,7 @@ zfs_secpolicy_log_history(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
static int
zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
{
- char parentname[MAXNAMELEN];
+ char parentname[ZFS_MAX_DATASET_NAME_LEN];
int error;
char *origin;
@@ -1219,7 +1219,7 @@ zfs_secpolicy_hold(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
pair = nvlist_next_nvpair(holds, pair)) {
- char fsname[MAXNAMELEN];
+ char fsname[ZFS_MAX_DATASET_NAME_LEN];
error = dmu_fsname(nvpair_name(pair), fsname);
if (error != 0)
return (error);
@@ -1240,7 +1240,7 @@ zfs_secpolicy_release(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
pair = nvlist_next_nvpair(innvl, pair)) {
- char fsname[MAXNAMELEN];
+ char fsname[ZFS_MAX_DATASET_NAME_LEN];
error = dmu_fsname(nvpair_name(pair), fsname);
if (error != 0)
return (error);
@@ -2260,7 +2260,8 @@ zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
* A dataset name of maximum length cannot have any snapshots,
* so exit immediately.
*/
- if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) {
+ if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >=
+ ZFS_MAX_DATASET_NAME_LEN) {
dmu_objset_rele(os, FTAG);
return (SET_ERROR(ESRCH));
}
@@ -3048,7 +3049,7 @@ zfs_fill_zplprops(const char *dataset, nvlist_t *createprops,
boolean_t fuids_ok, sa_ok;
uint64_t zplver = ZPL_VERSION;
objset_t *os = NULL;
- char parentname[MAXNAMELEN];
+ char parentname[ZFS_MAX_DATASET_NAME_LEN];
char *cp;
spa_t *spa;
uint64_t spa_vers;
@@ -3414,7 +3415,7 @@ zfs_destroy_unmount_origin(const char *fsname)
return;
ds = dmu_objset_ds(os);
if (dsl_dir_is_clone(ds->ds_dir) && DS_IS_DEFER_DESTROY(ds->ds_prev)) {
- char originname[MAXNAMELEN];
+ char originname[ZFS_MAX_DATASET_NAME_LEN];
dsl_dataset_name(ds->ds_prev, originname);
dmu_objset_rele(os, FTAG);
(void) zfs_unmount_snap(originname);
@@ -4266,7 +4267,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
nvlist_t *props = NULL;
char *origin = NULL;
char *tosnap;
- char tofs[ZFS_MAXNAMELEN];
+ char tofs[ZFS_MAX_DATASET_NAME_LEN];
int error = 0;
if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
@@ -4344,7 +4345,7 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
char *snapname = NULL;
char *origin = NULL;
char *tosnap;
- char tofs[ZFS_MAXNAMELEN];
+ char tofs[ZFS_MAX_DATASET_NAME_LEN];
boolean_t force;
boolean_t resumable;
uint64_t action_handle = 0;
diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c
index a72841c15..ef04b203d 100644
--- a/module/zfs/zfs_vfsops.c
+++ b/module/zfs/zfs_vfsops.c
@@ -1020,7 +1020,7 @@ zfs_statvfs(struct dentry *dentry, struct kstatfs *statp)
statp->f_fsid.val[0] = (uint32_t)fsid;
statp->f_fsid.val[1] = (uint32_t)(fsid >> 32);
statp->f_type = ZFS_SUPER_MAGIC;
- statp->f_namelen = ZFS_MAXNAMELEN;
+ statp->f_namelen = MAXNAMELEN - 1;
/*
* We have all of 40 characters to stuff a string here.
diff --git a/module/zfs/zil.c b/module/zfs/zil.c
index 988ffec29..863ccb930 100644
--- a/module/zfs/zil.c
+++ b/module/zfs/zil.c
@@ -2080,7 +2080,7 @@ typedef struct zil_replay_arg {
static int
zil_replay_error(zilog_t *zilog, lr_t *lr, int error)
{
- char name[MAXNAMELEN];
+ char name[ZFS_MAX_DATASET_NAME_LEN];
zilog->zl_replaying_seq--; /* didn't actually replay this one */
diff --git a/module/zfs/zpl_inode.c b/module/zfs/zpl_inode.c
index 089e3a1bc..8c75698e5 100644
--- a/module/zfs/zpl_inode.c
+++ b/module/zfs/zpl_inode.c
@@ -50,7 +50,7 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
int zfs_flags = 0;
zfs_sb_t *zsb = dentry->d_sb->s_fs_info;
- if (dlen(dentry) > ZFS_MAXNAMELEN)
+ if (dlen(dentry) > ZFS_MAX_DATASET_NAME_LEN)
return (ERR_PTR(-ENAMETOOLONG));
crhold(cr);