[PATCH] Squashfs: check xz dictionary size isn't zero

Phillip Lougher posted 1 patch 1 month, 2 weeks ago
fs/squashfs/xz_wrapper.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
[PATCH] Squashfs: check xz dictionary size isn't zero
Posted by Phillip Lougher 1 month, 2 weeks ago
Syzkaller reports a "UBSAN: shift-out-of-bounds in squashfs_xz_comp_opts"

This is caused by a zero dict_size value read from disk, which produces a
negative shift.

The fix is to check that the dict_size is not zero.

Fixes: ff750311d30a ("Squashfs: add compression options support to xz decompressor")
Reported-by: syzbot+99fc070a2affcd27784b@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6994c60f.a70a0220.2c38d7.0108.GAE@google.com/

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
---
 fs/squashfs/xz_wrapper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c
index 6c49481a2f8c..71eeec9970ec 100644
--- a/fs/squashfs/xz_wrapper.c
+++ b/fs/squashfs/xz_wrapper.c
@@ -58,9 +58,9 @@ static void *squashfs_xz_comp_opts(struct squashfs_sb_info *msblk,
 		opts->dict_size = le32_to_cpu(comp_opts->dictionary_size);
 
 		/* the dictionary size should be 2^n or 2^n+2^(n+1) */
-		n = ffs(opts->dict_size) - 1;
-		if (opts->dict_size != (1 << n) && opts->dict_size != (1 << n) +
-						(1 << (n + 1))) {
+		n = ffs(opts->dict_size);
+		if (n-- == 0 || (opts->dict_size != (1 << n) &&
+				opts->dict_size != (1 << n) + (1 << (n + 1)))) {
 			err = -EIO;
 			goto out;
 		}
-- 
2.47.3