diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index 08076bc09..b19ebb6fe 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -768,6 +768,9 @@ typedef struct ddt_histogram { * /dev/zfs ioctl numbers. */ typedef enum zfs_ioc { + /* + * Illumos - 69/128 numbers reserved. + */ ZFS_IOC_FIRST = ('Z' << 8), ZFS_IOC = ZFS_IOC_FIRST, ZFS_IOC_POOL_CREATE = ZFS_IOC_FIRST, @@ -805,7 +808,6 @@ typedef enum zfs_ioc { ZFS_IOC_ERROR_LOG, ZFS_IOC_CLEAR, ZFS_IOC_PROMOTE, - ZFS_IOC_DESTROY_SNAPS, ZFS_IOC_SNAPSHOT, ZFS_IOC_DSOBJ_TO_DSNAME, ZFS_IOC_OBJ_TO_PATH, @@ -828,17 +830,29 @@ typedef enum zfs_ioc { ZFS_IOC_DIFF, ZFS_IOC_TMP_SNAPSHOT, ZFS_IOC_OBJ_TO_STATS, - ZFS_IOC_EVENTS_NEXT, - ZFS_IOC_EVENTS_CLEAR, - ZFS_IOC_POOL_REGUID, ZFS_IOC_SPACE_WRITTEN, ZFS_IOC_SPACE_SNAPS, + ZFS_IOC_DESTROY_SNAPS, + ZFS_IOC_POOL_REGUID, ZFS_IOC_POOL_REOPEN, ZFS_IOC_SEND_PROGRESS, ZFS_IOC_LOG_HISTORY, ZFS_IOC_SEND_NEW, ZFS_IOC_SEND_SPACE, ZFS_IOC_CLONE, + + /* + * Linux - 3/64 numbers reserved. + */ + ZFS_IOC_LINUX = ('Z' << 8) + 0x80, + ZFS_IOC_EVENTS_NEXT, + ZFS_IOC_EVENTS_CLEAR, + + /* + * FreeBSD - 1/64 numbers reserved. + */ + ZFS_IOC_FREEBSD = ('Z' << 8) + 0xC0, + ZFS_IOC_LAST } zfs_ioc_t; diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 9b084632f..924151480 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -5565,6 +5565,13 @@ zfsdev_ioctl(struct file *filp, unsigned cmd, unsigned long arg) return (-SET_ERROR(EINVAL)); vec = &zfs_ioc_vec[vecnum]; + /* + * The registered ioctl list may be sparse, verify that either + * a normal or legacy handler are registered. + */ + if (vec->zvec_func == NULL && vec->zvec_legacy_func == NULL) + return (-SET_ERROR(EINVAL)); + zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP | KM_NODEBUG); saved_poolname = kmem_alloc(MAXNAMELEN, KM_SLEEP);