From patchwork Fri Mar 4 15:04:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 4675 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00F7CC433F5 for ; Fri, 4 Mar 2022 15:04:49 +0000 (UTC) Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) by mx.groups.io with SMTP id smtpd.web11.7937.1646406288118967185 for ; Fri, 04 Mar 2022 07:04:48 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@sakoman-com.20210112.gappssmtp.com header.s=20210112 header.b=iLWA0ca5; spf=softfail (domain: sakoman.com, ip: 209.85.210.172, mailfrom: steve@sakoman.com) Received: by mail-pf1-f172.google.com with SMTP id d17so7876990pfl.0 for ; Fri, 04 Mar 2022 07:04:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20210112.gappssmtp.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=c8vDgkDH0OXWjJUOi1/N38mARoS3q5mlQ1Wi5xQwV2c=; b=iLWA0ca5Ji70Va6AJrLHsndtY5QP5Jy8yRzlgroL1W3b4CxW+UL7CjTRRyWC7AcoF4 r19Nc6P9m+mfiwCpJTb+0zcT6UtC2mQjGvlOg7AMvbxuf50mrdim0HxIIf4pPgGCtbiX SYQHO6LDO/EZUuPXKMUmP1N00WwDUBwGcp4qMkWAixFZr6owo1Xz2w7xX4fgPiLd9Rlb Q3YM+dLnIwhsOE9GTO+XSE9FBz3vpx/oFJw00m6/dinfJXRn2I6zeif2cFrbfC9GL8Ef zCezE37YaudEEwJWj53QMUoqwOtQrWLdHInLEf5MHG5jEEtPPbl7vcTZi6l5oabpidf8 bGrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=c8vDgkDH0OXWjJUOi1/N38mARoS3q5mlQ1Wi5xQwV2c=; b=FdGEWZahzdOplAyLcUZbTACiuEd7RalDTJ4Pf7i39mM79lGmQBxG3zbGdisZdUnZJ5 dkRA0O68xnZe3RuGem7SKWGa+2vJwP8tVKsSvCenu1J5koLOGsXkoUjGanqpRU6bYus+ ibpDR/60bryntsFHjgQtC2swbev/vxsYl8oaQSq2qse9SDgOjtgQd5tUAtVpXHPbmgfC yEXD3TevC6daNT3RugFyvNpwp4bOTbq8Go4iXQMHLUuNxWNLyO5KMwosE650GPVjclaN 7q/aUVjEgddHS3HgFO7Dwl4w677D6xQLmECRnE/tPliLNvtXDVnUAMhb8B43w5mxFWB5 hpLg== X-Gm-Message-State: AOAM533bi4p/ecMjqH/bzCVA9nBZve30Bmk2lQsnHxeGCLS1dnDhtCn6 AqaOMpiEDYLtv9jFY+f4e4qHds5HxCDW6MVDXpo= X-Google-Smtp-Source: ABdhPJz5m57SuCCXfM0sKoAw3Gwvts1qq5k0fVAmBez1yhNMWaKXtfAEVjsjjuFLUmXlaRUh29yhtw== X-Received: by 2002:a63:6c8a:0:b0:37c:62da:a647 with SMTP id h132-20020a636c8a000000b0037c62daa647mr5544832pgc.423.1646406286299; Fri, 04 Mar 2022 07:04:46 -0800 (PST) Received: from hexa.router0800d9.com (dhcp-72-253-6-214.hawaiiantel.net. [72.253.6.214]) by smtp.gmail.com with ESMTPSA id f194-20020a6238cb000000b004f6ce898c61sm80400pfa.77.2022.03.04.07.04.44 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Mar 2022 07:04:45 -0800 (PST) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][dunfell 01/18] libarchive: Fix for CVE-2021-36976 Date: Fri, 4 Mar 2022 05:04:09 -1000 Message-Id: <6c356aec8dabc08bd98da3106780896dc7b52501.1646406001.git.steve@sakoman.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 04 Mar 2022 15:04:48 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/162720 From: Virendra Thakur Add patch to fix CVE-2021-36976 CVE-2021-36976 fix are provided by below mentioned pull request. 1) https://github.com/libarchive/libarchive/pull/1491 2) https://github.com/libarchive/libarchive/pull/1492 3) https://github.com/libarchive/libarchive/pull/1493 Signed-off-by: Virendra Thakur Signed-off-by: virendra thakur Signed-off-by: Steve Sakoman --- .../libarchive/CVE-2021-36976-1.patch | 321 ++++++++++++++++++ .../libarchive/CVE-2021-36976-2.patch | 121 +++++++ .../libarchive/CVE-2021-36976-3.patch | 93 +++++ .../libarchive/libarchive_3.4.2.bb | 6 +- 4 files changed, 540 insertions(+), 1 deletion(-) create mode 100644 meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch create mode 100644 meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch create mode 100644 meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch new file mode 100644 index 0000000000..fca53fc9b6 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-1.patch @@ -0,0 +1,321 @@ +From 05ebb55896d10a9737dad9ae0303f7f45489ba6f Mon Sep 17 00:00:00 2001 +From: Grzegorz Antoniak +Date: Sat, 13 Feb 2021 09:08:13 +0100 +Subject: [PATCH] RAR5 reader: fixed out of bounds read in some files + +Added more range checks in the bit stream reading functions +(read_bits_16 and read_bits_32) in order to better guard against out of +memory reads. + +This commit contains a test with OSSFuzz sample #30448. + +Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-1.patch?h=applied/3.4.3-2ubuntu0.1] +CVE: CVE-2021-36976 +Signed-off-by: Virendra Thakur +--- + Makefile.am | 1 + + libarchive/archive_read_support_format_rar5.c | 108 ++++++++++-------- + libarchive/test/test_read_format_rar5.c | 16 +++ + ...r5_decode_number_out_of_bounds_read.rar.uu | 10 ++ + 4 files changed, 89 insertions(+), 46 deletions(-) + create mode 100644 libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu + +--- a/Makefile.am ++++ b/Makefile.am +@@ -883,6 +883,7 @@ libarchive_test_EXTRA_DIST=\ + libarchive/test/test_read_format_rar5_arm_filter_on_window_boundary.rar.uu \ + libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ + libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ ++ libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ + libarchive/test/test_read_format_raw.bufr.uu \ + libarchive/test/test_read_format_raw.data.gz.uu \ + libarchive/test/test_read_format_raw.data.Z.uu \ +--- a/libarchive/archive_read_support_format_rar5.c ++++ b/libarchive/archive_read_support_format_rar5.c +@@ -1012,7 +1012,16 @@ static int read_var_sized(struct archive + return ret; + } + +-static int read_bits_32(struct rar5* rar, const uint8_t* p, uint32_t* value) { ++static int read_bits_32(struct archive_read* a, struct rar5* rar, ++ const uint8_t* p, uint32_t* value) ++{ ++ if(rar->bits.in_addr >= rar->cstate.cur_block_size) { ++ archive_set_error(&a->archive, ++ ARCHIVE_ERRNO_PROGRAMMER, ++ "Premature end of stream during extraction of data (#1)"); ++ return ARCHIVE_FATAL; ++ } ++ + uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24; + bits |= p[rar->bits.in_addr + 1] << 16; + bits |= p[rar->bits.in_addr + 2] << 8; +@@ -1023,7 +1032,16 @@ static int read_bits_32(struct rar5* rar + return ARCHIVE_OK; + } + +-static int read_bits_16(struct rar5* rar, const uint8_t* p, uint16_t* value) { ++static int read_bits_16(struct archive_read* a, struct rar5* rar, ++ const uint8_t* p, uint16_t* value) ++{ ++ if(rar->bits.in_addr >= rar->cstate.cur_block_size) { ++ archive_set_error(&a->archive, ++ ARCHIVE_ERRNO_PROGRAMMER, ++ "Premature end of stream during extraction of data (#2)"); ++ return ARCHIVE_FATAL; ++ } ++ + int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16; + bits |= (int) p[rar->bits.in_addr + 1] << 8; + bits |= (int) p[rar->bits.in_addr + 2]; +@@ -1039,8 +1057,8 @@ static void skip_bits(struct rar5* rar, + } + + /* n = up to 16 */ +-static int read_consume_bits(struct rar5* rar, const uint8_t* p, int n, +- int* value) ++static int read_consume_bits(struct archive_read* a, struct rar5* rar, ++ const uint8_t* p, int n, int* value) + { + uint16_t v; + int ret, num; +@@ -1051,7 +1069,7 @@ static int read_consume_bits(struct rar5 + return ARCHIVE_FATAL; + } + +- ret = read_bits_16(rar, p, &v); ++ ret = read_bits_16(a, rar, p, &v); + if(ret != ARCHIVE_OK) + return ret; + +@@ -2425,13 +2443,13 @@ static int create_decode_tables(uint8_t* + static int decode_number(struct archive_read* a, struct decode_table* table, + const uint8_t* p, uint16_t* num) + { +- int i, bits, dist; ++ int i, bits, dist, ret; + uint16_t bitfield; + uint32_t pos; + struct rar5* rar = get_context(a); + +- if(ARCHIVE_OK != read_bits_16(rar, p, &bitfield)) { +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &bitfield))) { ++ return ret; + } + + bitfield &= 0xfffe; +@@ -2537,14 +2555,6 @@ static int parse_tables(struct archive_r + for(i = 0; i < HUFF_TABLE_SIZE;) { + uint16_t num; + +- if((rar->bits.in_addr + 6) >= rar->cstate.cur_block_size) { +- /* Truncated data, can't continue. */ +- archive_set_error(&a->archive, +- ARCHIVE_ERRNO_FILE_FORMAT, +- "Truncated data in huffman tables (#2)"); +- return ARCHIVE_FATAL; +- } +- + ret = decode_number(a, &rar->cstate.bd, p, &num); + if(ret != ARCHIVE_OK) { + archive_set_error(&a->archive, +@@ -2561,8 +2571,8 @@ static int parse_tables(struct archive_r + /* 16..17: repeat previous code */ + uint16_t n; + +- if(ARCHIVE_OK != read_bits_16(rar, p, &n)) +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) ++ return ret; + + if(num == 16) { + n >>= 13; +@@ -2590,8 +2600,8 @@ static int parse_tables(struct archive_r + /* other codes: fill with zeroes `n` times */ + uint16_t n; + +- if(ARCHIVE_OK != read_bits_16(rar, p, &n)) +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n))) ++ return ret; + + if(num == 18) { + n >>= 13; +@@ -2707,22 +2717,22 @@ static int parse_block_header(struct arc + } + + /* Convenience function used during filter processing. */ +-static int parse_filter_data(struct rar5* rar, const uint8_t* p, +- uint32_t* filter_data) ++static int parse_filter_data(struct archive_read* a, struct rar5* rar, ++ const uint8_t* p, uint32_t* filter_data) + { +- int i, bytes; ++ int i, bytes, ret; + uint32_t data = 0; + +- if(ARCHIVE_OK != read_consume_bits(rar, p, 2, &bytes)) +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, p, 2, &bytes))) ++ return ret; + + bytes++; + + for(i = 0; i < bytes; i++) { + uint16_t byte; + +- if(ARCHIVE_OK != read_bits_16(rar, p, &byte)) { +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &byte))) { ++ return ret; + } + + /* Cast to uint32_t will ensure the shift operation will not +@@ -2765,16 +2775,17 @@ static int parse_filter(struct archive_r + uint16_t filter_type; + struct filter_info* filt = NULL; + struct rar5* rar = get_context(ar); ++ int ret; + + /* Read the parameters from the input stream. */ +- if(ARCHIVE_OK != parse_filter_data(rar, p, &block_start)) +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_start))) ++ return ret; + +- if(ARCHIVE_OK != parse_filter_data(rar, p, &block_length)) +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_length))) ++ return ret; + +- if(ARCHIVE_OK != read_bits_16(rar, p, &filter_type)) +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = read_bits_16(ar, rar, p, &filter_type))) ++ return ret; + + filter_type >>= 13; + skip_bits(rar, 3); +@@ -2814,8 +2825,8 @@ static int parse_filter(struct archive_r + if(filter_type == FILTER_DELTA) { + int channels; + +- if(ARCHIVE_OK != read_consume_bits(rar, p, 5, &channels)) +- return ARCHIVE_EOF; ++ if(ARCHIVE_OK != (ret = read_consume_bits(ar, rar, p, 5, &channels))) ++ return ret; + + filt->channels = channels + 1; + } +@@ -2823,10 +2834,11 @@ static int parse_filter(struct archive_r + return ARCHIVE_OK; + } + +-static int decode_code_length(struct rar5* rar, const uint8_t* p, +- uint16_t code) ++static int decode_code_length(struct archive_read* a, struct rar5* rar, ++ const uint8_t* p, uint16_t code) + { + int lbits, length = 2; ++ + if(code < 8) { + lbits = 0; + length += code; +@@ -2838,7 +2850,7 @@ static int decode_code_length(struct rar + if(lbits > 0) { + int add; + +- if(ARCHIVE_OK != read_consume_bits(rar, p, lbits, &add)) ++ if(ARCHIVE_OK != read_consume_bits(a, rar, p, lbits, &add)) + return -1; + + length += add; +@@ -2933,7 +2945,7 @@ static int do_uncompress_block(struct ar + continue; + } else if(num >= 262) { + uint16_t dist_slot; +- int len = decode_code_length(rar, p, num - 262), ++ int len = decode_code_length(a, rar, p, num - 262), + dbits, + dist = 1; + +@@ -2975,12 +2987,12 @@ static int do_uncompress_block(struct ar + uint16_t low_dist; + + if(dbits > 4) { +- if(ARCHIVE_OK != read_bits_32( +- rar, p, &add)) { ++ if(ARCHIVE_OK != (ret = read_bits_32( ++ a, rar, p, &add))) { + /* Return EOF if we + * can't read more + * data. */ +- return ARCHIVE_EOF; ++ return ret; + } + + skip_bits(rar, dbits - 4); +@@ -3015,11 +3027,11 @@ static int do_uncompress_block(struct ar + /* dbits is one of [0,1,2,3] */ + int add; + +- if(ARCHIVE_OK != read_consume_bits(rar, +- p, dbits, &add)) { ++ if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, ++ p, dbits, &add))) { + /* Return EOF if we can't read + * more data. */ +- return ARCHIVE_EOF; ++ return ret; + } + + dist += add; +@@ -3076,7 +3088,11 @@ static int do_uncompress_block(struct ar + return ARCHIVE_FATAL; + } + +- len = decode_code_length(rar, p, len_slot); ++ len = decode_code_length(a, rar, p, len_slot); ++ if (len == -1) { ++ return ARCHIVE_FATAL; ++ } ++ + rar->cstate.last_len = len; + + if(ARCHIVE_OK != copy_string(a, len, dist)) +--- a/libarchive/test/test_read_format_rar5.c ++++ b/libarchive/test/test_read_format_rar5.c +@@ -1271,3 +1271,20 @@ DEFINE_TEST(test_read_format_rar5_block_ + + EPILOGUE(); + } ++ ++DEFINE_TEST(test_read_format_rar5_decode_number_out_of_bounds_read) ++{ ++ /* oss fuzz 30448 */ ++ ++ char buf[4096]; ++ PROLOGUE("test_read_format_rar5_decode_number_out_of_bounds_read.rar"); ++ ++ /* Return codes of those calls are ignored, because this sample file ++ * is invalid. However, the unpacker shouldn't produce any SIGSEGV ++ * errors during processing. */ ++ ++ (void) archive_read_next_header(a, &ae); ++ while(0 < archive_read_data(a, buf, sizeof(buf))) {} ++ ++ EPILOGUE(); ++} +--- /dev/null ++++ b/libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu +@@ -0,0 +1,10 @@ ++begin 644 test_read_format_rar5_decode_number_out_of_bounds_read.rar ++M4F%R(1H'`0!3@"KT`P+G(@(0("`@@`L!!"`@("`@(($D_[BJ2"!::7!)210V ++M+0#ZF#)Q!`+>YPW_("`@("``_R````````````````````````````!__P`` ++M``````!T72`@/EW_(/\@("`@("`@("`@("`@("`@("`@("`@("`@(/\@("`@ ++M("`@("#_("`@("`@("`@("`@("`@("`@("`@("`@("#_("`@("`@("`@_R`@ ++M("`@("`@("`@("`@("`@("`@("`@("`@_R`@("`@("`@(/\@("`@("`@("`@ ++M("`@("`@("`@("`@("`@(/\@("`@("`@("#_("`@("`@("`@("`@("`@("`@ ++E("`@("`@("#_("`@("`@("`@_R`@("`@("`@("`@("`@("`@(``` ++` ++end diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch new file mode 100644 index 0000000000..b5da44ec7b --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-2.patch @@ -0,0 +1,121 @@ +From 17f4e83c0f0fc3bacf4b2bbacb01f987bb5aff5f Mon Sep 17 00:00:00 2001 +From: Grzegorz Antoniak +Date: Fri, 12 Feb 2021 20:18:31 +0100 +Subject: [PATCH] RAR5 reader: fix invalid memory access in some files + +RAR5 reader uses several variables to manage the window buffer during +extraction: the buffer itself (`window_buf`), the current size of the +window buffer (`window_size`), and a helper variable (`window_mask`) +that is used to constrain read and write offsets to the window buffer. + +Some specially crafted files can force the unpacker to update the +`window_mask` variable to a value that is out of sync with current +buffer size. If the `window_mask` will be bigger than the actual buffer +size, then an invalid access operation can happen (SIGSEGV). + +This commit ensures that if the `window_size` and `window_mask` will be +changed, the window buffer will be reallocated to the proper size, so no +invalid memory operation should be possible. + +This commit contains a test file from OSSFuzz #30442. + +Upstream-Status: Backport [https://git.launchpad.net/ubuntu/+source/libarchive/plain/debian/patches/CVE-2021-36976-2.patch?h=applied/3.4.3-2ubuntu0.1] +CVE: CVE-2021-36976 +Signed-off-by: Virendra Thakur + +--- + Makefile.am | 1 + + libarchive/archive_read_support_format_rar5.c | 27 ++++++++++++++----- + libarchive/test/test_read_format_rar5.c | 17 ++++++++++++ + ...mat_rar5_window_buf_and_size_desync.rar.uu | 11 ++++++++ + 4 files changed, 50 insertions(+), 6 deletions(-) + create mode 100644 libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu + +--- a/Makefile.am ++++ b/Makefile.am +@@ -884,6 +884,7 @@ libarchive_test_EXTRA_DIST=\ + libarchive/test/test_read_format_rar5_different_winsize_on_merge.rar.uu \ + libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ + libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ ++ libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ + libarchive/test/test_read_format_raw.bufr.uu \ + libarchive/test/test_read_format_raw.data.gz.uu \ + libarchive/test/test_read_format_raw.data.Z.uu \ +--- a/libarchive/archive_read_support_format_rar5.c ++++ b/libarchive/archive_read_support_format_rar5.c +@@ -1730,14 +1730,29 @@ static int process_head_file(struct arch + } + } + +- /* If we're currently switching volumes, ignore the new definition of +- * window_size. */ +- if(rar->cstate.switch_multivolume == 0) { +- /* Values up to 64M should fit into ssize_t on every +- * architecture. */ +- rar->cstate.window_size = (ssize_t) window_size; ++ if(rar->cstate.window_size < (ssize_t) window_size && ++ rar->cstate.window_buf) ++ { ++ /* If window_buf has been allocated before, reallocate it, so ++ * that its size will match new window_size. */ ++ ++ uint8_t* new_window_buf = ++ realloc(rar->cstate.window_buf, window_size); ++ ++ if(!new_window_buf) { ++ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER, ++ "Not enough memory when trying to realloc the window " ++ "buffer."); ++ return ARCHIVE_FATAL; ++ } ++ ++ rar->cstate.window_buf = new_window_buf; + } + ++ /* Values up to 64M should fit into ssize_t on every ++ * architecture. */ ++ rar->cstate.window_size = (ssize_t) window_size; ++ + if(rar->file.solid > 0 && rar->file.solid_window_size == 0) { + /* Solid files have to have the same window_size across + whole archive. Remember the window_size parameter +--- a/libarchive/test/test_read_format_rar5.c ++++ b/libarchive/test/test_read_format_rar5.c +@@ -1206,6 +1206,23 @@ DEFINE_TEST(test_read_format_rar5_differ + EPILOGUE(); + } + ++DEFINE_TEST(test_read_format_rar5_window_buf_and_size_desync) ++{ ++ /* oss fuzz 30442 */ ++ ++ char buf[4096]; ++ PROLOGUE("test_read_format_rar5_window_buf_and_size_desync.rar"); ++ ++ /* Return codes of those calls are ignored, because this sample file ++ * is invalid. However, the unpacker shouldn't produce any SIGSEGV ++ * errors during processing. */ ++ ++ (void) archive_read_next_header(a, &ae); ++ while(0 < archive_read_data(a, buf, 46)) {} ++ ++ EPILOGUE(); ++} ++ + DEFINE_TEST(test_read_format_rar5_arm_filter_on_window_boundary) + { + char buf[4096]; +--- /dev/null ++++ b/libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu +@@ -0,0 +1,11 @@ ++begin 644 test_read_format_rar5_window_buf_and_size_desync.rar ++M4F%R(1H'`0`]/-[E`@$`_P$`1#[Z5P("`PL``BXB"?\`!(@B@0`)6.-AF?_1 ++M^0DI&0GG(F%R(0<:)`!3@"KT`P+G(@O_X[\``#&``(?!!0$$[:L``$.M*E)A ++MP0";/P1%``A*2DI*2DYQ<6TN9'%*2DI*2DI*``!DGNGIZ>8_^>GE/_``!. ++` ++end diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch new file mode 100644 index 0000000000..0e1549f229 --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2021-36976-3.patch @@ -0,0 +1,93 @@ +From 313bcd7ac547f7cc25945831f63507420c0874d7 Mon Sep 17 00:00:00 2001 +From: Grzegorz Antoniak +Date: Sat, 13 Feb 2021 10:13:22 +0100 +Subject: [PATCH] RAR5 reader: add more checks for invalid extraction + parameters + +Some specially crafted files declare invalid extraction parameters that +can confuse the RAR5 reader. + +One of the arguments is the declared window size parameter that the +archive file can declare for each file stored in the archive. Some +crafted files declare window size equal to 0, which is clearly wrong. + +This commit adds additional safety checks decreasing the tolerance of +the RAR5 format. + +This commit also contains OSSFuzz sample #30459. +--- + Makefile.am | 1 + + libarchive/archive_read_support_format_rar5.c | 10 ++++++++++ + libarchive/test/test_read_format_rar5.c | 19 +++++++++++++++++++ + ...t_rar5_bad_window_sz_in_mltarc_file.rar.uu | 7 +++++++ + 4 files changed, 37 insertions(+) + create mode 100644 libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu + +Upstream-Status: Backport [https://github.com/libarchive/libarchive/pull/1493/commits/313bcd7ac547f7cc25945831f63507420c0874d7] +CVE: CVE-2021-36976 +Signed-off-by: Virendra Thakur + +--- libarchive-3.4.2.orig/Makefile.am ++++ libarchive-3.4.2/Makefile.am +@@ -882,6 +882,7 @@ libarchive_test_EXTRA_DIST=\ + libarchive/test/test_read_format_rar5_block_size_is_too_small.rar.uu \ + libarchive/test/test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu \ + libarchive/test/test_read_format_rar5_window_buf_and_size_desync.rar.uu \ ++ libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu \ + libarchive/test/test_read_format_raw.bufr.uu \ + libarchive/test/test_read_format_raw.data.gz.uu \ + libarchive/test/test_read_format_raw.data.Z.uu \ +--- libarchive-3.4.2.orig/libarchive/archive_read_support_format_rar5.c ++++ libarchive-3.4.2/libarchive/archive_read_support_format_rar5.c +@@ -3637,6 +3637,16 @@ static int do_uncompress_file(struct arc + rar->cstate.initialized = 1; + } + ++ /* Don't allow extraction if window_size is invalid. */ ++ if(rar->cstate.window_size == 0) { ++ archive_set_error(&a->archive, ++ ARCHIVE_ERRNO_FILE_FORMAT, ++ "Invalid window size declaration in this file"); ++ ++ /* This should never happen in valid files. */ ++ return ARCHIVE_FATAL; ++ } ++ + if(rar->cstate.all_filters_applied == 1) { + /* We use while(1) here, but standard case allows for just 1 + * iteration. The loop will iterate if process_block() didn't +--- libarchive-3.4.2.orig/libarchive/test/test_read_format_rar5.c ++++ libarchive-3.4.2/libarchive/test/test_read_format_rar5.c +@@ -1305,3 +1305,22 @@ DEFINE_TEST(test_read_format_rar5_decode + + EPILOGUE(); + } ++ ++DEFINE_TEST(test_read_format_rar5_bad_window_size_in_multiarchive_file) ++{ ++ /* oss fuzz 30459 */ ++ ++ char buf[4096]; ++ PROLOGUE("test_read_format_rar5_bad_window_sz_in_mltarc_file.rar"); ++ ++ /* This file is damaged, so those functions should return failure. ++ * Additionally, SIGSEGV shouldn't be raised during execution ++ * of those functions. */ ++ ++ (void) archive_read_next_header(a, &ae); ++ while(0 < archive_read_data(a, buf, sizeof(buf))) {} ++ (void) archive_read_next_header(a, &ae); ++ while(0 < archive_read_data(a, buf, sizeof(buf))) {} ++ ++ EPILOGUE(); ++} +--- /dev/null ++++ libarchive-3.4.2/libarchive/test/test_read_format_rar5_bad_window_sz_in_mltarc_file.rar.uu +@@ -0,0 +1,7 @@ ++begin 644 test_read_format_rar5_bad_window_size_in_multiarchive_file.rar ++M4F%R(1H'`0`]/-[E`@$`_R`@1#[Z5P("`PL`("`@@"(`"?\@("#___\@("`@ ++M("`@("`@("`@4X`J]`,"YR(#$($@("`@``$@("`@@ X-Patchwork-Id: 14173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org From: "Steve Sakoman" Subject: [OE-core][dunfell 02/18] go: fix CVE-2022-23806 Date: Fri, 4 Mar 2022 05:04:10 -1000 Message-Id: In-Reply-To: References: MIME-Version: 1.0 List-id: To: openembedded-core@lists.openembedded.org From: Minjae Kim crypto/elliptic: fix IsOnCurve for big.Int values that are not valid coordinates Some big.Int values that are not valid field elements (negative or overflowing) might cause Curve.IsOnCurve to incorrectly return true. Operating on those values may cause a panic or an invalid curve operation. Note that Unmarshal will never return such values. Upstream-Status: Backport [https://go.dev/issue/50974] CVE: CVE-2022-23806 Signed-off-by:Minjae Kim Signed-off-by: Steve Sakoman --- meta/recipes-devtools/go/go-1.14.inc | 1 + .../go/go-1.14/CVE-2022-23806.patch | 142 ++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2022-23806.patch diff --git a/meta/recipes-devtools/go/go-1.14.inc b/meta/recipes-devtools/go/go-1.14.inc index abc6f42184..fcb316e09e 100644 --- a/meta/recipes-devtools/go/go-1.14.inc +++ b/meta/recipes-devtools/go/go-1.14.inc @@ -19,6 +19,7 @@ SRC_URI += "\ file://CVE-2021-34558.patch \ file://CVE-2021-33196.patch \ file://CVE-2021-33197.patch \ + file://CVE-2022-23806.patch \ " SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch" SRC_URI[main.sha256sum] = "7ed13b2209e54a451835997f78035530b331c5b6943cdcd68a3d815fdc009149" diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2022-23806.patch b/meta/recipes-devtools/go/go-1.14/CVE-2022-23806.patch new file mode 100644 index 0000000000..772acdcbf6 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.14/CVE-2022-23806.patch @@ -0,0 +1,142 @@ +From 5b376a209d1c61e10847e062d78c4b1aa90dff0c Mon Sep 17 00:00:00 2001 +From: Filippo Valsorda +Date: Sat, 26 Feb 2022 10:40:57 +0000 +Subject: [PATCH] crypto/elliptic: make IsOnCurve return false for invalid + + field elements + +Updates #50974 +Fixes #50977 +Fixes CVE-2022-23806 + +Signed-off-by: Minjae Kim + +--- + src/crypto/elliptic/elliptic.go | 6 +++ + src/crypto/elliptic/elliptic_test.go | 81 ++++++++++++++++++++++++++++ + src/crypto/elliptic/p224.go | 6 +++ + 3 files changed, 93 insertions(+) + +diff --git a/src/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go +index e2f71cd..bd574a4 100644 +--- a/src/crypto/elliptic/elliptic.go ++++ b/src/crypto/elliptic/elliptic.go +@@ -53,6 +53,12 @@ func (curve *CurveParams) Params() *CurveParams { + } + + func (curve *CurveParams) IsOnCurve(x, y *big.Int) bool { ++ ++ if x.Sign() < 0 || x.Cmp(curve.P) >= 0 || ++ y.Sign() < 0 || y.Cmp(curve.P) >= 0 { ++ return false ++ } ++ + // y² = x³ - 3x + b + y2 := new(big.Int).Mul(y, y) + y2.Mod(y2, curve.P) +diff --git a/src/crypto/elliptic/elliptic_test.go b/src/crypto/elliptic/elliptic_test.go +index 09c5483..b13a620 100644 +--- a/src/crypto/elliptic/elliptic_test.go ++++ b/src/crypto/elliptic/elliptic_test.go +@@ -628,3 +628,84 @@ func TestUnmarshalToLargeCoordinates(t *testing.T) { + t.Errorf("Unmarshal accepts invalid Y coordinate") + } + } ++ ++func testAllCurves(t *testing.T, f func(*testing.T, Curve)) { ++ tests := []struct { ++ name string ++ curve Curve ++ }{ ++ {"P256", P256()}, ++ {"P256/Params", P256().Params()}, ++ {"P224", P224()}, ++ {"P224/Params", P224().Params()}, ++ {"P384", P384()}, ++ {"P384/Params", P384().Params()}, ++ {"P521", P521()}, ++ {"P521/Params", P521().Params()}, ++ } ++ if testing.Short() { ++ tests = tests[:1] ++ } ++ for _, test := range tests { ++ curve := test.curve ++ t.Run(test.name, func(t *testing.T) { ++ t.Parallel() ++ f(t, curve) ++ }) ++ } ++} ++ ++// TestInvalidCoordinates tests big.Int values that are not valid field elements ++// (negative or bigger than P). They are expected to return false from ++// IsOnCurve, all other behavior is undefined. ++func TestInvalidCoordinates(t *testing.T) { ++ testAllCurves(t, testInvalidCoordinates) ++} ++ ++func testInvalidCoordinates(t *testing.T, curve Curve) { ++ checkIsOnCurveFalse := func(name string, x, y *big.Int) { ++ if curve.IsOnCurve(x, y) { ++ t.Errorf("IsOnCurve(%s) unexpectedly returned true", name) ++ } ++ } ++ ++ p := curve.Params().P ++ _, x, y, _ := GenerateKey(curve, rand.Reader) ++ xx, yy := new(big.Int), new(big.Int) ++ ++ // Check if the sign is getting dropped. ++ xx.Neg(x) ++ checkIsOnCurveFalse("-x, y", xx, y) ++ yy.Neg(y) ++ checkIsOnCurveFalse("x, -y", x, yy) ++ ++ // Check if negative values are reduced modulo P. ++ xx.Sub(x, p) ++ checkIsOnCurveFalse("x-P, y", xx, y) ++ yy.Sub(y, p) ++ checkIsOnCurveFalse("x, y-P", x, yy) ++ ++ // Check if positive values are reduced modulo P. ++ xx.Add(x, p) ++ checkIsOnCurveFalse("x+P, y", xx, y) ++ yy.Add(y, p) ++ checkIsOnCurveFalse("x, y+P", x, yy) ++ ++ // Check if the overflow is dropped. ++ xx.Add(x, new(big.Int).Lsh(big.NewInt(1), 535)) ++ checkIsOnCurveFalse("x+2⁵³⁵, y", xx, y) ++ yy.Add(y, new(big.Int).Lsh(big.NewInt(1), 535)) ++ checkIsOnCurveFalse("x, y+2⁵³⁵", x, yy) ++ ++ // Check if P is treated like zero (if possible). ++ // y^2 = x^3 - 3x + B ++ // y = mod_sqrt(x^3 - 3x + B) ++ // y = mod_sqrt(B) if x = 0 ++ // If there is no modsqrt, there is no point with x = 0, can't test x = P. ++ if yy := new(big.Int).ModSqrt(curve.Params().B, p); yy != nil { ++ if !curve.IsOnCurve(big.NewInt(0), yy) { ++ t.Fatal("(0, mod_sqrt(B)) is not on the curve?") ++ } ++ checkIsOnCurveFalse("P, y", p, yy) ++ } ++} +diff --git a/src/crypto/elliptic/p224.go b/src/crypto/elliptic/p224.go +index 8c76021..f1bfd7e 100644 +--- a/src/crypto/elliptic/p224.go ++++ b/src/crypto/elliptic/p224.go +@@ -48,6 +48,12 @@ func (curve p224Curve) Params() *CurveParams { + } + + func (curve p224Curve) IsOnCurve(bigX, bigY *big.Int) bool { ++ ++ if bigX.Sign() < 0 || bigX.Cmp(curve.P) >= 0 || ++ bigY.Sign() < 0 || bigY.Cmp(curve.P) >= 0 { ++ return false ++ } ++ + var x, y p224FieldElement + p224FromBig(&x, bigX) + p224FromBig(&y, bigY) From patchwork Fri Mar 4 15:04:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 4676 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07612C433F5 for ; Fri, 4 Mar 2022 15:04:54 +0000 (UTC) Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) by mx.groups.io with SMTP id smtpd.web10.7840.1646406292770788095 for ; Fri, 04 Mar 2022 07:04:53 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@sakoman-com.20210112.gappssmtp.com header.s=20210112 header.b=x5IgWclN; spf=softfail (domain: sakoman.com, ip: 209.85.216.50, mailfrom: steve@sakoman.com) Received: by mail-pj1-f50.google.com with SMTP id p3-20020a17090a680300b001bbfb9d760eso10817902pjj.2 for ; Fri, 04 Mar 2022 07:04:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20210112.gappssmtp.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=wdxGlIgnJGiz3lGKvCaGxmrdBY7AVdGMNueth6HAC1E=; b=x5IgWclNSh8Y59a/tRX/OPLT5Lsxwuq/tDCrBgwZV11LBD8X7PYOdWP4jRYfkitdjm U9qTrXks+prmQk4gD2QxUA7g/3G6LClDYV5thYal5t+1Yg2pqRm2eUakztFb/4V+5RAL OF/mDPR8+McXTQoN46p9yDe8+ILPx23/5zwzeLEwjGByGbX97Z63+yPpup+JboFC1uGC MkpsgoCoe3r2YolEutGCugndFzRKwaK6mX9z+fw3Av0+QwDeti/pK6BBQx1R26vI82Cv G6Avj2lcVdC5OS8BWmxgvbyQEt9zQh/Igroey0ng8oqhHq/b/4s5WS58C+DNA8ktpAHc oJdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wdxGlIgnJGiz3lGKvCaGxmrdBY7AVdGMNueth6HAC1E=; b=fjuK+4S7XcS3UhZkE3fLHnM7Lo97BFtgyv/jbka/ZoKIoLriA6ZNbL3+W6KeSBztBd TIagM+nhSa4I15qFoNeDtXveUuVjVloQ/DHRAS7FpGWnclm/H6H1OIXnVcxYRG2/PSyi trwN+HC6CFJOvG4Zd7LjCGyCx51/5d9YzyITzaRaCSXQQAYjhwJBFakfCVGuHg4FyrOw ZxuGeaz+eCvNw/eJMPDDFdnSaqvvuHYlt6akJ+w+hyPEbdY7f+JhC37U6EhLMm2NoM/h u0iRiZoUJtIHdQ+VXWri+Q+vPEBwhWj1jZijxQds6kOl8yy+bUOXHeezF2OOHMugSLqS M3dg== X-Gm-Message-State: AOAM530dKo1MSfFELbyi0XlDwzdVWFn5osjYbGFd5ZOcCf9xEwhu2mJW 3wFja8eG/2jNRTGQEkUF+va38xF89SQF4aDVUd0= X-Google-Smtp-Source: ABdhPJz4IUzjbG7j20IUBN9lXdM3J275IDFvYejkOL9TLmAsxfPS3AbYBL2gfXDXSM2V1/WZuqu4Dg== X-Received: by 2002:a17:90a:4146:b0:1bf:2dc8:7407 with SMTP id m6-20020a17090a414600b001bf2dc87407mr2201300pjg.76.1646406291731; Fri, 04 Mar 2022 07:04:51 -0800 (PST) Received: from hexa.router0800d9.com (dhcp-72-253-6-214.hawaiiantel.net. [72.253.6.214]) by smtp.gmail.com with ESMTPSA id f194-20020a6238cb000000b004f6ce898c61sm80400pfa.77.2022.03.04.07.04.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Mar 2022 07:04:51 -0800 (PST) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][dunfell 03/18] go: fix CVE-2022-23772 Date: Fri, 4 Mar 2022 05:04:11 -1000 Message-Id: X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 04 Mar 2022 15:04:54 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/162722 From: Minjae Kim math/big: prevent large memory consumption in Rat.SetString An attacker can cause unbounded memory growth in a program using (*Rat).SetString due to an unhandled overflow. Upstream-Status: Backport [https://go.dev/issue/50699] CVE: CVE-2022-23772 Signed-off-by:Minjae Kim Signed-off-by: Steve Sakoman --- meta/recipes-devtools/go/go-1.14.inc | 1 + .../go/go-1.14/CVE-2022-23772.patch | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2022-23772.patch diff --git a/meta/recipes-devtools/go/go-1.14.inc b/meta/recipes-devtools/go/go-1.14.inc index fcb316e09e..9b3c3b30a8 100644 --- a/meta/recipes-devtools/go/go-1.14.inc +++ b/meta/recipes-devtools/go/go-1.14.inc @@ -20,6 +20,7 @@ SRC_URI += "\ file://CVE-2021-33196.patch \ file://CVE-2021-33197.patch \ file://CVE-2022-23806.patch \ + file://CVE-2022-23772.patch \ " SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch" SRC_URI[main.sha256sum] = "7ed13b2209e54a451835997f78035530b331c5b6943cdcd68a3d815fdc009149" diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2022-23772.patch b/meta/recipes-devtools/go/go-1.14/CVE-2022-23772.patch new file mode 100644 index 0000000000..f0daee3624 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.14/CVE-2022-23772.patch @@ -0,0 +1,50 @@ +From 70882eedccac803ddcf1c3215e0ae8fd59847e39 Mon Sep 17 00:00:00 2001 +From: Katie Hockman +Date: Sat, 26 Feb 2022 20:03:38 +0000 +Subject: [PATCH] [release-branch.go1.16] math/big: prevent overflow in + (*Rat).SetString + +Credit to rsc@ for the original patch. + +Thanks to the OSS-Fuzz project for discovering this +issue and to Emmanuel Odeke (@odeke_et) for reporting it. + +Updates #50699 +Fixes #50700 +Fixes CVE-2022-23772 +--- + src/math/big/ratconv.go | 5 +++++ + src/math/big/ratconv_test.go | 1 + + 2 files changed, 6 insertions(+) + +diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go +index 941139e..e8cbdbe 100644 +--- a/src/math/big/ratconv.go ++++ b/src/math/big/ratconv.go +@@ -168,6 +168,11 @@ func (z *Rat) SetString(s string) (*Rat, bool) { + n := exp5 + if n < 0 { + n = -n ++ if n < 0 { ++ // This can occur if -n overflows. -(-1 << 63) would become ++ // -1 << 63, which is still negative. ++ return nil, false ++ } + } + pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs + if exp5 > 0 { +diff --git a/src/math/big/ratconv_test.go b/src/math/big/ratconv_test.go +index ba0d1ba..b820df4 100644 +--- a/src/math/big/ratconv_test.go ++++ b/src/math/big/ratconv_test.go +@@ -104,6 +104,7 @@ var setStringTests = []StringTest{ + {in: "4/3/"}, + {in: "4/3."}, + {in: "4/"}, ++ {in: "13e-9223372036854775808"}, // CVE-2022-23772 + + // valid + {"0", "0", true}, +-- +2.17.1 + From patchwork Fri Mar 4 15:04:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve Sakoman X-Patchwork-Id: 4677 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C506C433EF for ; Fri, 4 Mar 2022 15:04:56 +0000 (UTC) Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) by mx.groups.io with SMTP id smtpd.web11.7942.1646406295589241111 for ; Fri, 04 Mar 2022 07:04:55 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@sakoman-com.20210112.gappssmtp.com header.s=20210112 header.b=E0DetpGQ; spf=softfail (domain: sakoman.com, ip: 209.85.215.181, mailfrom: steve@sakoman.com) Received: by mail-pg1-f181.google.com with SMTP id 195so7747111pgc.6 for ; Fri, 04 Mar 2022 07:04:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sakoman-com.20210112.gappssmtp.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=+VIPxverKIPH7mpG29z537Q0uQUlDTlGNDEycqZnj24=; b=E0DetpGQjIRC8OmMTD84tyGWSDVRDBmUYyaH6w0Ymp33xe6ymbtZux3bCZIxn3qD6T k218f4DpoGAVOax2LurAhlrY67zy4U6pa7N5nMAN2fO988klIhK+62Eik5ofjxnA2UbK edO0nj1gdTOdxDyH9MbF1QgOeH1mfjASiBtHjoGatkXuSBcejgtdei02DwxvlW854oej jNyPoRYqBLk1aD70FkpSaYEY8Kb6Z+T69CKU3BAD2L9mtwWsyEYbyUoyK7gk3+XK6Nsm K+FIFnn9Y3PQgWR4T6VnH/82qkvQ1cAtV09yadXG8iXRrxGk1QmiRzE3aquu28omtfWX Q63g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+VIPxverKIPH7mpG29z537Q0uQUlDTlGNDEycqZnj24=; b=N/NM3rE69sKskWFg2Y4LdsjnviQJPf4rjKH+uZ9ANccRzNqNwwq0EiAmehV7ZrTG24 FHBhhDZnCaXAqywQ/dGldr6QSdmVxqo36YxUSX69GXp5haQX1NPn+qyAfmgma9Jx/kfP wg3SDMwNlFWIcPYiLXN62r1/8tDsLAyRJzkUENsPWtadq8gVQE8rQJlM3q9ezGClNSJj GeCzBJCzHgGONSJUzv/HZVw/F9IHpDWM3sKot4jRpr28SN7QNBzTv5jNgyuZ0B9It+cF dXf0a9cG1UMwsMQr+is6wlBzBL5iAzmhMeP+7DCYOjn3wugqB4UERHs8xfDceTCAaOn0 ZitQ== X-Gm-Message-State: AOAM532AfNOECso6LLObua2XXKFXTnVWVkaGSO4d+f1Btg0jk4q6z3wP EyA7NXCtrRR9RSvQ7Ej/DjxIqRfEJlpaCGwZYmU= X-Google-Smtp-Source: ABdhPJzMQhXSpBateW424KPBVe0+975KrG8iWQ8skXj1CEIWLKwhKsxGsmQudXHepCwX5d97btiswg== X-Received: by 2002:a63:3d0b:0:b0:37f:ef34:1431 with SMTP id k11-20020a633d0b000000b0037fef341431mr87078pga.547.1646406294105; Fri, 04 Mar 2022 07:04:54 -0800 (PST) Received: from hexa.router0800d9.com (dhcp-72-253-6-214.hawaiiantel.net. [72.253.6.214]) by smtp.gmail.com with ESMTPSA id f194-20020a6238cb000000b004f6ce898c61sm80400pfa.77.2022.03.04.07.04.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Mar 2022 07:04:53 -0800 (PST) From: Steve Sakoman To: openembedded-core@lists.openembedded.org Subject: [OE-core][dunfell 04/18] expat: fix CVE-2022-25235 Date: Fri, 4 Mar 2022 05:04:12 -1000 Message-Id: <27ab07b1e8caa5c85526eee4a7a3ad0d73326866.1646406001.git.steve@sakoman.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 04 Mar 2022 15:04:56 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-core/message/162723 xmltok_impl.c in Expat (aka libexpat) before 2.4.5 lacks certain validation of encoding, such as checks for whether a UTF-8 character is valid in a certain context. Backport patches from: https://github.com/libexpat/libexpat/pull/562/commits CVE: CVE-2022-25235 Signed-off-by: Steve Sakoman --- .../expat/expat/CVE-2022-25235.patch | 283 ++++++++++++++++++ meta/recipes-core/expat/expat_2.2.9.bb | 1 + 2 files changed, 284 insertions(+) create mode 100644 meta/recipes-core/expat/expat/CVE-2022-25235.patch diff --git a/meta/recipes-core/expat/expat/CVE-2022-25235.patch b/meta/recipes-core/expat/expat/CVE-2022-25235.patch new file mode 100644 index 0000000000..be9182a5c1 --- /dev/null +++ b/meta/recipes-core/expat/expat/CVE-2022-25235.patch @@ -0,0 +1,283 @@ +From ee2a5b50e7d1940ba8745715b62ceb9efd3a96da Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Tue, 8 Feb 2022 17:37:14 +0100 +Subject: [PATCH] lib: Drop unused macro UTF8_GET_NAMING + +Upstream-Status: Backport +https://github.com/libexpat/libexpat/pull/562/commits + +CVE: CVE-2022-25235 + +Signed-off-by: Steve Sakoman + +--- + expat/lib/xmltok.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/lib/xmltok.c b/lib/xmltok.c +index a72200e8..3bddf125 100644 +--- a/lib/xmltok.c ++++ b/lib/xmltok.c +@@ -95,11 +95,6 @@ + + ((((byte)[1]) & 3) << 1) + ((((byte)[2]) >> 5) & 1)] \ + & (1u << (((byte)[2]) & 0x1F))) + +-#define UTF8_GET_NAMING(pages, p, n) \ +- ((n) == 2 \ +- ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \ +- : ((n) == 3 ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) : 0)) +- + /* Detection of invalid UTF-8 sequences is based on Table 3.1B + of Unicode 3.2: http://www.unicode.org/unicode/reports/tr28/ + with the additional restriction of not allowing the Unicode +From 3f0a0cb644438d4d8e3294cd0b1245d0edb0c6c6 Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Tue, 8 Feb 2022 04:32:20 +0100 +Subject: [PATCH] lib: Add missing validation of encoding (CVE-2022-25235) + +--- + expat/lib/xmltok_impl.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/lib/xmltok_impl.c b/lib/xmltok_impl.c +index 0430591b4..64a3b2c15 100644 +--- a/lib/xmltok_impl.c ++++ b/lib/xmltok_impl.c +@@ -61,7 +61,7 @@ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ +- if (! IS_NAME_CHAR(enc, ptr, n)) { \ ++ if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NAME_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ +@@ -90,7 +90,7 @@ + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ +- if (! IS_NMSTRT_CHAR(enc, ptr, n)) { \ ++ if (IS_INVALID_CHAR(enc, ptr, n) || ! IS_NMSTRT_CHAR(enc, ptr, n)) { \ + *nextTokPtr = ptr; \ + return XML_TOK_INVALID; \ + } \ +@@ -1134,6 +1134,10 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, + case BT_LEAD##n: \ + if (end - ptr < n) \ + return XML_TOK_PARTIAL_CHAR; \ ++ if (IS_INVALID_CHAR(enc, ptr, n)) { \ ++ *nextTokPtr = ptr; \ ++ return XML_TOK_INVALID; \ ++ } \ + if (IS_NMSTRT_CHAR(enc, ptr, n)) { \ + ptr += n; \ + tok = XML_TOK_NAME; \ +From c85a3025e7a1be086dc34e7559fbc543914d047f Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Wed, 9 Feb 2022 01:00:38 +0100 +Subject: [PATCH] lib: Add comments to BT_LEAD* cases where encoding has + already been validated + +--- + expat/lib/xmltok_impl.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/lib/xmltok_impl.c b/lib/xmltok_impl.c +index 64a3b2c1..84ff35f9 100644 +--- a/lib/xmltok_impl.c ++++ b/lib/xmltok_impl.c +@@ -1266,7 +1266,7 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, + switch (BYTE_TYPE(enc, ptr)) { + # define LEAD_CASE(n) \ + case BT_LEAD##n: \ +- ptr += n; \ ++ ptr += n; /* NOTE: The encoding has already been validated. */ \ + break; + LEAD_CASE(2) + LEAD_CASE(3) +@@ -1335,7 +1335,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, + switch (BYTE_TYPE(enc, ptr)) { + # define LEAD_CASE(n) \ + case BT_LEAD##n: \ +- ptr += n; \ ++ ptr += n; /* NOTE: The encoding has already been validated. */ \ + break; + LEAD_CASE(2) + LEAD_CASE(3) +@@ -1514,7 +1514,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, int attsMax, + state = inName; \ + } + # define LEAD_CASE(n) \ +- case BT_LEAD##n: \ ++ case BT_LEAD##n: /* NOTE: The encoding has already been validated. */ \ + START_NAME ptr += (n - MINBPC(enc)); \ + break; + LEAD_CASE(2) +@@ -1726,7 +1726,7 @@ PREFIX(nameLength)(const ENCODING *enc, const char *ptr) { + switch (BYTE_TYPE(enc, ptr)) { + # define LEAD_CASE(n) \ + case BT_LEAD##n: \ +- ptr += n; \ ++ ptr += n; /* NOTE: The encoding has already been validated. */ \ + break; + LEAD_CASE(2) + LEAD_CASE(3) +@@ -1771,7 +1771,7 @@ PREFIX(updatePosition)(const ENCODING *enc, const char *ptr, const char *end, + switch (BYTE_TYPE(enc, ptr)) { + # define LEAD_CASE(n) \ + case BT_LEAD##n: \ +- ptr += n; \ ++ ptr += n; /* NOTE: The encoding has already been validated. */ \ + break; + LEAD_CASE(2) + LEAD_CASE(3) +From 6a5510bc6b7efe743356296724e0b38300f05379 Mon Sep 17 00:00:00 2001 +From: Sebastian Pipping +Date: Tue, 8 Feb 2022 04:06:21 +0100 +Subject: [PATCH] tests: Cover missing validation of encoding (CVE-2022-25235) + +--- + expat/tests/runtests.c | 109 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 109 insertions(+) + +diff --git a/tests/runtests.c b/tests/runtests.c +index bc5344b1..9b155b82 100644 +--- a/tests/runtests.c ++++ b/tests/runtests.c +@@ -5998,6 +5998,105 @@ START_TEST(test_utf8_in_cdata_section_2) { + } + END_TEST + ++START_TEST(test_utf8_in_start_tags) { ++ struct test_case { ++ bool goodName; ++ bool goodNameStart; ++ const char *tagName; ++ }; ++ ++ // The idea with the tests below is this: ++ // We want to cover 1-, 2- and 3-byte sequences, 4-byte sequences ++ // go to isNever and are hence not a concern. ++ // ++ // We start with a character that is a valid name character ++ // (or even name-start character, see XML 1.0r4 spec) and then we flip ++ // single bits at places where (1) the result leaves the UTF-8 encoding space ++ // and (2) we stay in the same n-byte sequence family. ++ // ++ // The flipped bits are highlighted in angle brackets in comments, ++ // e.g. "[<1>011 1001]" means we had [0011 1001] but we now flipped ++ // the most significant bit to 1 to leave UTF-8 encoding space. ++ struct test_case cases[] = { ++ // 1-byte UTF-8: [0xxx xxxx] ++ {true, true, "\x3A"}, // [0011 1010] = ASCII colon ':' ++ {false, false, "\xBA"}, // [<1>011 1010] ++ {true, false, "\x39"}, // [0011 1001] = ASCII nine '9' ++ {false, false, "\xB9"}, // [<1>011 1001] ++ ++ // 2-byte UTF-8: [110x xxxx] [10xx xxxx] ++ {true, true, "\xDB\xA5"}, // [1101 1011] [1010 0101] = ++ // Arabic small waw U+06E5 ++ {false, false, "\x9B\xA5"}, // [1<0>01 1011] [1010 0101] ++ {false, false, "\xDB\x25"}, // [1101 1011] [<0>010 0101] ++ {false, false, "\xDB\xE5"}, // [1101 1011] [1<1>10 0101] ++ {true, false, "\xCC\x81"}, // [1100 1100] [1000 0001] = ++ // combining char U+0301 ++ {false, false, "\x8C\x81"}, // [1<0>00 1100] [1000 0001] ++ {false, false, "\xCC\x01"}, // [1100 1100] [<0>000 0001] ++ {false, false, "\xCC\xC1"}, // [1100 1100] [1<1>00 0001] ++ ++ // 3-byte UTF-8: [1110 xxxx] [10xx xxxx] [10xxxxxx] ++ {true, true, "\xE0\xA4\x85"}, // [1110 0000] [1010 0100] [1000 0101] = ++ // Devanagari Letter A U+0905 ++ {false, false, "\xA0\xA4\x85"}, // [1<0>10 0000] [1010 0100] [1000 0101] ++ {false, false, "\xE0\x24\x85"}, // [1110 0000] [<0>010 0100] [1000 0101] ++ {false, false, "\xE0\xE4\x85"}, // [1110 0000] [1<1>10 0100] [1000 0101] ++ {false, false, "\xE0\xA4\x05"}, // [1110 0000] [1010 0100] [<0>000 0101] ++ {false, false, "\xE0\xA4\xC5"}, // [1110 0000] [1010 0100] [1<1>00 0101] ++ {true, false, "\xE0\xA4\x81"}, // [1110 0000] [1010 0100] [1000 0001] = ++ // combining char U+0901 ++ {false, false, "\xA0\xA4\x81"}, // [1<0>10 0000] [1010 0100] [1000 0001] ++ {false, false, "\xE0\x24\x81"}, // [1110 0000] [<0>010 0100] [1000 0001] ++ {false, false, "\xE0\xE4\x81"}, // [1110 0000] [1<1>10 0100] [1000 0001] ++ {false, false, "\xE0\xA4\x01"}, // [1110 0000] [1010 0100] [<0>000 0001] ++ {false, false, "\xE0\xA4\xC1"}, // [1110 0000] [1010 0100] [1<1>00 0001] ++ }; ++ const bool atNameStart[] = {true, false}; ++ ++ size_t i = 0; ++ char doc[1024]; ++ size_t failCount = 0; ++ ++ for (; i < sizeof(cases) / sizeof(cases[0]); i++) { ++ size_t j = 0; ++ for (; j < sizeof(atNameStart) / sizeof(atNameStart[0]); j++) { ++ const bool expectedSuccess ++ = atNameStart[j] ? cases[i].goodNameStart : cases[i].goodName; ++ sprintf(doc, "<%s%s>