From 94aa8d8e1352ddf29c823845609e494668e1f6ff Mon Sep 17 00:00:00 2001 From: Saul Wold Date: Thu, 14 Nov 2013 09:43:53 -0800 Subject: squashfs-tools: remove FILESEXTRAPATH and move patches directory (From OE-Core rev: 60375dd8d0a849a7a23badb0f195a662c93a4922) Signed-off-by: Saul Wold Signed-off-by: Richard Purdie --- .../squashfs-4.2-fix-CVE-2012-4025.patch | 190 +++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 meta/recipes-devtools/squashfs-tools/squashfs-tools/squashfs-4.2-fix-CVE-2012-4025.patch (limited to 'meta/recipes-devtools/squashfs-tools/squashfs-tools/squashfs-4.2-fix-CVE-2012-4025.patch') diff --git a/meta/recipes-devtools/squashfs-tools/squashfs-tools/squashfs-4.2-fix-CVE-2012-4025.patch b/meta/recipes-devtools/squashfs-tools/squashfs-tools/squashfs-4.2-fix-CVE-2012-4025.patch new file mode 100644 index 0000000000..0dabfba663 --- /dev/null +++ b/meta/recipes-devtools/squashfs-tools/squashfs-tools/squashfs-4.2-fix-CVE-2012-4025.patch @@ -0,0 +1,190 @@ +Upstream-Status: Backport + +Reference: http://squashfs.git.sourceforge.net/git/gitweb.cgi? +p=squashfs/squashfs;a=patch;h=8515b3d420f502c5c0236b86e2d6d7e3b23c190e + +Integer overflow in the queue_init function in unsquashfs.c in +unsquashfs in Squashfs 4.2 and earlier allows remote attackers +to execute arbitrary code via a crafted block_log field in the +superblock of a .sqsh file, leading to a heap-based buffer overflow. + +http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-4025 + +Signed-off-by: yanjun.zhu + +--- a/unsquashfs.c 2012-11-30 17:57:57.000000000 +0800 ++++ b/unsquashfs.c 2012-11-30 17:58:09.000000000 +0800 +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + struct cache *fragment_cache, *data_cache; + struct queue *to_reader, *to_deflate, *to_writer, *from_writer; +@@ -138,6 +139,24 @@ void sigalrm_handler() + } + + ++int add_overflow(int a, int b) ++{ ++ return (INT_MAX - a) < b; ++} ++ ++ ++int shift_overflow(int a, int shift) ++{ ++ return (INT_MAX >> shift) < a; ++} ++ ++ ++int multiply_overflow(int a, int multiplier) ++{ ++ return (INT_MAX / multiplier) < a; ++} ++ ++ + struct queue *queue_init(int size) + { + struct queue *queue = malloc(sizeof(struct queue)); +@@ -145,6 +164,10 @@ struct queue *queue_init(int size) + if(queue == NULL) + EXIT_UNSQUASH("Out of memory in queue_init\n"); + ++ if(add_overflow(size, 1) || ++ multiply_overflow(size + 1, sizeof(void *))) ++ EXIT_UNSQUASH("Size too large in queue_init\n"); ++ + queue->data = malloc(sizeof(void *) * (size + 1)); + if(queue->data == NULL) + EXIT_UNSQUASH("Out of memory in queue_init\n"); +@@ -1948,13 +1971,30 @@ void initialise_threads(int fragment_buf + * allocate to_reader, to_deflate and to_writer queues. Set based on + * open file limit and cache size, unless open file limit is unlimited, + * in which case set purely based on cache limits ++ * ++ * In doing so, check that the user supplied values do not overflow ++ * a signed int + */ + if (max_files != -1) { ++ if(add_overflow(data_buffer_size, max_files) || ++ add_overflow(data_buffer_size, max_files * 2)) ++ EXIT_UNSQUASH("Data queue size is too large\n"); ++ + to_reader = queue_init(max_files + data_buffer_size); + to_deflate = queue_init(max_files + data_buffer_size); + to_writer = queue_init(max_files * 2 + data_buffer_size); + } else { +- int all_buffers_size = fragment_buffer_size + data_buffer_size; ++ int all_buffers_size; ++ ++ if(add_overflow(fragment_buffer_size, data_buffer_size)) ++ EXIT_UNSQUASH("Data and fragment queues combined are" ++ " too large\n"); ++ ++ all_buffers_size = fragment_buffer_size + data_buffer_size; ++ ++ if(add_overflow(all_buffers_size, all_buffers_size)) ++ EXIT_UNSQUASH("Data and fragment queues combined are" ++ " too large\n"); + + to_reader = queue_init(all_buffers_size); + to_deflate = queue_init(all_buffers_size); +@@ -2059,6 +2099,32 @@ void progress_bar(long long current, lon + } + + ++int parse_number(char *arg, int *res) ++{ ++ char *b; ++ long number = strtol(arg, &b, 10); ++ ++ /* check for trailing junk after number */ ++ if(*b != '\0') ++ return 0; ++ ++ /* check for strtol underflow or overflow in conversion */ ++ if(number == LONG_MIN || number == LONG_MAX) ++ return 0; ++ ++ /* reject negative numbers as invalid */ ++ if(number < 0) ++ return 0; ++ ++ /* check if long result will overflow signed int */ ++ if(number > INT_MAX) ++ return 0; ++ ++ *res = number; ++ return 1; ++} ++ ++ + #define VERSION() \ + printf("unsquashfs version 4.2 (2011/02/28)\n");\ + printf("copyright (C) 2011 Phillip Lougher "\ +@@ -2140,8 +2206,8 @@ int main(int argc, char *argv[]) + } else if(strcmp(argv[i], "-data-queue") == 0 || + strcmp(argv[i], "-da") == 0) { + if((++i == argc) || +- (data_buffer_size = strtol(argv[i], &b, +- 10), *b != '\0')) { ++ !parse_number(argv[i], ++ &data_buffer_size)) { + ERROR("%s: -data-queue missing or invalid " + "queue size\n", argv[0]); + exit(1); +@@ -2154,8 +2220,8 @@ int main(int argc, char *argv[]) + } else if(strcmp(argv[i], "-frag-queue") == 0 || + strcmp(argv[i], "-fr") == 0) { + if((++i == argc) || +- (fragment_buffer_size = strtol(argv[i], +- &b, 10), *b != '\0')) { ++ !parse_number(argv[i], ++ &fragment_buffer_size)) { + ERROR("%s: -frag-queue missing or invalid " + "queue size\n", argv[0]); + exit(1); +@@ -2280,11 +2346,39 @@ options: + block_log = sBlk.s.block_log; + + /* ++ * Sanity check block size and block log. ++ * ++ * Check they're within correct limits ++ */ ++ if(block_size > SQUASHFS_FILE_MAX_SIZE || ++ block_log > SQUASHFS_FILE_MAX_LOG) ++ EXIT_UNSQUASH("Block size or block_log too large." ++ " File system is corrupt.\n"); ++ ++ /* ++ * Check block_size and block_log match ++ */ ++ if(block_size != (1 << block_log)) ++ EXIT_UNSQUASH("Block size and block_log do not match." ++ " File system is corrupt.\n"); ++ ++ /* + * convert from queue size in Mbytes to queue size in +- * blocks ++ * blocks. ++ * ++ * In doing so, check that the user supplied values do not ++ * overflow a signed int + */ +- fragment_buffer_size <<= 20 - block_log; +- data_buffer_size <<= 20 - block_log; ++ if(shift_overflow(fragment_buffer_size, 20 - block_log)) ++ EXIT_UNSQUASH("Fragment queue size is too large\n"); ++ else ++ fragment_buffer_size <<= 20 - block_log; ++ ++ if(shift_overflow(data_buffer_size, 20 - block_log)) ++ EXIT_UNSQUASH("Data queue size is too large\n"); ++ else ++ data_buffer_size <<= 20 - block_log; ++ + initialise_threads(fragment_buffer_size, data_buffer_size); + + fragment_data = malloc(block_size); -- cgit v1.2.3-54-g00ecf