mirror of
https://github.com/linux-sunxi/u-boot-sunxi.git
synced 2024-02-12 11:16:03 +08:00
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: 2460098cff
("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>
This commit is contained in:

committed by
Tom Rini

parent
09fa964bba
commit
af609e3764
30
fs/fat/fat.c
30
fs/fat/fat.c
@ -1039,12 +1039,15 @@ int fat_exists(const char *filename)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
itr = malloc_cache_aligned(sizeof(fat_itr));
|
itr = malloc_cache_aligned(sizeof(fat_itr));
|
||||||
|
if (!itr)
|
||||||
|
return 0;
|
||||||
ret = fat_itr_root(itr, &fsdata);
|
ret = fat_itr_root(itr, &fsdata);
|
||||||
if (ret)
|
if (ret)
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
ret = fat_itr_resolve(itr, filename, TYPE_ANY);
|
ret = fat_itr_resolve(itr, filename, TYPE_ANY);
|
||||||
free(fsdata.fatbuf);
|
free(fsdata.fatbuf);
|
||||||
|
out:
|
||||||
free(itr);
|
free(itr);
|
||||||
return ret == 0;
|
return ret == 0;
|
||||||
}
|
}
|
||||||
@ -1056,9 +1059,11 @@ int fat_size(const char *filename, loff_t *size)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
itr = malloc_cache_aligned(sizeof(fat_itr));
|
itr = malloc_cache_aligned(sizeof(fat_itr));
|
||||||
|
if (!itr)
|
||||||
|
return -ENOMEM;
|
||||||
ret = fat_itr_root(itr, &fsdata);
|
ret = fat_itr_root(itr, &fsdata);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out_free_itr;
|
||||||
|
|
||||||
ret = fat_itr_resolve(itr, filename, TYPE_FILE);
|
ret = fat_itr_resolve(itr, filename, TYPE_FILE);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -1072,12 +1077,13 @@ int fat_size(const char *filename, loff_t *size)
|
|||||||
*size = 0;
|
*size = 0;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
goto out;
|
goto out_free_both;
|
||||||
}
|
}
|
||||||
|
|
||||||
*size = FAT2CPU32(itr->dent->size);
|
*size = FAT2CPU32(itr->dent->size);
|
||||||
|
out_free_both:
|
||||||
free(fsdata.fatbuf);
|
free(fsdata.fatbuf);
|
||||||
out:
|
out_free_itr:
|
||||||
free(itr);
|
free(itr);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1090,19 +1096,22 @@ int file_fat_read_at(const char *filename, loff_t pos, void *buffer,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
itr = malloc_cache_aligned(sizeof(fat_itr));
|
itr = malloc_cache_aligned(sizeof(fat_itr));
|
||||||
|
if (!itr)
|
||||||
|
return -ENOMEM;
|
||||||
ret = fat_itr_root(itr, &fsdata);
|
ret = fat_itr_root(itr, &fsdata);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
goto out_free_itr;
|
||||||
|
|
||||||
ret = fat_itr_resolve(itr, filename, TYPE_FILE);
|
ret = fat_itr_resolve(itr, filename, TYPE_FILE);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out_free_both;
|
||||||
|
|
||||||
printf("reading %s\n", filename);
|
printf("reading %s\n", filename);
|
||||||
ret = get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread);
|
ret = get_contents(&fsdata, itr->dent, pos, buffer, maxsize, actread);
|
||||||
|
|
||||||
out:
|
out_free_both:
|
||||||
free(fsdata.fatbuf);
|
free(fsdata.fatbuf);
|
||||||
|
out_free_itr:
|
||||||
free(itr);
|
free(itr);
|
||||||
return ret;
|
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);
|
ret = fat_itr_root(&dir->itr, &dir->fsdata);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail_free_dir;
|
||||||
|
|
||||||
ret = fat_itr_resolve(&dir->itr, filename, TYPE_DIR);
|
ret = fat_itr_resolve(&dir->itr, filename, TYPE_DIR);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto fail;
|
goto fail_free_both;
|
||||||
|
|
||||||
*dirsp = (struct fs_dir_stream *)dir;
|
*dirsp = (struct fs_dir_stream *)dir;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail_free_both:
|
||||||
free(dir->fsdata.fatbuf);
|
free(dir->fsdata.fatbuf);
|
||||||
|
fail_free_dir:
|
||||||
free(dir);
|
free(dir);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user