Skip to content

Commit 986a7de

Browse files
ahrenspcd1193182
authored andcommitted
receive ioctl should check unsupported features
When receiving a send stream that has unexpected features enabled (i.e. a flag is set in `DMU_GET_FEATUREFLAGS(drr_versioninfo)` that is not in `DMU_BACKUP_FEATURE_MASK`), libzfs will detect this and fail, printing `cannot receive: stream has unsupported feature, feature flags = ...`. However, if a process is using libzfs_core directly (i.e. `lzc_receive*()`), or if libzfs and the kernel module are mismatched, then the kernel may attempt to receive a stream with unsupported features. The problem is that the kernel is not explicitly checking drr_versioninfo for unsupported features. Typically this will cause the receive the fail with EINVAL when it encounters a specific piece of metadata that is not understood (e.g. a new record type). However, other, arbitrarily bad failure modes are also possible. The solution is to make the kernel explicitly check drr_versioninfo for unsupported features. A new zfs_errno_t value was added, which the kernel will return, and libzfs will print `cannot receive new filesystem stream: the loaded zfs module does not support this operation. A reboot may be required to enable this operation.`
1 parent 6a1cc41 commit 986a7de

File tree

3 files changed

+9
-0
lines changed

3 files changed

+9
-0
lines changed

include/sys/fs/zfs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,7 @@ typedef enum {
12241224
ZFS_ERR_IOC_ARG_UNAVAIL,
12251225
ZFS_ERR_IOC_ARG_REQUIRED,
12261226
ZFS_ERR_IOC_ARG_BADTYPE,
1227+
ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE,
12271228
} zfs_errno_t;
12281229

12291230
/*

lib/libzfs/libzfs_util.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ zfs_standard_error_fmt(libzfs_handle_t *hdl, int error, const char *fmt, ...)
450450
case EREMOTEIO:
451451
zfs_verror(hdl, EZFS_ACTIVE_POOL, fmt, ap);
452452
break;
453+
case ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE:
453454
case ZFS_ERR_IOC_CMD_UNAVAIL:
454455
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "the loaded zfs "
455456
"module does not support this operation. A reboot may "

module/zfs/dmu_recv.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,13 @@ recv_begin_check_existing_impl(dmu_recv_begin_arg_t *drba, dsl_dataset_t *ds,
476476
static int
477477
recv_begin_check_feature_flags_impl(uint64_t featureflags, spa_t *spa)
478478
{
479+
/*
480+
* Check if there are any unsupported feature flags.
481+
*/
482+
if (!DMU_STREAM_SUPPORTED(featureflags)) {
483+
return (SET_ERROR(ZFS_ERR_UNKNOWN_SEND_STREAM_FEATURE));
484+
}
485+
479486
/* Verify pool version supports SA if SA_SPILL feature set */
480487
if ((featureflags & DMU_BACKUP_FEATURE_SA_SPILL) &&
481488
spa_version(spa) < SPA_VERSION_SA)

0 commit comments

Comments
 (0)