diff options
author | Richard Genoud <richard.genoud@posteo.net> | 2020-11-03 12:11:00 +0100 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-11-19 09:45:49 -0500 |
commit | f268768d43bbf11c7107597abef57c6b86b6b229 (patch) | |
tree | decd6325b74ce79ad9046022ea59bab84c2d7cda /fs/squashfs | |
parent | 1b1e0c019588afc64a639b89fd0b6cd12534bce4 (diff) | |
download | u-boot-f268768d43bbf11c7107597abef57c6b86b6b229.tar.gz u-boot-f268768d43bbf11c7107597abef57c6b86b6b229.tar.bz2 u-boot-f268768d43bbf11c7107597abef57c6b86b6b229.zip |
fs/squashfs: sqfs_opendir: fix some memory leaks and dangling pointers
When trying to load an non-existing file, the cpu hangs!
Signed-off-by: Richard Genoud <richard.genoud@posteo.net>
Diffstat (limited to 'fs/squashfs')
-rw-r--r-- | fs/squashfs/sqfs.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 15208b4dab..1fdb9ac534 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -821,22 +821,37 @@ int sqfs_opendir(const char *filename, struct fs_dir_stream **dirsp) if (!dirs) return -EINVAL; + /* these should be set to NULL to prevent dangling pointers */ + dirs->dir_header = NULL; + dirs->entry = NULL; + dirs->table = NULL; + dirs->inode_table = NULL; + dirs->dir_table = NULL; + ret = sqfs_read_inode_table(&inode_table); - if (ret) - return -EINVAL; + if (ret) { + ret = -EINVAL; + goto free_dirs; + } metablks_count = sqfs_read_directory_table(&dir_table, &pos_list); - if (metablks_count < 1) - return -EINVAL; + if (metablks_count < 1) { + ret = -EINVAL; + goto free_inode_table; + } /* Tokenize filename */ token_count = sqfs_count_tokens(filename); - if (token_count < 0) - return -EINVAL; + if (token_count < 0) { + ret = -EINVAL; + goto free_inode_table; + } path = strdup(filename); - if (!path) - return -ENOMEM; + if (!path) { + ret = -EINVAL; + goto free_inode_table; + } token_list = malloc(token_count * sizeof(char *)); if (!token_list) { @@ -882,6 +897,12 @@ free_tokens: free(pos_list); free_path: free(path); +free_inode_table: + if (ret) + free(inode_table); +free_dirs: + if (ret) + free(dirs); return ret; } |