From f3cc6f7adbd8dd692c459a2ac7d213f8ca7a74c4 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Wed, 19 Jun 2024 04:48:57 +0200 Subject: [PATCH] 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 --- tests/fssum.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/tests/fssum.c b/tests/fssum.c index 9ae21c6e..d3d2870a 100644 --- a/tests/fssum.c +++ b/tests/fssum.c @@ -524,6 +524,7 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in) int ret; int fd; int excl; + int error = 0; sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ? sum_file_data_strict : sum_file_data_permissive; 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, "..")) continue; if (entries == alloclen) { + void *tmp; + alloclen += CHUNKS; - namelist = realloc(namelist, - alloclen * sizeof(*namelist)); - if (!namelist) { - fprintf(stderr, "malloc failed\n"); - exit(-1); + tmp = realloc(namelist, alloclen * sizeof(*namelist)); + if (!tmp) { + fprintf(stderr, "realloc failed\n"); + error = 1; + goto free_namelist; } + namelist = tmp; } namelist[entries] = strdup(de->d_name); if (!namelist[entries]) { - fprintf(stderr, "malloc failed\n"); - exit(-1); + fprintf(stderr, "stdup failed\n"); + error = 1; + goto free_namelist; } ++entries; } @@ -577,13 +582,15 @@ sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in) ret = fchdir(dirfd); if (ret == -1) { perror("fchdir"); - exit(-1); + error = 1; + goto free_namelist; } ret = lstat(namelist[i], &st); if (ret) { fprintf(stderr, "stat failed for %s/%s: %m\n", path_prefix, path); - exit(-1); + error = 1; + goto free_namelist; } /* 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: free(path); } + +free_namelist: + closedir(d); + for (i = 0; i < entries; i++) + free(namelist[i]); + free(namelist); + if (error) + exit(-1); } int