diff mbox series

[v2,06/12] ref-filter: also free head for ATOM_HEAD to avoid leak

Message ID 20210725130830.5145-7-andrzej@ahunt.org (mailing list archive)
State Accepted
Commit d7cf4188e2e85faa00552b8616db31a17844df1b
Headers show
Series [v2,01/12] fmt-merge-msg: free newly allocated temporary strings when done | expand

Commit Message

Andrzej Hunt July 25, 2021, 1:08 p.m. UTC
From: Andrzej Hunt <ajrhunt@google.com>

u.head is populated using resolve_refdup(), which returns a newly
allocated string - hence we also need to free() it.

Found while running t0041 with LSAN:

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x486804 in strdup ../projects/compiler-rt/lib/asan/asan_interceptors.cpp:452:3
    #1 0xa8be98 in xstrdup wrapper.c:29:14
    #2 0x9481db in head_atom_parser ref-filter.c:549:17
    #3 0x9408c7 in parse_ref_filter_atom ref-filter.c:703:30
    #4 0x9400e3 in verify_ref_format ref-filter.c:974:8
    #5 0x4f9e8b in print_ref_list builtin/branch.c:439:6
    #6 0x4f9e8b in cmd_branch builtin/branch.c:757:3
    #7 0x4ce83e in run_builtin git.c:475:11
    #8 0x4ccafe in handle_builtin git.c:729:3
    #9 0x4cb01c in run_argv git.c:818:4
    #10 0x4cb01c in cmd_main git.c:949:19
    #11 0x6bdc2d in main common-main.c:52:11
    #12 0x7f96edf86349 in __libc_start_main (/lib64/libc.so.6+0x24349)

SUMMARY: AddressSanitizer: 16 byte(s) leaked in 1 allocation(s).

Signed-off-by: Andrzej Hunt <andrzej@ahunt.org>
---
 ref-filter.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Comments

Junio C Hamano July 26, 2021, 8:04 p.m. UTC | #1
andrzej@ahunt.org writes:

> From: Andrzej Hunt <ajrhunt@google.com>
>
> u.head is populated using resolve_refdup(), which returns a newly
> allocated string - hence we also need to free() it.

Correct.  The solution makes me wonder if this approach scales as we
add more and more members to u.* union that need deallocating, but
for now, this is perfectly adequate.

Thanks.

>
> Found while running t0041 with LSAN:
>
> Direct leak of 16 byte(s) in 1 object(s) allocated from:
>     #0 0x486804 in strdup ../projects/compiler-rt/lib/asan/asan_interceptors.cpp:452:3
>     #1 0xa8be98 in xstrdup wrapper.c:29:14
>     #2 0x9481db in head_atom_parser ref-filter.c:549:17
>     #3 0x9408c7 in parse_ref_filter_atom ref-filter.c:703:30
>     #4 0x9400e3 in verify_ref_format ref-filter.c:974:8
>     #5 0x4f9e8b in print_ref_list builtin/branch.c:439:6
>     #6 0x4f9e8b in cmd_branch builtin/branch.c:757:3
>     #7 0x4ce83e in run_builtin git.c:475:11
>     #8 0x4ccafe in handle_builtin git.c:729:3
>     #9 0x4cb01c in run_argv git.c:818:4
>     #10 0x4cb01c in cmd_main git.c:949:19
>     #11 0x6bdc2d in main common-main.c:52:11
>     #12 0x7f96edf86349 in __libc_start_main (/lib64/libc.so.6+0x24349)
>
> SUMMARY: AddressSanitizer: 16 byte(s) leaked in 1 allocation(s).
>
> Signed-off-by: Andrzej Hunt <andrzej@ahunt.org>
> ---
>  ref-filter.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/ref-filter.c b/ref-filter.c
> index f45d3a1b26..0cfef7b719 100644
> --- a/ref-filter.c
> +++ b/ref-filter.c
> @@ -2226,8 +2226,12 @@ void ref_array_clear(struct ref_array *array)
>  	FREE_AND_NULL(array->items);
>  	array->nr = array->alloc = 0;
>  
> -	for (i = 0; i < used_atom_cnt; i++)
> -		free((char *)used_atom[i].name);
> +	for (i = 0; i < used_atom_cnt; i++) {
> +		struct used_atom *atom = &used_atom[i];
> +		if (atom->atom_type == ATOM_HEAD)
> +			free(atom->u.head);
> +		free((char *)atom->name);
> +	}
>  	FREE_AND_NULL(used_atom);
>  	used_atom_cnt = 0;
diff mbox series

Patch

diff --git a/ref-filter.c b/ref-filter.c
index f45d3a1b26..0cfef7b719 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -2226,8 +2226,12 @@  void ref_array_clear(struct ref_array *array)
 	FREE_AND_NULL(array->items);
 	array->nr = array->alloc = 0;
 
-	for (i = 0; i < used_atom_cnt; i++)
-		free((char *)used_atom[i].name);
+	for (i = 0; i < used_atom_cnt; i++) {
+		struct used_atom *atom = &used_atom[i];
+		if (atom->atom_type == ATOM_HEAD)
+			free(atom->u.head);
+		free((char *)atom->name);
+	}
 	FREE_AND_NULL(used_atom);
 	used_atom_cnt = 0;