fs/squashfs: sqfs_get_abs_path: fix possible memory leak on error

if  sqfs_tokenize(rel_tokens, rc, rel); fails, the function exits
without freeing the array base_tokens.

Reviewed-by: Joao Marcos Costa <jmcosta944@gmail.com>
Signed-off-by: Richard Genoud <richard.genoud@posteo.net>
This commit is contained in:
Richard Genoud 2020-11-03 12:11:17 +01:00 committed by Tom Rini
parent 53db0e24a8
commit 33686804d2

View File

@ -340,28 +340,31 @@ static char *sqfs_get_abs_path(const char *base, const char *rel)
char **base_tokens, **rel_tokens, *resolved = NULL; char **base_tokens, **rel_tokens, *resolved = NULL;
int ret, bc, rc, i, updir = 0, resolved_size = 0, offset = 0; int ret, bc, rc, i, updir = 0, resolved_size = 0, offset = 0;
base_tokens = NULL;
rel_tokens = NULL;
/* Memory allocation for the token lists */ /* Memory allocation for the token lists */
bc = sqfs_count_tokens(base); bc = sqfs_count_tokens(base);
rc = sqfs_count_tokens(rel); rc = sqfs_count_tokens(rel);
if (bc < 1 || rc < 1) if (bc < 1 || rc < 1)
return NULL; return NULL;
base_tokens = malloc(bc * sizeof(char *)); base_tokens = calloc(bc, sizeof(char *));
if (!base_tokens) if (!base_tokens)
return NULL; return NULL;
rel_tokens = malloc(rc * sizeof(char *)); rel_tokens = calloc(rc, sizeof(char *));
if (!rel_tokens) if (!rel_tokens)
goto free_b_tokens; goto out;
/* Fill token lists */ /* Fill token lists */
ret = sqfs_tokenize(base_tokens, bc, base); ret = sqfs_tokenize(base_tokens, bc, base);
if (ret) if (ret)
goto free_r_tokens; goto out;
ret = sqfs_tokenize(rel_tokens, rc, rel); ret = sqfs_tokenize(rel_tokens, rc, rel);
if (ret) if (ret)
goto free_r_tokens; goto out;
/* count '..' occurrences in target path */ /* count '..' occurrences in target path */
for (i = 0; i < rc; i++) { for (i = 0; i < rc; i++) {
@ -372,7 +375,7 @@ static char *sqfs_get_abs_path(const char *base, const char *rel)
/* Remove the last token and the '..' occurrences */ /* Remove the last token and the '..' occurrences */
bc = sqfs_clean_base_path(base_tokens, bc, updir); bc = sqfs_clean_base_path(base_tokens, bc, updir);
if (bc < 0) if (bc < 0)
goto free_r_tokens; goto out;
/* Calculate resolved path size */ /* Calculate resolved path size */
if (!bc) if (!bc)
@ -383,7 +386,7 @@ static char *sqfs_get_abs_path(const char *base, const char *rel)
resolved = malloc(resolved_size + 1); resolved = malloc(resolved_size + 1);
if (!resolved) if (!resolved)
goto free_r_tokens_loop; goto out;
/* Set resolved path */ /* Set resolved path */
memset(resolved, '\0', resolved_size + 1); memset(resolved, '\0', resolved_size + 1);
@ -391,14 +394,15 @@ static char *sqfs_get_abs_path(const char *base, const char *rel)
resolved[offset++] = '/'; resolved[offset++] = '/';
offset += sqfs_join(rel_tokens, resolved + offset, updir, rc, '/'); offset += sqfs_join(rel_tokens, resolved + offset, updir, rc, '/');
free_r_tokens_loop: out:
for (i = 0; i < rc; i++) if (rel_tokens)
free(rel_tokens[i]); for (i = 0; i < rc; i++)
for (i = 0; i < bc; i++) free(rel_tokens[i]);
free(base_tokens[i]); if (base_tokens)
free_r_tokens: for (i = 0; i < bc; i++)
free(base_tokens[i]);
free(rel_tokens); free(rel_tokens);
free_b_tokens:
free(base_tokens); free(base_tokens);
return resolved; return resolved;