Don't leak packed recieved proprties

When local properties (e.g., from -o and -x) are provided, don't leak
the packed representation of the received properties due to variable
reuse.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Brooks Davis <brooks.davis@sri.com>
Closes #14197
This commit is contained in:
Brooks Davis 2022-11-29 09:51:35 -08:00 committed by Tony Hutter
parent e48aaef89f
commit c4468a70c3
1 changed files with 10 additions and 7 deletions

View File

@ -890,7 +890,8 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
fnvlist_free(outnvl); fnvlist_free(outnvl);
} else { } else {
zfs_cmd_t zc = {"\0"}; zfs_cmd_t zc = {"\0"};
char *packed = NULL; char *rp_packed = NULL;
char *lp_packed = NULL;
size_t size; size_t size;
ASSERT3S(g_refcount, >, 0); ASSERT3S(g_refcount, >, 0);
@ -899,14 +900,14 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
(void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value)); (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
if (recvdprops != NULL) { if (recvdprops != NULL) {
packed = fnvlist_pack(recvdprops, &size); rp_packed = fnvlist_pack(recvdprops, &size);
zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed; zc.zc_nvlist_src = (uint64_t)(uintptr_t)rp_packed;
zc.zc_nvlist_src_size = size; zc.zc_nvlist_src_size = size;
} }
if (localprops != NULL) { if (localprops != NULL) {
packed = fnvlist_pack(localprops, &size); lp_packed = fnvlist_pack(localprops, &size);
zc.zc_nvlist_conf = (uint64_t)(uintptr_t)packed; zc.zc_nvlist_conf = (uint64_t)(uintptr_t)lp_packed;
zc.zc_nvlist_conf_size = size; zc.zc_nvlist_conf_size = size;
} }
@ -941,8 +942,10 @@ recv_impl(const char *snapname, nvlist_t *recvdprops, nvlist_t *localprops,
zc.zc_nvlist_dst_size, errors, KM_SLEEP)); zc.zc_nvlist_dst_size, errors, KM_SLEEP));
} }
if (packed != NULL) if (rp_packed != NULL)
fnvlist_pack_free(packed, size); fnvlist_pack_free(rp_packed, size);
if (lp_packed != NULL)
fnvlist_pack_free(lp_packed, size);
free((void *)(uintptr_t)zc.zc_nvlist_dst); free((void *)(uintptr_t)zc.zc_nvlist_dst);
} }