diff options
-rw-r--r-- | user/squashfs-tools/0001-mksquashfs-fix-rare-race-in-fragment-waiting-in-file.patch | 60 | ||||
-rw-r--r-- | user/squashfs-tools/APKBUILD | 35 | ||||
-rw-r--r-- | user/squashfs-tools/CVE-2015-4645.patch | 29 | ||||
-rw-r--r-- | user/squashfs-tools/fix-compat.patch | 46 | ||||
-rw-r--r-- | user/squashfs-tools/vla-overlow.patch | 21 |
5 files changed, 191 insertions, 0 deletions
diff --git a/user/squashfs-tools/0001-mksquashfs-fix-rare-race-in-fragment-waiting-in-file.patch b/user/squashfs-tools/0001-mksquashfs-fix-rare-race-in-fragment-waiting-in-file.patch new file mode 100644 index 000000000..51f588818 --- /dev/null +++ b/user/squashfs-tools/0001-mksquashfs-fix-rare-race-in-fragment-waiting-in-file.patch @@ -0,0 +1,60 @@ +From de03266983ceb62e5365aac84fcd3b2fd4d16e6f Mon Sep 17 00:00:00 2001 +From: Phillip Lougher <phillip@squashfs.org.uk> +Date: Thu, 18 Sep 2014 01:28:11 +0100 +Subject: [PATCH] mksquashfs: fix rare race in fragment waiting in filesystem + finalisation + +Fix a rare race condition in fragment waiting when finalising the +filesystem. This is a race condition that was initially fixed in 2009, +but inadvertantly re-introduced in the latest release when the code +was rewritten. + +Background: + +When finalising the filesystem, the main control thread needs to ensure +all the in-flight fragments have been queued to the writer thread before +asking the writer thread to finish, and then writing the metadata. + +It does this by waiting on the fragments_outstanding counter. Once this +counter reaches 0, it synchronises with the writer thread, waiting until +the writer thread reports no outstanding data to be written. + +However, the main thread can race with the fragment deflator thread(s) +because the fragment deflator thread(s) decrement the fragments_outstanding +counter and release the mutex before queueing the compressed fragment +to the writer thread, i.e. the offending code is: + + fragments_outstanding --; + pthread_mutex_unlock(&fragment_mutex); + queue_put(to_writer, write_buffer); + +In extremely rare circumstances, the main thread may see the +fragments_outstanding counter is zero before the fragment +deflator sends the fragment buffer to the writer thread, and synchronise +with the writer thread, and finalise before the fragment has been written. + +The fix is to ensure the fragment is queued to the writer thread +before releasing the mutex. + +Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk> +--- + squashfs-tools/mksquashfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c +index 87b7d86..f1fcff1 100644 +--- a/squashfs-tools/mksquashfs.c ++++ b/squashfs-tools/mksquashfs.c +@@ -2419,8 +2419,8 @@ void *frag_deflator(void *arg) + write_buffer->block = bytes; + bytes += compressed_size; + fragments_outstanding --; +- pthread_mutex_unlock(&fragment_mutex); + queue_put(to_writer, write_buffer); ++ pthread_mutex_unlock(&fragment_mutex); + TRACE("Writing fragment %lld, uncompressed size %d, " + "compressed size %d\n", file_buffer->block, + file_buffer->size, compressed_size); +-- +2.10.2 + diff --git a/user/squashfs-tools/APKBUILD b/user/squashfs-tools/APKBUILD new file mode 100644 index 000000000..227faf11d --- /dev/null +++ b/user/squashfs-tools/APKBUILD @@ -0,0 +1,35 @@ +# Maintainer: A. Wilcox <awilfox@adelielinux.org> +pkgname=squashfs-tools +pkgver=4.3 +pkgrel=5 +pkgdesc="Tools for SquashFS, a highly compressed read-only filesystem" +url="http://squashfs.sourceforge.net" +arch="all" +options="!check" # No test suite. +license="GPL-2.0+" +depends= +makedepends="zlib-dev xz-dev lzo-dev lz4-dev attr-dev" +source="http://downloads.sourceforge.net/sourceforge/squashfs/squashfs$pkgver.tar.gz + fix-compat.patch + vla-overlow.patch + CVE-2015-4645.patch + 0001-mksquashfs-fix-rare-race-in-fragment-waiting-in-file.patch +" +builddir="$srcdir/squashfs$pkgver" + +build() { + cd "$builddir"/$pkgname + make XZ_SUPPORT=1 LZO_SUPPORT=1 LZ4_SUPPORT=1 +} + +package() { + cd "$builddir"/$pkgname + mkdir -p "$pkgdir"/sbin + cp -a mksquashfs unsquashfs "$pkgdir"/sbin +} + +sha512sums="854ed7acc99920f24ecf11e0da807e5a2a162eeda55db971aba63a03f0da2c13b20ec0564a906c4b0e415bd8258b273a10208c7abc0704f2ceea773aa6148a79 squashfs4.3.tar.gz +868e3923f98a7f8bb980fe8ab0d648e9ae9a55e324bea3830d6047aa348a4302dcb96d65bf59c6e04665891d822e18fad367a37c6704505b8492f64d749fc140 fix-compat.patch +975d09d047f4122866e83c4322ce3a15795c051b850d14a85a615c3beef970378e5a620ee16058b9c5104c53f973f9b3804d96c3ba1ab4f622f1e096c04e0360 vla-overlow.patch +77431a0a4a529ce63f1613a65a23af2fb8683a16d14ad1a5cfed3a9fac4df6a1212f081d1879ede188a25b77e860445058012131423c546657fb562069865d2c CVE-2015-4645.patch +1b2338a448ec8a2b75880ddc8c13f99392451847ab26277e1bc82b49a3a804796934e212dd1ba54a502940537a61891ee0103e913d0bda65cff0ca2827b8b41c 0001-mksquashfs-fix-rare-race-in-fragment-waiting-in-file.patch" diff --git a/user/squashfs-tools/CVE-2015-4645.patch b/user/squashfs-tools/CVE-2015-4645.patch new file mode 100644 index 000000000..f69025f18 --- /dev/null +++ b/user/squashfs-tools/CVE-2015-4645.patch @@ -0,0 +1,29 @@ +diff --git a/squashfs-tools/unsquash-4.c b/squashfs-tools/unsquash-4.c +index ecdaac796f09..2c0cf63daf67 100644 +--- a/squashfs-tools/unsquash-4.c ++++ b/squashfs-tools/unsquash-4.c +@@ -31,9 +31,9 @@ static unsigned int *id_table; + int read_fragment_table_4(long long *directory_table_end) + { + int res, i; +- int bytes = SQUASHFS_FRAGMENT_BYTES(sBlk.s.fragments); +- int indexes = SQUASHFS_FRAGMENT_INDEXES(sBlk.s.fragments); +- long long fragment_table_index[indexes]; ++ size_t bytes = SQUASHFS_FRAGMENT_BYTES(sBlk.s.fragments); ++ size_t indexes = SQUASHFS_FRAGMENT_INDEXES(sBlk.s.fragments); ++ long long *fragment_table_index; + + TRACE("read_fragment_table: %d fragments, reading %d fragment indexes " + "from 0x%llx\n", sBlk.s.fragments, indexes, +@@ -44,6 +44,11 @@ int read_fragment_table_4(long long *directory_table_end) + return TRUE; + } + ++ fragment_table_index = malloc(indexes*sizeof(long long)); ++ if(fragment_table_index == NULL) ++ EXIT_UNSQUASH("read_fragment_table: failed to allocate " ++ "fragment table index\n"); ++ + fragment_table = malloc(bytes); + if(fragment_table == NULL) + EXIT_UNSQUASH("read_fragment_table: failed to allocate " diff --git a/user/squashfs-tools/fix-compat.patch b/user/squashfs-tools/fix-compat.patch new file mode 100644 index 000000000..2a3b33ca9 --- /dev/null +++ b/user/squashfs-tools/fix-compat.patch @@ -0,0 +1,46 @@ +--- squashfs4.3.orig/squashfs-tools/action.c ++++ squashfs4.3/squashfs-tools/action.c +@@ -1905,6 +1905,9 @@ + return 1; + } + ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 ++#endif + + TEST_FN(name, ACTION_ALL_LNK, \ + return fnmatch(atom->argv[0], action_data->name, +--- squashfs4.3.orig/squashfs-tools/mksquashfs.c ++++ squashfs4.3/squashfs-tools/mksquashfs.c +@@ -4391,6 +4391,9 @@ + return paths; + } + ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 ++#endif + + int excluded_match(char *name, struct pathname *path, struct pathnames **new) + { +--- squashfs4.3.orig/squashfs-tools/pseudo.c ++++ squashfs4.3/squashfs-tools/pseudo.c +@@ -32,6 +32,7 @@ + #include <stdlib.h> + #include <sys/types.h> + #include <sys/wait.h> ++#include <sys/stat.h> + #include <ctype.h> + + #include "pseudo.h" +--- squashfs4.3.orig/squashfs-tools/unsquashfs.c ++++ squashfs4.3/squashfs-tools/unsquashfs.c +@@ -1410,6 +1410,9 @@ + free(paths); + } + ++#ifndef FNM_EXTMATCH ++#define FNM_EXTMATCH 0 ++#endif + + int matches(struct pathnames *paths, char *name, struct pathnames **new) + { diff --git a/user/squashfs-tools/vla-overlow.patch b/user/squashfs-tools/vla-overlow.patch new file mode 100644 index 000000000..a9840fe01 --- /dev/null +++ b/user/squashfs-tools/vla-overlow.patch @@ -0,0 +1,21 @@ +--- ./squashfs-tools/unsquashfs.c.orig ++++ ./squashfs-tools/unsquashfs.c +@@ -2099,7 +2099,9 @@ + */ + void *inflator(void *arg) + { +- char tmp[block_size]; ++ char *tmp = malloc(block_size); ++ if(tmp == NULL) ++ EXIT_UNSQUASH("Out of memory allocating block buffer\n"); + + while(1) { + struct cache_entry *entry = queue_get(to_inflate); +@@ -2122,6 +2124,7 @@ + */ + cache_block_ready(entry, res == -1); + } ++ free(tmp); + } + + |