Index: sbin/savecore/savecore.c =================================================================== --- sbin/savecore/savecore.c +++ sbin/savecore/savecore.c @@ -583,13 +583,14 @@ static void DoFile(const char *savedir, int savedirfd, const char *device) { - xo_handle_t *xostdout, *xoinfo; + xo_handle_t *xostdout; + xo_handle_t *xoinfo = NULL; static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX]; static char keyname[PATH_MAX]; static char *buf = NULL; char *temp = NULL; struct kerneldumpheader kdhf, kdhl; - uint8_t *dumpkey; + uint8_t *dumpkey = NULL; off_t mediasize, dumpextent, dumplength, firsthd, lasthd; FILE *core, *info; int fdcore, fddev, error; @@ -599,7 +600,6 @@ bool iscompressed, isencrypted, istextdump, ret; bounds = getbounds(savedirfd); - dumpkey = NULL; mediasize = 0; status = STATUS_UNKNOWN; @@ -959,35 +959,43 @@ } xo_close_container_h(xostdout, "crashdump"); xo_finish_h(xostdout); + xo_destroy(xoinfo); free(dumpkey); free(temp); close(fddev); + free(buf); + xo_destroy(xostdout); return; closeall: + xo_destroy(xoinfo); fclose(core); closefd: free(dumpkey); free(temp); close(fddev); + free(buf); + xo_destroy(xostdout); } -/* Prepend "/dev/" to any arguments that don't already have it */ -static char ** -devify(int argc, char **argv) +/* + * Prepend "/dev/" to any arguments that don't already have it. + * Return the number of devices + */ +static int +devify(int argc, char **argv, char ***devs) { - char **devs; int i, l; - devs = malloc(argc * sizeof(*argv)); - if (devs == NULL) { + *devs = malloc(argc * sizeof(*argv)); + if (*devs == NULL) { logmsg(LOG_ERR, "malloc(): %m"); exit(1); } for (i = 0; i < argc; i++) { if (strncmp(argv[i], _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) - devs[i] = strdup(argv[i]); + (*devs)[i] = strdup(argv[i]); else { char *fullpath; @@ -1005,17 +1013,20 @@ logmsg(LOG_ERR, "device name too long"); exit(1); } - devs[i] = fullpath; + (*devs)[i] = fullpath; } } - return (devs); + return (argc); } -static char ** -enum_dumpdevs(int *argcp) +/* + * Build a list of dump devices from /etc/fstab. + * Return the number of devices + */ +static int +enum_dumpdevs(char ***devs) { struct fstab *fsp; - char **argv; int argc, n; /* @@ -1025,8 +1036,8 @@ */ argc = 0; n = 8; - argv = malloc(n * sizeof(*argv)); - if (argv == NULL) { + *devs = malloc(n * sizeof(**devs)); + if (*devs == NULL) { logmsg(LOG_ERR, "malloc(): %m"); exit(1); } @@ -1039,24 +1050,34 @@ continue; if (argc >= n) { n *= 2; - argv = realloc(argv, n * sizeof(*argv)); - if (argv == NULL) { + *devs = realloc(*devs, n * sizeof(**devs)); + if (*devs == NULL) { logmsg(LOG_ERR, "realloc(): %m"); exit(1); } } - argv[argc] = strdup(fsp->fs_spec); - if (argv[argc] == NULL) { + (*devs)[argc] = strdup(fsp->fs_spec); + if ((*devs)[argc] == NULL) { logmsg(LOG_ERR, "strdup(): %m"); exit(1); } argc++; } - *argcp = argc; - return (argv); + return (argc); } static void +freedevs(int argc, char **devs) +{ + int i; + + for (i = 0; i < argc; i++) { + free(devs[i]); + } + free(devs); +} + +static void init_caps(int argc, char **argv) { cap_rights_t rights; @@ -1171,9 +1192,9 @@ argv++; } if (argc == 0) - devs = enum_dumpdevs(&argc); + argc = enum_dumpdevs(&devs); else - devs = devify(argc, argv); + argc = devify(argc, argv, &devs); savedirfd = open(savedir, O_RDONLY | O_DIRECTORY); if (savedirfd < 0) { @@ -1213,6 +1234,7 @@ logmsg(LOG_WARNING, "no unsaved dumps found"); } + freedevs(argc, devs); return (0); }