path: root/lib
diff options
authorAndriy Gapon <avg@FreeBSD.org>2017-06-09 15:00:13 +0000
committerAndriy Gapon <avg@FreeBSD.org>2017-06-09 15:00:13 +0000
commit1cb31ff6a482198e43465e250354d2a70ef48da3 (patch)
tree56526380426d9d6ee5ff257415ef10559f6622c1 /lib
parentacabd65c2a538d190921307bde0e954caee214b3 (diff)
8168 NULL pointer dereference in zfs_create()
illumos/illumos-gate@690031d326342fa4ea28b5e80f1ad6a16281519d https://github.com/illumos/illumos-gate/commit/690031d326342fa4ea28b5e80f1ad6a16281519d https://www.illumos.org/issues/8168 If we manage to export the pool on which we are creating a dataset (filesystem or zvol) between entering libzfs`zfs_create() and libzfs`zpool_open() call (for which we never check the return value) we end up dereferencing a NULL pointer in libzfs`zpool_close(). This was discovered on ZFS on Linux. The same issue can be reproduced on Illumos running in parallel: while :; do zpool import -d /tmp testpool ; zpool export testpool ; done while :; do zfs create testpool/fs; zfs destroy testpool/fs ; done Eventually this will result in several core dumps like this one: [root@52-54-00-d3-7a-01 /cores]# mdb core.zfs.4244 Loading modules: [ libumem.so.1 libc.so.1 libtopo.so.1 libavl.so.1 libnvpair.so.1 ld.so.1 ] > ::stack libzfs.so.1`zpool_close+0x17(0, 0, 0, 8047450) libzfs.so.1`zfs_create+0x1bb(8090548, 8047e6f, 1, 808cba8) zfs_do_create+0x545(2, 8047d74, 80778a0, 801, 0, 3) main+0x22c(8047d2c, fef5c6e8, 8047d64, 8055a17, 3, 8047d70) _start+0x83(3, 8047e64, 8047e68, 8047e6f, 0, 8047e7b) > Fix and reproducer (systemtap): https://github.com/zfsonlinux/zfs/pull/6096 Reviewed by: Matt Ahrens <mahrens@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> Author: loli10K <ezomori.nozomu@gmail.com>
Notes: svn path=/vendor/illumos/dist/; revision=319740
Diffstat (limited to 'lib')
1 files changed, 3 insertions, 1 deletions
diff --git a/lib/libzfs/common/libzfs_dataset.c b/lib/libzfs/common/libzfs_dataset.c
index a01d29e8c1e4..33803630a162 100644
--- a/lib/libzfs/common/libzfs_dataset.c
+++ b/lib/libzfs/common/libzfs_dataset.c
@@ -3271,6 +3271,7 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
char errbuf[1024];
uint64_t zoned;
enum lzc_dataset_type ost;
+ zpool_handle_t *zpool_handle;
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot create '%s'"), path);
@@ -3310,7 +3311,8 @@ zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
if (p != NULL)
*p = '\0';
- zpool_handle_t *zpool_handle = zpool_open(hdl, pool_path);
+ if ((zpool_handle = zpool_open(hdl, pool_path)) == NULL)
+ return (-1);
if (props && (props = zfs_valid_proplist(hdl, type, props,
zoned, NULL, zpool_handle, errbuf)) == 0) {