aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/zfs/zfs_main.c
diff options
context:
space:
mode:
authorRichard Yao <[email protected]>2022-10-19 20:08:33 -0400
committerGitHub <[email protected]>2022-10-19 17:08:33 -0700
commit219cf0f928475d832d5a7bf0e286ee9ae008fb84 (patch)
tree2474ac0d239140d3f380fe0da09955d4ee547e10 /cmd/zfs/zfs_main.c
parent5405be036516280c00d481bc44394d8ef7ab15c6 (diff)
Fix userland memory leak in zfs_do_send()
Clang 15's static analyzer caught this. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Richard Yao <[email protected]> Closes #14045
Diffstat (limited to 'cmd/zfs/zfs_main.c')
-rw-r--r--cmd/zfs/zfs_main.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c
index ac51df0f9..dddf387de 100644
--- a/cmd/zfs/zfs_main.c
+++ b/cmd/zfs/zfs_main.c
@@ -4504,6 +4504,7 @@ zfs_do_send(int argc, char **argv)
gettext("missing argument for '%s' "
"option\n"), argv[optind - 1]);
}
+ free(excludes.list);
usage(B_FALSE);
break;
case '?':
@@ -4522,6 +4523,7 @@ zfs_do_send(int argc, char **argv)
argv[optind - 1]);
}
+ free(excludes.list);
usage(B_FALSE);
}
}
@@ -4530,6 +4532,7 @@ zfs_do_send(int argc, char **argv)
flags.verbosity = 1;
if (excludes.count > 0 && !flags.replicate) {
+ free(excludes.list);
(void) fprintf(stderr, gettext("Cannot specify "
"dataset exclusion (-X) on a non-recursive "
"send.\n"));
@@ -4543,21 +4546,25 @@ zfs_do_send(int argc, char **argv)
if (fromname != NULL || flags.replicate || flags.props ||
flags.backup || flags.holds ||
flags.saved || redactbook != NULL) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("invalid flags combined with -t\n"));
usage(B_FALSE);
}
if (argc > 0) {
+ free(excludes.list);
(void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE);
}
} else {
if (argc < 1) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("missing snapshot argument\n"));
usage(B_FALSE);
}
if (argc > 1) {
+ free(excludes.list);
(void) fprintf(stderr, gettext("too many arguments\n"));
usage(B_FALSE);
}
@@ -4568,11 +4575,15 @@ zfs_do_send(int argc, char **argv)
flags.doall || flags.backup ||
flags.holds || flags.largeblock || flags.embed_data ||
flags.compress || flags.raw || redactbook != NULL) {
+ free(excludes.list);
+
(void) fprintf(stderr, gettext("incompatible flags "
"combined with saved send flag\n"));
usage(B_FALSE);
}
if (strchr(argv[0], '@') != NULL) {
+ free(excludes.list);
+
(void) fprintf(stderr, gettext("saved send must "
"specify the dataset with partially-received "
"state\n"));
@@ -4581,12 +4592,14 @@ zfs_do_send(int argc, char **argv)
}
if (flags.raw && redactbook != NULL) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("Error: raw sends may not be redacted.\n"));
return (1);
}
if (!flags.dryrun && isatty(STDOUT_FILENO)) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("Error: Stream can not be written to a terminal.\n"
"You must redirect standard output.\n"));
@@ -4595,19 +4608,24 @@ zfs_do_send(int argc, char **argv)
if (flags.saved) {
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
- if (zhp == NULL)
+ if (zhp == NULL) {
+ free(excludes.list);
return (1);
+ }
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
resume_token);
+ free(excludes.list);
zfs_close(zhp);
return (err != 0);
} else if (resume_token != NULL) {
+ free(excludes.list);
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
resume_token));
}
if (flags.skipmissing && !flags.replicate) {
+ free(excludes.list);
(void) fprintf(stderr,
gettext("skip-missing flag can only be used in "
"conjunction with replicate\n"));
@@ -4650,10 +4668,14 @@ zfs_do_send(int argc, char **argv)
}
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
- if (zhp == NULL)
+ if (zhp == NULL) {
+ free(excludes.list);
return (1);
+ }
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
redactbook);
+
+ free(excludes.list);
zfs_close(zhp);
return (err != 0);
}
@@ -4662,25 +4684,30 @@ zfs_do_send(int argc, char **argv)
(void) fprintf(stderr,
gettext("Error: multiple snapshots cannot be "
"sent from a bookmark.\n"));
+ free(excludes.list);
return (1);
}
if (redactbook != NULL) {
(void) fprintf(stderr, gettext("Error: multiple snapshots "
"cannot be sent redacted.\n"));
+ free(excludes.list);
return (1);
}
if ((cp = strchr(argv[0], '@')) == NULL) {
(void) fprintf(stderr, gettext("Error: "
"Unsupported flag with filesystem or bookmark.\n"));
+ free(excludes.list);
return (1);
}
*cp = '\0';
toname = cp + 1;
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
- if (zhp == NULL)
+ if (zhp == NULL) {
+ free(excludes.list);
return (1);
+ }
/*
* If they specified the full path to the snapshot, chop off
@@ -4700,6 +4727,8 @@ zfs_do_send(int argc, char **argv)
} else {
*cp = '\0';
if (cp != fromname && strcmp(argv[0], fromname)) {
+ zfs_close(zhp);
+ free(excludes.list);
(void) fprintf(stderr,
gettext("incremental source must be "
"in same filesystem\n"));
@@ -4707,6 +4736,8 @@ zfs_do_send(int argc, char **argv)
}
fromname = cp + 1;
if (strchr(fromname, '@') || strchr(fromname, '/')) {
+ zfs_close(zhp);
+ free(excludes.list);
(void) fprintf(stderr,
gettext("invalid incremental source\n"));
usage(B_FALSE);