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
+9 -9
View File
@@ -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,