From 640a5a732e3d836c3a0f6992d4085468a486b4b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Mon, 3 May 2021 17:11:17 +0200 Subject: [PATCH] libselinux: matchpathcon: free memory on realloc failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case `realloc()` fails and returns NULL, free the passed array, instead of just setting the size helper variables to 0. Also free the string contents in `free_array_elts()` of the array `con_array`, instead of just the array of pointers. Found by cppcheck. src/matchpathcon.c:86:4: error: Common realloc mistake: 'con_array' nulled but not freed upon failure [memleakOnRealloc] con_array = (char **)realloc(con_array, sizeof(char*) * ^ Signed-off-by: Christian Göttsche --- libselinux/src/matchpathcon.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c index 9e1fab593266..075a3fb3ffcb 100644 --- a/libselinux/src/matchpathcon.c +++ b/libselinux/src/matchpathcon.c @@ -78,17 +78,30 @@ static pthread_once_t once = PTHREAD_ONCE_INIT; static pthread_key_t destructor_key; static int destructor_key_initialized = 0; +static void free_array_elts(void) +{ + int i; + for (i = 0; i < con_array_used; i++) + free(con_array[i]); + free(con_array); + + con_array_size = con_array_used = 0; + con_array = NULL; +} + static int add_array_elt(char *con) { + char **tmp; if (con_array_size) { while (con_array_used >= con_array_size) { con_array_size *= 2; - con_array = (char **)realloc(con_array, sizeof(char*) * + tmp = (char **)realloc(con_array, sizeof(char*) * con_array_size); - if (!con_array) { - con_array_size = con_array_used = 0; + if (!tmp) { + free_array_elts(); return -1; } + con_array = tmp; } } else { con_array_size = 1000; @@ -105,13 +118,6 @@ static int add_array_elt(char *con) return con_array_used++; } -static void free_array_elts(void) -{ - con_array_size = con_array_used = 0; - free(con_array); - con_array = NULL; -} - void set_matchpathcon_invalidcon(int (*f) (const char *p, unsigned l, char *c)) { myinvalidcon = f; -- 2.32.0.rc1