diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index 7013fbfb64f..414ea6bad3c 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -6652,21 +6652,27 @@ zfs_ioc_userspace_one(zfs_cmd_t *zc) * outputs: * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t) * zc_cookie zap cursor + * + * The zc_nvlist_dst output array is limited to 1000 entries. */ static int zfs_ioc_userspace_many(zfs_cmd_t *zc) { + const size_t batch_limit = 1000 * sizeof (zfs_useracct_t); + uint64_t bufsize = MIN(zc->zc_nvlist_dst_size, batch_limit); zfsvfs_t *zfsvfs; - int bufsize = zc->zc_nvlist_dst_size; - if (bufsize <= 0) + if (bufsize < sizeof (zfs_useracct_t)) { + zc->zc_nvlist_dst_size = sizeof (zfs_useracct_t); return (SET_ERROR(ENOMEM)); + } int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); if (error != 0) return (error); void *buf = vmem_alloc(bufsize, KM_SLEEP); + zc->zc_nvlist_dst_size = bufsize; error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie, buf, &zc->zc_nvlist_dst_size, &zc->zc_guid);