summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2010-05-21 08:55:18 +0000
committermm <mm@FreeBSD.org>2010-05-21 08:55:18 +0000
commitc5161d1ad5baa751d09569af1e5c06e990e4edaa (patch)
tree272d85c82790236966a4bb4f92bf027f68719113
parentc47ee5a2cae1d2e03f929710d8ef0ac7e14b81c6 (diff)
downloadFreeBSD-src-c5161d1ad5baa751d09569af1e5c06e990e4edaa.zip
FreeBSD-src-c5161d1ad5baa751d09569af1e5c06e990e4edaa.tar.gz
Fix stack overflow in zfs send.
OpenSolaris onnv-revision: 8012:8ea30813950f Approved by: pjd, delphij (mentor) Obtained from: OpenSolaris (Bug ID 6765626) MFC after: 3 days
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c7
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c16
2 files changed, 12 insertions, 11 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
index 15e789f..ef0284d 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c
@@ -134,6 +134,7 @@ static int
traverse_visitbp(struct traverse_data *td, const dnode_phys_t *dnp,
arc_buf_t *pbuf, blkptr_t *bp, const zbookmark_t *zb)
{
+ zbookmark_t czb;
int err = 0;
arc_buf_t *buf = NULL;
struct prefetch_data *pd = td->td_pfd;
@@ -179,8 +180,6 @@ traverse_visitbp(struct traverse_data *td, const dnode_phys_t *dnp,
/* recursively visitbp() blocks below this */
cbp = buf->b_data;
for (i = 0; i < epb; i++, cbp++) {
- zbookmark_t czb;
-
SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
zb->zb_level - 1,
zb->zb_blkid * epb + i);
@@ -203,8 +202,6 @@ traverse_visitbp(struct traverse_data *td, const dnode_phys_t *dnp,
dnp = buf->b_data;
for (i = 0; i < epb && err == 0; i++, dnp++) {
for (j = 0; j < dnp->dn_nblkptr; j++) {
- zbookmark_t czb;
-
SET_BOOKMARK(&czb, zb->zb_objset,
zb->zb_blkid * epb + i,
dnp->dn_nlevels - 1, j);
@@ -229,8 +226,6 @@ traverse_visitbp(struct traverse_data *td, const dnode_phys_t *dnp,
traverse_zil(td, &osp->os_zil_header);
for (j = 0; j < osp->os_meta_dnode.dn_nblkptr; j++) {
- zbookmark_t czb;
-
SET_BOOKMARK(&czb, zb->zb_objset, 0,
osp->os_meta_dnode.dn_nlevels - 1, j);
err = traverse_visitbp(td, &osp->os_meta_dnode, buf,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index c7bd8ad..a9ce5ab 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -2367,9 +2367,10 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
}
if (zfsvfs != NULL) {
- char osname[MAXNAMELEN];
+ char *osname;
int mode;
+ osname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
error = zfs_suspend_fs(zfsvfs, osname, &mode);
if (error == 0) {
int resume_err;
@@ -2381,6 +2382,7 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
} else {
dmu_objset_close(os);
}
+ kmem_free(osname, MAXNAMELEN);
VFS_RELE(zfsvfs->z_vfs);
} else {
error = dmu_objset_rollback(os);
@@ -2552,10 +2554,11 @@ zfs_ioc_recv(zfs_cmd_t *zc)
error = dmu_recv_stream(&drc, fp, &off);
if (error == 0 && zfsvfs) {
- char osname[MAXNAMELEN];
+ char *osname;
int mode;
/* online recv */
+ osname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
error = zfs_suspend_fs(zfsvfs, osname, &mode);
if (error == 0) {
int resume_err;
@@ -2566,6 +2569,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
} else {
dmu_recv_abort_cleanup(&drc);
}
+ kmem_free(osname, MAXNAMELEN);
} else if (error == 0) {
error = dmu_recv_end(&drc);
}
@@ -2616,16 +2620,18 @@ zfs_ioc_send(zfs_cmd_t *zc)
return (error);
if (zc->zc_value[0] != '\0') {
- char buf[MAXPATHLEN];
+ char *buf;
char *cp;
- (void) strncpy(buf, zc->zc_name, sizeof (buf));
+ buf = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+ (void) strncpy(buf, zc->zc_name, MAXPATHLEN);
cp = strchr(buf, '@');
if (cp)
*(cp+1) = 0;
- (void) strlcat(buf, zc->zc_value, sizeof (buf));
+ (void) strlcat(buf, zc->zc_value, MAXPATHLEN);
error = dmu_objset_open(buf, DMU_OST_ANY,
DS_MODE_USER | DS_MODE_READONLY, &fromsnap);
+ kmem_free(buf, MAXPATHLEN);
if (error) {
dmu_objset_close(tosnap);
return (error);
OpenPOWER on IntegriCloud