fnvlist_free(sd->snapprops);
fnvlist_free(sd->snapholds);
+ /* Do not allow the size of the properties list to exceed the limit */
+ if ((fnvlist_size(nvfs) + fnvlist_size(sd->fss)) >
+ zhp->zfs_hdl->libzfs_max_nvlist) {
+ (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
+ "warning: cannot send %s@%s: the size of the list of "
+ "snapshots and properties is too large to be received "
+ "successfully.\n"
+ "Select a smaller number of snapshots to send.\n"),
+ zhp->zfs_name, sd->tosnap);
+ rv = EZFS_NOSPC;
+ goto out;
+ }
/* add this fs to nvlist */
(void) snprintf(guidstring, sizeof (guidstring),
"0x%llx", (longlong_t)guid);
return (zfs_error(zhp->zfs_hdl, EZFS_BADBACKUP,
errbuf));
}
+ /*
+ * Do not allow the size of the properties list to exceed
+ * the limit
+ */
+ if ((fnvlist_size(fss) + fnvlist_size(hdrnv)) >
+ zhp->zfs_hdl->libzfs_max_nvlist) {
+ (void) snprintf(errbuf, sizeof (errbuf),
+ dgettext(TEXT_DOMAIN, "warning: cannot send '%s': "
+ "the size of the list of snapshots and properties "
+ "is too large to be received successfully.\n"
+ "Select a smaller number of snapshots to send.\n"),
+ zhp->zfs_name);
+ return (zfs_error(zhp->zfs_hdl, EZFS_NOSPC,
+ errbuf));
+ }
fnvlist_add_nvlist(hdrnv, "fss", fss);
VERIFY0(nvlist_pack(hdrnv, &packbuf, &buflen, NV_ENCODE_XDR,
0));
int rv;
int len = ilen;
- assert(ilen <= SPA_MAXBLOCKSIZE);
-
do {
rv = read(fd, cp, len);
cp += rv;
if (buf == NULL)
return (ENOMEM);
+ if (len > hdl->libzfs_max_nvlist) {
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "nvlist too large"));
+ return (ENOMEM);
+ }
+
err = recv_read(hdl, fd, buf, len, byteswap, zc);
if (err != 0) {
free(buf);
}
payload_size =
DRR_WRITE_PAYLOAD_SIZE(&drr->drr_u.drr_write);
+ assert(payload_size <= SPA_MAXBLOCKSIZE);
(void) recv_read(hdl, fd, buf,
payload_size, B_FALSE, NULL);
break;
{
libzfs_handle_t *hdl;
int error;
+ char *env;
error = libzfs_load_module();
if (error) {
if (getenv("ZFS_PROP_DEBUG") != NULL) {
hdl->libzfs_prop_debug = B_TRUE;
}
+ if ((env = getenv("ZFS_SENDRECV_MAX_NVLIST")) != NULL) {
+ if ((error = zfs_nicestrtonum(hdl, env,
+ &hdl->libzfs_max_nvlist))) {
+ errno = error;
+ return (NULL);
+ }
+ } else {
+ hdl->libzfs_max_nvlist = (SPA_MAXBLOCKSIZE * 4);
+ }
/*
* For testing, remove some settable properties and features