From 056f9dbfe9e9c27452629ec48ef70686328e5a3c Mon Sep 17 00:00:00 2001 From: shixuantong Date: Thu, 24 Nov 2022 21:28:49 +0800 Subject: [PATCH] fix memory leak and use-after-free bugs of struct TAR *t [1] fix CVE-2021-33640 The error information is as fllows: Error: USE_AFTER_FREE (CWE-416): libtar-v1.2.20/libtar/libtar.c:220:freeed_arg: "tar_close" frees "t". libtar-v1.2.20/libtar/libtar.c:222:deref_after_free: Dereferencing freed pointer "t". # 220| if (tar_close(t) != 0) # 221| { # 222|-> free_longlink_longname(t->th_buf); # 223| fprintf(stderr, "tar_close: %s\n", strerror(errno)); # 224| return -1; Error: USE_AFTER_FREE(CWE-416): libtar-v1.2.20/libtar/libtar.c:220:freeed_arg:"tar_close" frees "t". libtar-v1.2.20/libtar/libtar.c:227:deref_after_free: Dereferencing freed pointer"t". # 225| } # 226| # 227|-> free_longlink_longname(t->th_buf); # 228| return 0; # 229|} The pointer "t" is freed in tar_close() function, but the pointer "t" is still used after tar_close() is called in the list() function. Now, we put the free_longlink_longname() function in tar_close() function. [2]fix one memory leak bug: Release the memory of variable "TAR *t" in lib/extract.c:list() --- lib/handle.c | 1 + lib/util.c | 6 ++++++ libtar/libtar.c | 4 +--- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/handle.c b/lib/handle.c index 28a7dc2..ae829a9 100644 --- a/lib/handle.c +++ b/lib/handle.c @@ -124,6 +124,7 @@ tar_close(TAR *t) : (libtar_freefunc_t)tar_dev_free)); if (t->th_pathname != NULL) free(t->th_pathname); + free_longlink_longname(t->th_buf); free(t); return i; diff --git a/lib/util.c b/lib/util.c index 8a42e62..108ce23 100644 --- a/lib/util.c +++ b/lib/util.c @@ -164,7 +164,13 @@ int_to_oct_nonull(int num, char *oct, size_t octlen) void free_longlink_longname(struct tar_header th_buf) { if (th_buf.gnu_longname != NULL) + { free(th_buf.gnu_longname); + th_buf.gnu_longname = NULL; + } if (th_buf.gnu_longlink !=NULL) + { free(th_buf.gnu_longlink); + th_buf.gnu_longlink = NULL; + } } diff --git a/libtar/libtar.c b/libtar/libtar.c index 7e7354f..8c89211 100644 --- a/libtar/libtar.c +++ b/libtar/libtar.c @@ -196,7 +196,7 @@ list(char *tarfile) { fprintf(stderr, "tar_skip_regfile(): %s\n", strerror(errno)); - free_longlink_longname(t->th_buf); + tar_close(t); return -1; } } @@ -218,12 +218,10 @@ list(char *tarfile) if (tar_close(t) != 0) { - free_longlink_longname(t->th_buf); fprintf(stderr, "tar_close(): %s\n", strerror(errno)); return -1; } - free_longlink_longname(t->th_buf); return 0; } -- 2.27.0