OpenZFS 6314 - buffer overflow in dsl_dataset_name

Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
Approved by: Dan McDonald <danmcd@omniti.com>
Ported-by: Brian Behlendorf <behlendorf1@llnl.gov>

OpenZFS-issue: https://www.illumos.org/issues/6314
OpenZFS-commit: https://github.com/openzfs/openzfs/commit/d6160ee
This commit is contained in:
Igor Kozhukhov
2016-06-15 14:28:36 -07:00
committed by Brian Behlendorf
parent 43e52eddb1
commit eca7b76001
41 changed files with 297 additions and 334 deletions
+2 -1
View File
@@ -24,6 +24,7 @@
* Use is subject to license terms.
*
* Portions Copyright 2007 Ramprakash Jelari
* Copyright (c) 2014, 2015 by Delphix. All rights reserved.
*/
#include <libintl.h>
@@ -287,7 +288,7 @@ void
changelist_rename(prop_changelist_t *clp, const char *src, const char *dst)
{
prop_changenode_t *cn;
char newname[ZFS_MAXNAMELEN];
char newname[ZFS_MAX_DATASET_NAME_LEN];
for (cn = uu_list_first(clp->cl_list); cn != NULL;
cn = uu_list_next(clp->cl_list, cn)) {
+16 -16
View File
@@ -551,7 +551,7 @@ zfs_bookmark_exists(const char *path)
{
nvlist_t *bmarks;
nvlist_t *props;
char fsname[ZFS_MAXNAMELEN];
char fsname[ZFS_MAX_DATASET_NAME_LEN];
char *bmark_name;
char *pound;
int err;
@@ -2201,7 +2201,7 @@ struct get_clones_arg {
uint64_t numclones;
nvlist_t *value;
const char *origin;
char buf[ZFS_MAXNAMELEN];
char buf[ZFS_MAX_DATASET_NAME_LEN];
};
int
@@ -2256,7 +2256,7 @@ zfs_get_clones_nvl(zfs_handle_t *zhp)
if (gca.numclones != 0) {
zfs_handle_t *root;
char pool[ZFS_MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
char *cp = pool;
/* get the pool name */
@@ -3001,7 +3001,7 @@ check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
boolean_t accept_ancestor, int *prefixlen)
{
zfs_cmd_t zc = {"\0"};
char parent[ZFS_MAXNAMELEN];
char parent[ZFS_MAX_DATASET_NAME_LEN];
char *slash;
zfs_handle_t *zhp;
char errbuf[1024];
@@ -3240,7 +3240,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
ost = DMU_OST_ZFS;
/* open zpool handle for prop validation */
char pool_path[MAXNAMELEN];
char pool_path[ZFS_MAX_DATASET_NAME_LEN];
(void) strlcpy(pool_path, path, sizeof (pool_path));
/* truncate pool_path at first slash */
@@ -3309,7 +3309,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
/* check for failure */
if (ret != 0) {
char parent[ZFS_MAXNAMELEN];
char parent[ZFS_MAX_DATASET_NAME_LEN];
(void) parent_name(path, parent, sizeof (parent));
switch (errno) {
@@ -3399,7 +3399,7 @@ static int
zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
{
struct destroydata *dd = arg;
char name[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
int rv = 0;
(void) snprintf(name, sizeof (name),
@@ -3490,7 +3490,7 @@ zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
int
zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
{
char parent[ZFS_MAXNAMELEN];
char parent[ZFS_MAX_DATASET_NAME_LEN];
int ret;
char errbuf[1024];
libzfs_handle_t *hdl = zhp->zfs_hdl;
@@ -3620,7 +3620,7 @@ static int
zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
{
snapdata_t *sd = arg;
char name[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
int rv = 0;
if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
@@ -3669,7 +3669,7 @@ zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
* get pool handle for prop validation. assumes all snaps are in the
* same pool, as does lzc_snapshot (below).
*/
char pool[MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
elem = nvlist_next_nvpair(snaps, NULL);
(void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
pool[strcspn(pool, "/@")] = '\0';
@@ -3723,7 +3723,7 @@ zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
{
int ret;
snapdata_t sd = { 0 };
char fsname[ZFS_MAXNAMELEN];
char fsname[ZFS_MAX_DATASET_NAME_LEN];
char *cp;
zfs_handle_t *zhp;
char errbuf[1024];
@@ -3902,7 +3902,7 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
prop_changelist_t *cl = NULL;
zfs_handle_t *zhrp = NULL;
char *parentname = NULL;
char parent[ZFS_MAXNAMELEN];
char parent[ZFS_MAX_DATASET_NAME_LEN];
libzfs_handle_t *hdl = zhp->zfs_hdl;
char errbuf[1024];
@@ -4322,7 +4322,7 @@ zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
zc.zc_nvlist_dst_size = sizeof (buf);
if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
char errbuf[ZFS_MAXNAMELEN + 32];
char errbuf[1024];
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN,
@@ -4356,7 +4356,7 @@ static int
zfs_hold_one(zfs_handle_t *zhp, void *arg)
{
struct holdarg *ha = arg;
char name[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
int rv = 0;
(void) snprintf(name, sizeof (name),
@@ -4475,7 +4475,7 @@ static int
zfs_release_one(zfs_handle_t *zhp, void *arg)
{
struct holdarg *ha = arg;
char name[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
int rv = 0;
nvlist_t *existing_holds;
@@ -4604,7 +4604,7 @@ tryagain:
zc.zc_nvlist_dst_size = nvsz;
zc.zc_nvlist_dst = (uintptr_t)nvbuf;
(void) strlcpy(zc.zc_name, zhp->zfs_name, ZFS_MAXNAMELEN);
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
if (ioctl(hdl->libzfs_fd, ZFS_IOC_GET_FSACL, &zc) != 0) {
(void) snprintf(errbuf, sizeof (errbuf),
+2 -1
View File
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2015 by Delphix. All rights reserved.
* Copyright 2016 Joyent, Inc.
*/
@@ -604,7 +605,7 @@ get_snapshot_names(differ_info_t *di, const char *fromsnap,
* not the same dataset name, might be okay if
* tosnap is a clone of a fromsnap descendant.
*/
char origin[ZFS_MAXNAMELEN];
char origin[ZFS_MAX_DATASET_NAME_LEN];
zprop_source_t src;
zfs_handle_t *zhp;
+3 -3
View File
@@ -197,7 +197,7 @@ zfs_iter_bookmarks(zfs_handle_t *zhp, zfs_iter_f func, void *data)
for (pair = nvlist_next_nvpair(bmarks, NULL);
pair != NULL; pair = nvlist_next_nvpair(bmarks, pair)) {
char name[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
char *bmark_name;
nvlist_t *bmark_props;
@@ -384,7 +384,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
* exists.
*/
if (ssa.ssa_last[0] != '\0') {
char snapname[ZFS_MAXNAMELEN];
char snapname[ZFS_MAX_DATASET_NAME_LEN];
(void) snprintf(snapname, sizeof (snapname),
"%s@%s", zfs_get_name(fs_zhp),
ssa.ssa_last);
@@ -404,7 +404,7 @@ zfs_iter_snapspec(zfs_handle_t *fs_zhp, const char *spec_orig,
ret = ENOENT;
}
} else {
char snapname[ZFS_MAXNAMELEN];
char snapname[ZFS_MAX_DATASET_NAME_LEN];
zfs_handle_t *snap_zhp;
(void) snprintf(snapname, sizeof (snapname), "%s@%s",
zfs_get_name(fs_zhp), comma_separated);
+1 -1
View File
@@ -230,7 +230,7 @@ static boolean_t
zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen,
zprop_source_t *source)
{
char sourceloc[ZFS_MAXNAMELEN];
char sourceloc[MAXNAMELEN];
zprop_source_t sourcetype;
if (!zfs_prop_valid_for_type(ZFS_PROP_MOUNTPOINT, zhp->zfs_type,
+2 -2
View File
@@ -441,7 +441,7 @@ pool_uses_efi(nvlist_t *config)
boolean_t
zpool_is_bootable(zpool_handle_t *zhp)
{
char bootfs[ZPOOL_MAXNAMELEN];
char bootfs[ZFS_MAX_DATASET_NAME_LEN];
return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
sizeof (bootfs), NULL, B_FALSE) == 0 && strncmp(bootfs, "-",
@@ -4006,7 +4006,7 @@ zpool_obj_to_path(zpool_handle_t *zhp, uint64_t dsobj, uint64_t obj,
zfs_cmd_t zc = {"\0"};
boolean_t mounted = B_FALSE;
char *mntpnt = NULL;
char dsname[MAXNAMELEN];
char dsname[ZFS_MAX_DATASET_NAME_LEN];
if (dsobj == 0) {
/* special case for the MOS */
+25 -24
View File
@@ -837,7 +837,7 @@ typedef struct send_dump_data {
/* these are all just the short snapname (the part after the @) */
const char *fromsnap;
const char *tosnap;
char prevsnap[ZFS_MAXNAMELEN];
char prevsnap[ZFS_MAX_DATASET_NAME_LEN];
uint64_t prevsnap_obj;
boolean_t seenfrom, seento, replicate, doall, fromorigin;
boolean_t verbose, dryrun, parsable, progress, embed_data, std_out;
@@ -850,7 +850,7 @@ typedef struct send_dump_data {
snapfilter_cb_t *filter_cb;
void *filter_cb_arg;
nvlist_t *debugnv;
char holdtag[ZFS_MAXNAMELEN];
char holdtag[ZFS_MAX_DATASET_NAME_LEN];
int cleanup_fd;
uint64_t size;
} send_dump_data_t;
@@ -1485,7 +1485,7 @@ zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
uint64_t resumeobj, resumeoff, toguid, fromguid, bytes;
zfs_handle_t *zhp;
int error = 0;
char name[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
enum lzc_send_flags lzc_flags = 0;
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
@@ -2076,8 +2076,8 @@ recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
seq++;
(void) snprintf(newname, ZFS_MAXNAMELEN, "%.*srecv-%u-%u",
baselen, name, getpid(), seq);
(void) snprintf(newname, ZFS_MAX_DATASET_NAME_LEN,
"%.*srecv-%u-%u", baselen, name, getpid(), seq);
(void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
if (flags->verbose) {
@@ -2205,7 +2205,7 @@ static int
guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
boolean_t bookmark_ok, char *name)
{
char pname[ZFS_MAXNAMELEN];
char pname[ZFS_MAX_DATASET_NAME_LEN];
guid_to_name_data_t gtnd;
gtnd.guid = guid;
@@ -2260,7 +2260,7 @@ created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
{
nvlist_t *nvfs;
char *fsname = NULL, *snapname = NULL;
char buf[ZFS_MAXNAMELEN];
char buf[ZFS_MAX_DATASET_NAME_LEN];
int rv;
zfs_handle_t *guid1hdl, *guid2hdl;
uint64_t create1, create2;
@@ -2311,7 +2311,7 @@ recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
avl_tree_t *local_avl;
nvpair_t *fselem, *nextfselem;
char *fromsnap;
char newname[ZFS_MAXNAMELEN];
char newname[ZFS_MAX_DATASET_NAME_LEN];
char guidname[32];
int error;
boolean_t needagain, progress, recursive;
@@ -2430,7 +2430,7 @@ again:
/* check for delete */
if (found == NULL) {
char name[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
if (!flags->force)
continue;
@@ -2471,8 +2471,8 @@ again:
/* check for different snapname */
if (strcmp(nvpair_name(snapelem),
stream_snapname) != 0) {
char name[ZFS_MAXNAMELEN];
char tryname[ZFS_MAXNAMELEN];
char name[ZFS_MAX_DATASET_NAME_LEN];
char tryname[ZFS_MAX_DATASET_NAME_LEN];
(void) snprintf(name, sizeof (name), "%s@%s",
fsname, nvpair_name(snapelem));
@@ -2556,7 +2556,7 @@ again:
((flags->isprefix || strcmp(tofs, fsname) != 0) &&
(s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
nvlist_t *parent;
char tryname[ZFS_MAXNAMELEN];
char tryname[ZFS_MAX_DATASET_NAME_LEN];
parent = fsavl_find(local_avl,
stream_parent_fromsnap_guid, NULL);
@@ -2624,8 +2624,8 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
char *fromsnap = NULL;
char *sendsnap = NULL;
char *cp;
char tofs[ZFS_MAXNAMELEN];
char sendfs[ZFS_MAXNAMELEN];
char tofs[ZFS_MAX_DATASET_NAME_LEN];
char sendfs[ZFS_MAX_DATASET_NAME_LEN];
char errbuf[1024];
dmu_replay_record_t drre;
int error;
@@ -2709,7 +2709,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
nvlist_t *renamed = NULL;
nvpair_t *pair = NULL;
(void) strlcpy(tofs, destname, ZFS_MAXNAMELEN);
(void) strlcpy(tofs, destname, sizeof (tofs));
if (flags->isprefix) {
struct drr_begin *drrb = &drr->drr_u.drr_begin;
int i;
@@ -2718,7 +2718,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
cp = strrchr(drrb->drr_toname, '/');
if (cp == NULL) {
(void) strlcat(tofs, "/",
ZFS_MAXNAMELEN);
sizeof (tofs));
i = 0;
} else {
i = (cp - drrb->drr_toname);
@@ -2728,7 +2728,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
}
/* zfs_receive_one() will create_parents() */
(void) strlcat(tofs, &drrb->drr_toname[i],
ZFS_MAXNAMELEN);
sizeof (tofs));
*strchr(tofs, '@') = '\0';
}
@@ -2770,7 +2770,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
* zfs_receive_one().
*/
(void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
ZFS_MAXNAMELEN);
sizeof (sendfs));
if ((cp = strchr(sendfs, '@')) != NULL) {
*cp = '\0';
/*
@@ -2920,7 +2920,7 @@ static void
recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
boolean_t resumable)
{
char target_fs[ZFS_MAXNAMELEN];
char target_fs[ZFS_MAX_DATASET_NAME_LEN];
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"checksum mismatch or incomplete stream"));
@@ -3113,7 +3113,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
if (flags->verbose)
(void) printf("found clone origin %s\n", origin);
} else if (originsnap) {
(void) strncpy(origin, originsnap, ZFS_MAXNAMELEN);
(void) strncpy(origin, originsnap, sizeof (origin));
if (flags->verbose)
(void) printf("using provided clone origin %s\n",
origin);
@@ -3138,7 +3138,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
*cp = '\0';
if (cp &&
!zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
char suffix[ZFS_MAXNAMELEN];
char suffix[ZFS_MAX_DATASET_NAME_LEN];
(void) strcpy(suffix, strrchr(destsnap, '/'));
if (guid_to_name(hdl, name, parent_snapguid,
B_FALSE, destsnap) == 0) {
@@ -3165,7 +3165,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
!zfs_dataset_exists(hdl, name, ZFS_TYPE_DATASET)) {
char snap[ZFS_MAXNAMELEN];
char snap[ZFS_MAX_DATASET_NAME_LEN];
(void) strcpy(snap, strchr(destsnap, '@'));
if (guid_to_name(hdl, name, drrb->drr_fromguid,
B_FALSE, destsnap) == 0) {
@@ -3609,7 +3609,7 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
}
if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
char nonpackage_sendfs[ZFS_MAXNAMELEN];
char nonpackage_sendfs[ZFS_MAX_DATASET_NAME_LEN];
if (sendfs == NULL) {
/*
* We were not called from zfs_receive_package(). Get
@@ -3617,7 +3617,8 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
*/
char *cp;
(void) strlcpy(nonpackage_sendfs,
drr.drr_u.drr_begin.drr_toname, ZFS_MAXNAMELEN);
drr.drr_u.drr_begin.drr_toname,
sizeof (nonpackage_sendfs));
if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
*cp = '\0';
sendfs = nonpackage_sendfs;
+7 -7
View File
@@ -217,7 +217,7 @@ lzc_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t **errlist)
nvpair_t *elem;
nvlist_t *args;
int error;
char pool[MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
*errlist = NULL;
@@ -269,7 +269,7 @@ lzc_destroy_snaps(nvlist_t *snaps, boolean_t defer, nvlist_t **errlist)
nvpair_t *elem;
nvlist_t *args;
int error;
char pool[MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
/* determine the pool name */
elem = nvlist_next_nvpair(snaps, NULL);
@@ -296,7 +296,7 @@ lzc_snaprange_space(const char *firstsnap, const char *lastsnap,
nvlist_t *args;
nvlist_t *result;
int err;
char fs[MAXNAMELEN];
char fs[ZFS_MAX_DATASET_NAME_LEN];
char *atp;
/* determine the fs name */
@@ -361,7 +361,7 @@ lzc_exists(const char *dataset)
int
lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist)
{
char pool[MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
nvlist_t *args;
nvpair_t *elem;
int error;
@@ -408,7 +408,7 @@ lzc_hold(nvlist_t *holds, int cleanup_fd, nvlist_t **errlist)
int
lzc_release(nvlist_t *holds, nvlist_t **errlist)
{
char pool[MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
nvpair_t *elem;
/* determine the pool name */
@@ -842,7 +842,7 @@ lzc_bookmark(nvlist_t *bookmarks, nvlist_t **errlist)
{
nvpair_t *elem;
int error;
char pool[MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
/* determine the pool name */
elem = nvlist_next_nvpair(bookmarks, NULL);
@@ -904,7 +904,7 @@ lzc_destroy_bookmarks(nvlist_t *bmarks, nvlist_t **errlist)
{
nvpair_t *elem;
int error;
char pool[MAXNAMELEN];
char pool[ZFS_MAX_DATASET_NAME_LEN];
/* determine the pool name */
elem = nvlist_next_nvpair(bmarks, NULL);