Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions SPECS/libarchive/CVE-2026-4424.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
From ec6707deeda82a585bac6ec2b8d64a8a5924c985 Mon Sep 17 00:00:00 2001
From: elhananhaenel <elhanan.haenel@mail.huji.ac.il>
Date: Sat, 7 Mar 2026 22:32:09 +0200
Subject: [PATCH 1/2] rar: fix LZSS window size mismatch after PPMd block

When a PPMd-compressed block updates dictionary_size, the LZSS window
from a prior block is not reallocated. The allocation guard only checks
if dictionary_size is zero or the window pointer is NULL, not whether
the existing window is large enough. This allows copy_from_lzss_window()
to read past the allocated buffer.

Fix the guard to also check whether the current window is undersized.
Add bounds checks in copy_from_lzss_window() and parse_filter() as
defense in depth.
---
libarchive/archive_read_support_format_rar.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
index bb06f76..bc3f7d7 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -2503,7 +2503,8 @@ parse_codes(struct archive_read *a)
return (r);
}

- if (!rar->dictionary_size || !rar->lzss.window)
+ if (!rar->dictionary_size || !rar->lzss.window ||
+ (rar->lzss.mask + 1) < rar->dictionary_size)
{
/* Seems as though dictionary sizes are not used. Even so, minimize
* memory usage as much as possible.
@@ -3104,6 +3105,11 @@ copy_from_lzss_window(struct archive_read *a, uint8_t *buffer,

windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
firstpart = lzss_size(&rar->lzss) - windowoffs;
+ if (length > lzss_size(&rar->lzss)) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
+ "Bad RAR file data");
+ return (ARCHIVE_FATAL);
+ }
if (firstpart < 0) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Bad RAR file data");
@@ -3266,7 +3272,8 @@ parse_filter(struct archive_read *a, const uint8_t *bytes, uint16_t length, uint
else
blocklength = prog ? prog->oldfilterlength : 0;

- if (blocklength > rar->dictionary_size)
+ if (blocklength > rar->dictionary_size ||
+ blocklength > (uint32_t)(rar->lzss.mask + 1))
return 0;

registers[3] = PROGRAM_SYSTEM_GLOBAL_ADDRESS;
--
2.45.4


From 5fc14fd997dea3838ed49005b6e03241cb82f390 Mon Sep 17 00:00:00 2001
From: elhananhaenel <elhanan.haenel@mail.huji.ac.il>
Date: Sun, 8 Mar 2026 15:29:46 +0200
Subject: [PATCH 2/2] Fix -Wsign-compare: cast mask+1 to unsigned int

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/libarchive/libarchive/commit/762b30011a932c6ab988fd8664899a07eb6b7657.patch
---
libarchive/archive_read_support_format_rar.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
index bc3f7d7..ee02cf9 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -2504,7 +2504,7 @@ parse_codes(struct archive_read *a)
}

if (!rar->dictionary_size || !rar->lzss.window ||
- (rar->lzss.mask + 1) < rar->dictionary_size)
+ (unsigned int)(rar->lzss.mask + 1) < rar->dictionary_size)
{
/* Seems as though dictionary sizes are not used. Even so, minimize
* memory usage as much as possible.
--
2.45.4

85 changes: 85 additions & 0 deletions SPECS/libarchive/CVE-2026-4426.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
From b02edc81ab3947b0b9fc18fd5a6b127a6e0f447c Mon Sep 17 00:00:00 2001
From: elhananhaenel <elhanan.haenel@mail.huji.ac.il>
Date: Sat, 7 Mar 2026 22:14:23 +0200
Subject: [PATCH 1/2] iso9660: validate pz_log2_bs in parse_rockridge_ZF1()

The zisofs block size exponent (pz_log2_bs) read from the Rock Ridge ZF
extension entry is used directly in shift expressions without validation.
The zisofs specification only permits values 15, 16, or 17 (corresponding
to 32K, 64K, and 128K block sizes).

When pz_log2_bs >= 64 on 64-bit systems (or >= 32 on 32-bit), the
expression (size_t)1UL << pz_log2_bs is undefined behavior per C11
6.5.7. On 32-bit systems, a large exponent also causes the block pointer
allocation size computation (ceil + 1) * 4 to overflow to zero, leading
to a heap buffer overflow write after malloc(0).

Fix: reject any pz_log2_bs outside the range [15, 17] by disabling
zisofs for the entry (file->pz = 0), which prevents the zisofs
decompression path from executing.

Found by fuzzing with ASAN/UBSAN.
---
libarchive/archive_read_support_format_iso9660.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index baf265f..8dfeb88 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -2756,11 +2756,16 @@ parse_rockridge_ZF1(struct file_info *file, const unsigned char *data,
{

if (data[0] == 0x70 && data[1] == 0x7a && data_length == 12) {
- /* paged zlib */
- file->pz = 1;
- file->pz_log2_bs = data[3];
- file->pz_uncompressed_size = archive_le32dec(&data[4]);
- }
+ /* paged zlib */
+ file->pz = 1;
+ file->pz_log2_bs = data[3];
+ if (file->pz_log2_bs < 15 || file->pz_log2_bs > 17) {
+ /* Invalid block size exponent; disable zisofs. */
+ file->pz = 0;
+ return;
+ }
+ file->pz_uncompressed_size = archive_le32dec(&data[4]);
+ }
}

static void
--
2.45.4


From f3299fa94765152bdc40ddfee4ec0052921ea0f9 Mon Sep 17 00:00:00 2001
From: elhananhaenel <elhanan.haenel@mail.huji.ac.il>
Date: Sun, 8 Mar 2026 15:33:50 +0200
Subject: [PATCH 2/2] Add TODO comment for future error propagation

Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: https://github.com/libarchive/libarchive/commit/071e2e1c5981372d40482995ba83c98c8b595418.patch
---
libarchive/archive_read_support_format_iso9660.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
index 8dfeb88..28d868b 100644
--- a/libarchive/archive_read_support_format_iso9660.c
+++ b/libarchive/archive_read_support_format_iso9660.c
@@ -2760,7 +2760,10 @@ parse_rockridge_ZF1(struct file_info *file, const unsigned char *data,
file->pz = 1;
file->pz_log2_bs = data[3];
if (file->pz_log2_bs < 15 || file->pz_log2_bs > 17) {
- /* Invalid block size exponent; disable zisofs. */
+ /* TODO: Return an error here instead of silently
+ * disabling zisofs. That requires propagating an
+ * error return through parse_rockridge() and its
+ * callers. */
file->pz = 0;
return;
}
--
2.45.4

Loading
Loading