From 5487477802e0ad7bfad046af25f4a04cfd98cb7a Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Tue, 3 Nov 2020 12:11:03 +0100 Subject: [PATCH] fs/squashfs: sqfs_split_path: fix memory leak and dangling pointers *file and *dir were not freed on error Reviewed-by: Joao Marcos Costa Signed-off-by: Richard Genoud --- fs/squashfs/sqfs.c | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 0ac922af9e..58b8bfc66d 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1089,15 +1089,27 @@ static int sqfs_split_path(char **file, char **dir, const char *path) char *dirc, *basec, *bname, *dname, *tmp_path; int ret = 0; + *file = NULL; + *dir = NULL; + dirc = NULL; + basec = NULL; + bname = NULL; + dname = NULL; + tmp_path = NULL; + /* check for first slash in path*/ if (path[0] == '/') { tmp_path = strdup(path); - if (!tmp_path) - return -ENOMEM; + if (!tmp_path) { + ret = -ENOMEM; + goto out; + } } else { tmp_path = malloc(strlen(path) + 2); - if (!tmp_path) - return -ENOMEM; + if (!tmp_path) { + ret = -ENOMEM; + goto out; + } tmp_path[0] = '/'; strcpy(tmp_path + 1, path); } @@ -1106,13 +1118,13 @@ static int sqfs_split_path(char **file, char **dir, const char *path) dirc = strdup(tmp_path); if (!dirc) { ret = -ENOMEM; - goto free_tmp; + goto out; } basec = strdup(tmp_path); if (!basec) { ret = -ENOMEM; - goto free_dirc; + goto out; } dname = sqfs_dirname(dirc); @@ -1122,14 +1134,14 @@ static int sqfs_split_path(char **file, char **dir, const char *path) if (!*file) { ret = -ENOMEM; - goto free_basec; + goto out; } if (*dname == '\0') { *dir = malloc(2); if (!*dir) { ret = -ENOMEM; - goto free_basec; + goto out; } (*dir)[0] = '/'; @@ -1138,15 +1150,19 @@ static int sqfs_split_path(char **file, char **dir, const char *path) *dir = strdup(dname); if (!*dir) { ret = -ENOMEM; - goto free_basec; + goto out; } } -free_basec: +out: + if (ret) { + free(*file); + free(*dir); + *dir = NULL; + *file = NULL; + } free(basec); -free_dirc: free(dirc); -free_tmp: free(tmp_path); return ret;