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

Reply via email to