Skip to content

Commit

Permalink
Add more property checks in zfs_receive_checkprops()
Browse files Browse the repository at this point in the history
  • Loading branch information
loli10K committed Nov 13, 2016
1 parent 93c97a1 commit 7f8826a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
51 changes: 49 additions & 2 deletions lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2783,8 +2783,6 @@ parse_overrides(libzfs_handle_t *hdl, nvlist_t *props, nvlist_t *poprops,
goto error;
}

/* TODO: check properties that cannot be received */

/* second pass: process "-o" properties */
nvp = NULL;
while ((nvp = nvlist_next_nvpair(nvl_voprops, nvp)) != NULL) {
Expand Down Expand Up @@ -3836,6 +3834,50 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
return (err);
}

/*
* Check properties we were asked to override (both -o|-x)
*/
static int
zfs_receive_checkprops(libzfs_handle_t *hdl, nvlist_t *props,
const char *errbuf)
{
nvpair_t *nvp;
int err = 0;
const char *name;

nvp = NULL;
while ((nvp = nvlist_next_nvpair(props, nvp)) != NULL && err == 0) {
zfs_prop_t prop;
name = nvpair_name(nvp);

prop = zfs_name_to_prop(name);
if (prop == ZPROP_INVAL)
continue;
/*
* "origin" is readonly but is used to receive datasets as
* clones so we don't raise an error here
*/
if (prop == ZFS_PROP_ORIGIN)
continue;

// cannot override readonly properties
if (zfs_prop_readonly(prop) == B_TRUE) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"cannot override received property '%s'"), name);
err = 1;
}
// also cannot override specific settable properties
if (prop == ZFS_PROP_VERSION ||
prop == ZFS_PROP_VOLSIZE) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"cannot override received property '%s'"), name);
err = 1;
}
}

return (err);
}

static int
zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
Expand All @@ -3853,6 +3895,11 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"cannot receive"));

/* check properties that cannot be received */
if (zfs_receive_checkprops(hdl, override_props, errbuf) != 0) {
return (zfs_error(hdl, EZFS_BADPROP, errbuf));
}

if (flags->isprefix &&
!zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ log_mustnot eval "$ZFS recv $dest -x atime=off < $streamfile_full"
log_mustnot eval "$ZFS recv $dest -o atime=off -x atime < $streamfile_full"
log_mustnot eval "$ZFS recv $dest -o atime=off -o atime=on < $streamfile_full"
log_mustnot eval "$ZFS recv $dest -x atime -x atime < $streamfile_full"
log_mustnot eval "$ZFS recv $dest -o version=1 < $streamfile_full"
log_mustnot eval "$ZFS recv $dest -x normalization < $streamfile_full"

# 5.2 Verify -o property=value works on streams without properties.
log_must eval "$ZFS recv -o compression=on -o '$userprop:dest1'='$userval' "\
Expand Down

0 comments on commit 7f8826a

Please sign in to comment.