Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-10-15 18:00:38 +0200
committerTakashi Iwai <tiwai@suse.de>2018-10-15 18:00:38 +0200
commit6ea48dd32f1d9c8cc9a06bf2b3fcb11d29cbedac (patch)
treea874b9ab644c1558aedadddf0daf9584bf39d090
parent680b1506f519bfa6c8afec929d0ca37ad5cc85c9 (diff)
squashfs: more metadata hardening (bsc#1051510).
-rw-r--r--patches.fixes/squashfs-more-metadata-hardening2.patch102
-rw-r--r--series.conf1
2 files changed, 103 insertions, 0 deletions
diff --git a/patches.fixes/squashfs-more-metadata-hardening2.patch b/patches.fixes/squashfs-more-metadata-hardening2.patch
new file mode 100644
index 0000000000..7e02521cb4
--- /dev/null
+++ b/patches.fixes/squashfs-more-metadata-hardening2.patch
@@ -0,0 +1,102 @@
+From 71755ee5350b63fb1f283de8561cdb61b47f4d1d Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Thu, 2 Aug 2018 08:43:35 -0700
+Subject: [PATCH] squashfs: more metadata hardening
+Mime-version: 1.0
+Content-type: text/plain; charset=UTF-8
+Content-transfer-encoding: 8bit
+Git-commit: 71755ee5350b63fb1f283de8561cdb61b47f4d1d
+Patch-mainline: v4.18-rc8
+References: bsc#1051510
+
+The squashfs fragment reading code doesn't actually verify that the
+fragment is inside the fragment table. The end result _is_ verified to
+be inside the image when actually reading the fragment data, but before
+that is done, we may end up taking a page fault because the fragment
+table itself might not even exist.
+
+Another report from Anatoly and his endless squashfs image fuzzing.
+
+Reported-by: Анатолий Тросиненко <anatoly.trosinenko@gmail.com>
+Acked-by:: Phillip Lougher <phillip.lougher@gmail.com>,
+
+Cc: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ fs/squashfs/fragment.c | 13 +++++++++----
+ fs/squashfs/squashfs_fs_sb.h | 1 +
+ fs/squashfs/super.c | 5 +++--
+ 3 files changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
+index 86ad9a4b8c36..0681feab4a84 100644
+--- a/fs/squashfs/fragment.c
++++ b/fs/squashfs/fragment.c
+@@ -49,11 +49,16 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
+ u64 *fragment_block)
+ {
+ struct squashfs_sb_info *msblk = sb->s_fs_info;
+- int block = SQUASHFS_FRAGMENT_INDEX(fragment);
+- int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
+- u64 start_block = le64_to_cpu(msblk->fragment_index[block]);
++ int block, offset, size;
+ struct squashfs_fragment_entry fragment_entry;
+- int size;
++ u64 start_block;
++
++ if (fragment >= msblk->fragments)
++ return -EIO;
++ block = SQUASHFS_FRAGMENT_INDEX(fragment);
++ offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
++
++ start_block = le64_to_cpu(msblk->fragment_index[block]);
+
+ size = squashfs_read_metadata(sb, &fragment_entry, &start_block,
+ &offset, sizeof(fragment_entry));
+diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
+index 1da565cb50c3..ef69c31947bf 100644
+--- a/fs/squashfs/squashfs_fs_sb.h
++++ b/fs/squashfs/squashfs_fs_sb.h
+@@ -75,6 +75,7 @@ struct squashfs_sb_info {
+ unsigned short block_log;
+ long long bytes_used;
+ unsigned int inodes;
++ unsigned int fragments;
+ int xattr_ids;
+ };
+ #endif
+diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
+index 8a73b97217c8..40e657386fa5 100644
+--- a/fs/squashfs/super.c
++++ b/fs/squashfs/super.c
+@@ -175,6 +175,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
+ msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
+ msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
+ msblk->inodes = le32_to_cpu(sblk->inodes);
++ msblk->fragments = le32_to_cpu(sblk->fragments);
+ flags = le16_to_cpu(sblk->flags);
+
+ TRACE("Found valid superblock on %pg\n", sb->s_bdev);
+@@ -185,7 +186,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
+ TRACE("Filesystem size %lld bytes\n", msblk->bytes_used);
+ TRACE("Block size %d\n", msblk->block_size);
+ TRACE("Number of inodes %d\n", msblk->inodes);
+- TRACE("Number of fragments %d\n", le32_to_cpu(sblk->fragments));
++ TRACE("Number of fragments %d\n", msblk->fragments);
+ TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids));
+ TRACE("sblk->inode_table_start %llx\n", msblk->inode_table);
+ TRACE("sblk->directory_table_start %llx\n", msblk->directory_table);
+@@ -272,7 +273,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
+ sb->s_export_op = &squashfs_export_ops;
+
+ handle_fragments:
+- fragments = le32_to_cpu(sblk->fragments);
++ fragments = msblk->fragments;
+ if (fragments == 0)
+ goto check_directory_table;
+
+--
+2.19.0
+
diff --git a/series.conf b/series.conf
index a05c3e4d14..cdda7a6ab8 100644
--- a/series.conf
+++ b/series.conf
@@ -17006,6 +17006,7 @@
patches.suse/cpufreq-intel_pstate-Limit-the-scope-of-HWP-dynamic-.patch
patches.fixes/tools-power-turbostat-fix-S-on-UP-systems.patch
patches.fixes/tools-power-turbostat-Read-extended-processor-family.patch
+ patches.fixes/squashfs-more-metadata-hardening2.patch
patches.fixes/Squashfs-Compute-expected-length-from-inode-size-rat.patch
patches.drivers/iwlwifi-add-more-card-IDs-for-9000-series
patches.fixes/inet-frag-enforce-memory-limits-earlier.patch