btrfs-progs: tests: fix fssum ASAN memory leak reports

Free memory after errors in sum(), this is reported by gcc 13 on the CI.

This was reproduced by:

$ make D=asan TEST=019-receive-clones-on-mounted-subvol test-misc

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2024-06-19 04:48:57 +02:00 committed by Qu Wenruo
parent ea4ae56160
commit f3cc6f7adb

View file

@ -524,6 +524,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
int ret; int ret;
int fd; int fd;
int excl; int excl;
int error = 0;
sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ? sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ?
sum_file_data_strict : sum_file_data_permissive; sum_file_data_strict : sum_file_data_permissive;
struct stat dir_st; struct stat dir_st;
@ -542,18 +543,22 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
continue; continue;
if (entries == alloclen) { if (entries == alloclen) {
void *tmp;
alloclen += CHUNKS; alloclen += CHUNKS;
namelist = realloc(namelist, tmp = realloc(namelist, alloclen * sizeof(*namelist));
alloclen * sizeof(*namelist)); if (!tmp) {
if (!namelist) { fprintf(stderr, "realloc failed\n");
fprintf(stderr, "malloc failed\n"); error = 1;
exit(-1); goto free_namelist;
} }
namelist = tmp;
} }
namelist[entries] = strdup(de->d_name); namelist[entries] = strdup(de->d_name);
if (!namelist[entries]) { if (!namelist[entries]) {
fprintf(stderr, "malloc failed\n"); fprintf(stderr, "stdup failed\n");
exit(-1); error = 1;
goto free_namelist;
} }
++entries; ++entries;
} }
@ -577,13 +582,15 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
ret = fchdir(dirfd); ret = fchdir(dirfd);
if (ret == -1) { if (ret == -1) {
perror("fchdir"); perror("fchdir");
exit(-1); error = 1;
goto free_namelist;
} }
ret = lstat(namelist[i], &st); ret = lstat(namelist[i], &st);
if (ret) { if (ret) {
fprintf(stderr, "stat failed for %s/%s: %m\n", fprintf(stderr, "stat failed for %s/%s: %m\n",
path_prefix, path); path_prefix, path);
exit(-1); error = 1;
goto free_namelist;
} }
/* We are crossing into a different subvol, skip this subtree. */ /* We are crossing into a different subvol, skip this subtree. */
@ -704,6 +711,14 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
next: next:
free(path); free(path);
} }
free_namelist:
closedir(d);
for (i = 0; i < entries; i++)
free(namelist[i]);
free(namelist);
if (error)
exit(-1);
} }
int int