[PATCH v2 08/28] fs/squashfs: sqfs_search_dir: fix memory leaks

João Marcos Costa jmcosta944 at gmail.com
Tue Nov 3 13:39:58 CET 2020


Reviewed-by Joao Marcos Costa <jmcosta944 at gmail.com>

Em ter., 3 de nov. de 2020 às 08:12, Richard Genoud <
richard.genoud at posteo.net> escreveu:

> path, target, res, rem and sym_tokens were not free on error nor success.
>
> Signed-off-by: Richard Genoud <richard.genoud at posteo.net>
> ---
>  fs/squashfs/sqfs.c | 64 ++++++++++++++++++++++++++++++++++++----------
>  1 file changed, 51 insertions(+), 13 deletions(-)
>
> diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c
> index 78893b5c85d..1714306e747 100644
> --- a/fs/squashfs/sqfs.c
> +++ b/fs/squashfs/sqfs.c
> @@ -434,7 +434,7 @@ static int sqfs_search_dir(struct squashfs_dir_stream
> *dirs, char **token_list,
>  {
>         struct squashfs_super_block *sblk = ctxt.sblk;
>         char *path, *target, **sym_tokens, *res, *rem;
> -       int j, ret, new_inode_number, offset;
> +       int j, ret = 0, new_inode_number, offset;
>         struct squashfs_symlink_inode *sym;
>         struct squashfs_ldir_inode *ldir;
>         struct squashfs_dir_inode *dir;
> @@ -442,6 +442,12 @@ static int sqfs_search_dir(struct squashfs_dir_stream
> *dirs, char **token_list,
>         struct fs_dirent *dent;
>         unsigned char *table;
>
> +       res = NULL;
> +       rem = NULL;
> +       path = NULL;
> +       target = NULL;
> +       sym_tokens = NULL;
> +
>         dirsp = (struct fs_dir_stream *)dirs;
>
>         /* Start by root inode */
> @@ -477,7 +483,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream
> *dirs, char **token_list,
>         for (j = 0; j < token_count; j++) {
>                 if (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) {
>                         printf("** Cannot find directory. **\n");
> -                       return -EINVAL;
> +                       ret = -EINVAL;
> +                       goto out;
>                 }
>
>                 while (!sqfs_readdir(dirsp, &dent)) {
> @@ -490,7 +497,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream
> *dirs, char **token_list,
>
>                 if (ret) {
>                         printf("** Cannot find directory. **\n");
> -                       return -EINVAL;
> +                       ret = -EINVAL;
> +                       goto out;
>                 }
>
>                 /* Redefine inode as the found token */
> @@ -507,40 +515,63 @@ static int sqfs_search_dir(struct
> squashfs_dir_stream *dirs, char **token_list,
>                         sym = (struct squashfs_symlink_inode *)table;
>                         /* Get first j + 1 tokens */
>                         path = sqfs_concat_tokens(token_list, j + 1);
> +                       if (!path) {
> +                               ret = -ENOMEM;
> +                               goto out;
> +                       }
>                         /* Resolve for these tokens */
>                         target = sqfs_resolve_symlink(sym, path);
> +                       if (!target) {
> +                               ret = -ENOMEM;
> +                               goto out;
> +                       }
>                         /* Join remaining tokens */
>                         rem = sqfs_concat_tokens(token_list + j + 1,
> token_count -
>                                                  j - 1);
> +                       if (!rem) {
> +                               ret = -ENOMEM;
> +                               goto out;
> +                       }
>                         /* Concatenate remaining tokens and symlink's
> target */
>                         res = malloc(strlen(rem) + strlen(target) + 1);
> +                       if (!res) {
> +                               ret = -ENOMEM;
> +                               goto out;
> +                       }
>                         strcpy(res, target);
>                         res[strlen(target)] = '/';
>                         strcpy(res + strlen(target) + 1, rem);
>                         token_count = sqfs_count_tokens(res);
>
> -                       if (token_count < 0)
> -                               return -EINVAL;
> +                       if (token_count < 0) {
> +                               ret = -EINVAL;
> +                               goto out;
> +                       }
>
>                         sym_tokens = malloc(token_count * sizeof(char *));
> -                       if (!sym_tokens)
> -                               return -EINVAL;
> +                       if (!sym_tokens) {
> +                               ret = -EINVAL;
> +                               goto out;
> +                       }
>
>                         /* Fill tokens list */
>                         ret = sqfs_tokenize(sym_tokens, token_count, res);
> -                       if (ret)
> -                               return -EINVAL;
> +                       if (ret) {
> +                               ret = -EINVAL;
> +                               goto out;
> +                       }
>                         free(dirs->entry);
>                         dirs->entry = NULL;
>
>                         ret = sqfs_search_dir(dirs, sym_tokens,
> token_count,
>                                               m_list, m_count);
> -                       return ret;
> +                       goto out;
>                 } else if
> (!sqfs_is_dir(get_unaligned_le16(&dir->inode_type))) {
>                         printf("** Cannot find directory. **\n");
>                         free(dirs->entry);
>                         dirs->entry = NULL;
> -                       return -EINVAL;
> +                       ret = -EINVAL;
> +                       goto out;
>                 }
>
>                 /* Check if it is an extended dir. */
> @@ -560,7 +591,8 @@ static int sqfs_search_dir(struct squashfs_dir_stream
> *dirs, char **token_list,
>                         printf("Empty directory.\n");
>                         free(dirs->entry);
>                         dirs->entry = NULL;
> -                       return SQFS_EMPTY_DIR;
> +                       ret = SQFS_EMPTY_DIR;
> +                       goto out;
>                 }
>
>                 dirs->table += SQFS_DIR_HEADER_SIZE;
> @@ -579,7 +611,13 @@ static int sqfs_search_dir(struct squashfs_dir_stream
> *dirs, char **token_list,
>         else
>                 memcpy(&dirs->i_ldir, ldir, sizeof(*ldir));
>
> -       return 0;
> +out:
> +       free(res);
> +       free(rem);
> +       free(path);
> +       free(target);
> +       free(sym_tokens);
> +       return ret;
>  }
>
>  /*
>


-- 
Atenciosamente,
João Marcos Costa

www.linkedin.com/in/jmarcoscosta/
https://github.com/jmarcoscosta


More information about the U-Boot mailing list