sqfs_resolve_symlink() can return NULL, on its symlink_size overflow guard or on an allocation failure. sqfs_read_nest() and sqfs_size_nest() use the result without checking it, unlike sqfs_search_dir(), and the NULL reaches sqfs_split_path() which dereferences path[0]. A crafted or corrupted image can thus crash U-Boot (a NULL read) while reading or sizing a file through a symlink.
Check the result in both callers and guard sqfs_split_path() against a NULL path. Found by fuzzing the SquashFS parser. Signed-off-by: Oscar Deschamps <[email protected]> --- fs/squashfs/sqfs.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 0ea6dcaba1a..28d6e64e79c 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -1295,6 +1295,10 @@ static int sqfs_split_path(char **file, char **dir, const char *path) *file = NULL; *dir = NULL; + + if (!path) + return -EINVAL; + dirc = NULL; basec = NULL; bname = NULL; @@ -1561,6 +1565,10 @@ static int sqfs_read_nest(const char *filename, void *buf, loff_t offset, dirs->entry = NULL; sqfs_closedir(dirsp); dirsp = NULL; + if (!resolved) { + ret = -EINVAL; + goto out; + } ret = sqfs_read_nest(resolved, buf, offset, len, actread); free(resolved); goto out; @@ -1848,6 +1856,10 @@ static int sqfs_size_nest(const char *filename, loff_t *size) */ sqfs_closedir(dirsp); dirsp = NULL; + if (!resolved) { + ret = -EINVAL; + break; + } ret = sqfs_size(resolved, size); free(resolved); break; -- 2.43.0
