diff options
author | Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi> | 2017-10-01 02:25:22 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2017-10-08 16:19:56 -0400 |
commit | af609e3764ea3ed7c0ccad8e57f9d9671c81c3e8 (patch) | |
tree | a680cc06ac395af2a49a48b5d5107e5de4b084e7 | |
parent | 09fa964bba80c45432660f0e64362181900a5aef (diff) | |
download | u-boot-af609e3764ea3ed7c0ccad8e57f9d9671c81c3e8.zip u-boot-af609e3764ea3ed7c0ccad8e57f9d9671c81c3e8.tar.gz u-boot-af609e3764ea3ed7c0ccad8e57f9d9671c81c3e8.tar.bz2 |
fs/fat: Check malloc return values and fix memory leaks
Check malloc() return values and properly unwind on errors so
memory allocated for fat_itr structures get freed properly.
Also fixes a leak of fsdata.fatbuf in fat_size().
Fixes: 2460098cffacd1 ("fs/fat: Reduce stack usage")
Reported-by: Coverity (CID: 167225, 167233, 167234)
Signed-off-by: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
Reviewed-by: Tom Rini <trini@konsulko.com>
-rw-r--r-- | fs/fat/fat.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 35941c1..7fe7843 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1039,12 +1039,15 @@ int fat_exists(const char *filename) int ret; itr = malloc_cache_aligned(sizeof(fat_itr)); + if (!itr) + return 0; ret = fat_itr_root(itr, &fsdata); if (ret) - return 0; + goto out; ret = fat_itr_resolve(itr, filename, TYPE_ANY); free(fsdata.fatbuf); +out: free(itr); return ret == 0; } @@ -1056,9 +1059,11 @@ int fat_size(const char *filename, loff_t *size) int ret; itr = malloc_cache_aligned(sizeof(fat_itr)); + if (!itr) + return -ENOMEM; ret = fat_itr_root(itr, &fsdata); if (ret) - return ret; + goto out_free_itr; ret = fat_itr_resolve(itr, filename, TYPE_FILE); if (ret) { @@ -1072,12 +1077,13 @@ int fat_size(const char *filename, loff_t *size) *size = 0; ret = 0; } - goto out; + goto out_free_both; } *size = FAT2CPU32(itr->dent->size); +out_free_both: free(fsdata.fatbuf); -out: +out_free_itr: free(itr); return ret; } @@ -1090,19 +1096,22 @@ int file_fat_read_at(const char *filename, loff_t pos, void *buffer, int ret; itr = malloc_cache_aligned(sizeof(fat_itr)); + if (!itr) + return -ENOMEM; ret = fat_itr_root(itr, &fsdata); if (ret) - return ret; + goto out_free_itr; ret = fat_itr_resolve(itr, filename, TYPE_FILE); if (ret) - goto out; + goto out_free_both; printf("reading %s\n", filename); ret = get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread); -out: +out_free_both: free(fsdata.fatbuf); +out_free_itr: free(itr); return ret; } @@ -1148,17 +1157,18 @@ int fat_opendir(const char *filename, struct fs_dir_stream **dirsp) ret = fat_itr_root(&dir->itr, &dir->fsdata); if (ret) - goto fail; + goto fail_free_dir; ret = fat_itr_resolve(&dir->itr, filename, TYPE_DIR); if (ret) - goto fail; + goto fail_free_both; *dirsp = (struct fs_dir_stream *)dir; return 0; -fail: +fail_free_both: free(dir->fsdata.fatbuf); +fail_free_dir: free(dir); return ret; } |