mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-11-17 01:51:00 +03:00
Fix userland memory leak in zfs_do_send()
Clang 15's static analyzer caught this. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Closes #14045
This commit is contained in:
parent
5405be0365
commit
219cf0f928
@ -4504,6 +4504,7 @@ zfs_do_send(int argc, char **argv)
|
|||||||
gettext("missing argument for '%s' "
|
gettext("missing argument for '%s' "
|
||||||
"option\n"), argv[optind - 1]);
|
"option\n"), argv[optind - 1]);
|
||||||
}
|
}
|
||||||
|
free(excludes.list);
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
@ -4522,6 +4523,7 @@ zfs_do_send(int argc, char **argv)
|
|||||||
argv[optind - 1]);
|
argv[optind - 1]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
free(excludes.list);
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4530,6 +4532,7 @@ zfs_do_send(int argc, char **argv)
|
|||||||
flags.verbosity = 1;
|
flags.verbosity = 1;
|
||||||
|
|
||||||
if (excludes.count > 0 && !flags.replicate) {
|
if (excludes.count > 0 && !flags.replicate) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr, gettext("Cannot specify "
|
(void) fprintf(stderr, gettext("Cannot specify "
|
||||||
"dataset exclusion (-X) on a non-recursive "
|
"dataset exclusion (-X) on a non-recursive "
|
||||||
"send.\n"));
|
"send.\n"));
|
||||||
@ -4543,21 +4546,25 @@ zfs_do_send(int argc, char **argv)
|
|||||||
if (fromname != NULL || flags.replicate || flags.props ||
|
if (fromname != NULL || flags.replicate || flags.props ||
|
||||||
flags.backup || flags.holds ||
|
flags.backup || flags.holds ||
|
||||||
flags.saved || redactbook != NULL) {
|
flags.saved || redactbook != NULL) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("invalid flags combined with -t\n"));
|
gettext("invalid flags combined with -t\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
if (argc > 0) {
|
if (argc > 0) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("missing snapshot argument\n"));
|
gettext("missing snapshot argument\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr, gettext("too many arguments\n"));
|
(void) fprintf(stderr, gettext("too many arguments\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
@ -4568,11 +4575,15 @@ zfs_do_send(int argc, char **argv)
|
|||||||
flags.doall || flags.backup ||
|
flags.doall || flags.backup ||
|
||||||
flags.holds || flags.largeblock || flags.embed_data ||
|
flags.holds || flags.largeblock || flags.embed_data ||
|
||||||
flags.compress || flags.raw || redactbook != NULL) {
|
flags.compress || flags.raw || redactbook != NULL) {
|
||||||
|
free(excludes.list);
|
||||||
|
|
||||||
(void) fprintf(stderr, gettext("incompatible flags "
|
(void) fprintf(stderr, gettext("incompatible flags "
|
||||||
"combined with saved send flag\n"));
|
"combined with saved send flag\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
}
|
}
|
||||||
if (strchr(argv[0], '@') != NULL) {
|
if (strchr(argv[0], '@') != NULL) {
|
||||||
|
free(excludes.list);
|
||||||
|
|
||||||
(void) fprintf(stderr, gettext("saved send must "
|
(void) fprintf(stderr, gettext("saved send must "
|
||||||
"specify the dataset with partially-received "
|
"specify the dataset with partially-received "
|
||||||
"state\n"));
|
"state\n"));
|
||||||
@ -4581,12 +4592,14 @@ zfs_do_send(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags.raw && redactbook != NULL) {
|
if (flags.raw && redactbook != NULL) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("Error: raw sends may not be redacted.\n"));
|
gettext("Error: raw sends may not be redacted.\n"));
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!flags.dryrun && isatty(STDOUT_FILENO)) {
|
if (!flags.dryrun && isatty(STDOUT_FILENO)) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("Error: Stream can not be written to a terminal.\n"
|
gettext("Error: Stream can not be written to a terminal.\n"
|
||||||
"You must redirect standard output.\n"));
|
"You must redirect standard output.\n"));
|
||||||
@ -4595,19 +4608,24 @@ zfs_do_send(int argc, char **argv)
|
|||||||
|
|
||||||
if (flags.saved) {
|
if (flags.saved) {
|
||||||
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
|
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
|
||||||
if (zhp == NULL)
|
if (zhp == NULL) {
|
||||||
|
free(excludes.list);
|
||||||
return (1);
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
|
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
|
||||||
resume_token);
|
resume_token);
|
||||||
|
free(excludes.list);
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
return (err != 0);
|
return (err != 0);
|
||||||
} else if (resume_token != NULL) {
|
} else if (resume_token != NULL) {
|
||||||
|
free(excludes.list);
|
||||||
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
|
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
|
||||||
resume_token));
|
resume_token));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags.skipmissing && !flags.replicate) {
|
if (flags.skipmissing && !flags.replicate) {
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("skip-missing flag can only be used in "
|
gettext("skip-missing flag can only be used in "
|
||||||
"conjunction with replicate\n"));
|
"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);
|
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET);
|
||||||
if (zhp == NULL)
|
if (zhp == NULL) {
|
||||||
|
free(excludes.list);
|
||||||
return (1);
|
return (1);
|
||||||
|
}
|
||||||
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
|
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
|
||||||
redactbook);
|
redactbook);
|
||||||
|
|
||||||
|
free(excludes.list);
|
||||||
zfs_close(zhp);
|
zfs_close(zhp);
|
||||||
return (err != 0);
|
return (err != 0);
|
||||||
}
|
}
|
||||||
@ -4662,25 +4684,30 @@ zfs_do_send(int argc, char **argv)
|
|||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("Error: multiple snapshots cannot be "
|
gettext("Error: multiple snapshots cannot be "
|
||||||
"sent from a bookmark.\n"));
|
"sent from a bookmark.\n"));
|
||||||
|
free(excludes.list);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redactbook != NULL) {
|
if (redactbook != NULL) {
|
||||||
(void) fprintf(stderr, gettext("Error: multiple snapshots "
|
(void) fprintf(stderr, gettext("Error: multiple snapshots "
|
||||||
"cannot be sent redacted.\n"));
|
"cannot be sent redacted.\n"));
|
||||||
|
free(excludes.list);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cp = strchr(argv[0], '@')) == NULL) {
|
if ((cp = strchr(argv[0], '@')) == NULL) {
|
||||||
(void) fprintf(stderr, gettext("Error: "
|
(void) fprintf(stderr, gettext("Error: "
|
||||||
"Unsupported flag with filesystem or bookmark.\n"));
|
"Unsupported flag with filesystem or bookmark.\n"));
|
||||||
|
free(excludes.list);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
toname = cp + 1;
|
toname = cp + 1;
|
||||||
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
|
||||||
if (zhp == NULL)
|
if (zhp == NULL) {
|
||||||
|
free(excludes.list);
|
||||||
return (1);
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If they specified the full path to the snapshot, chop off
|
* If they specified the full path to the snapshot, chop off
|
||||||
@ -4700,6 +4727,8 @@ zfs_do_send(int argc, char **argv)
|
|||||||
} else {
|
} else {
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
if (cp != fromname && strcmp(argv[0], fromname)) {
|
if (cp != fromname && strcmp(argv[0], fromname)) {
|
||||||
|
zfs_close(zhp);
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("incremental source must be "
|
gettext("incremental source must be "
|
||||||
"in same filesystem\n"));
|
"in same filesystem\n"));
|
||||||
@ -4707,6 +4736,8 @@ zfs_do_send(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
fromname = cp + 1;
|
fromname = cp + 1;
|
||||||
if (strchr(fromname, '@') || strchr(fromname, '/')) {
|
if (strchr(fromname, '@') || strchr(fromname, '/')) {
|
||||||
|
zfs_close(zhp);
|
||||||
|
free(excludes.list);
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
gettext("invalid incremental source\n"));
|
gettext("invalid incremental source\n"));
|
||||||
usage(B_FALSE);
|
usage(B_FALSE);
|
||||||
|
Loading…
Reference in New Issue
Block a user