From: datauwu <209150516+datauwu@users.noreply.github.com> Date: Tue, 30 Jun 2026 13:46:55 +0000 (+0800) Subject: 7zip: fix SFX boundary checks X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aabed7871061b891cabaedbf8debc1cfbf72ad54;p=thirdparty%2Flibarchive.git 7zip: fix SFX boundary checks The SFX scanner missed a valid 7-Zip header when exactly 32 bytes remained in the lookahead buffer. The ELF SFX path also missed ".data" when it was at the last valid position in the section string table. It also allowed e_shstrndx to be equal to e_shnum, even though that is one past the section table. Tighten these checks so valid edge cases are handled correctly. --- diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c index 31fca67f4..02124e436 100644 --- a/libarchive/archive_read_support_format_7zip.c +++ b/libarchive/archive_read_support_format_7zip.c @@ -579,7 +579,7 @@ get_data_offset(struct archive_read *a, int64_t *data_offset, int compat) continue; } p = buff + offset; - while (p + 32 < buff + bytes_avail) { + while (buff + bytes_avail - p >= 32) { size_t step = check_7zip_header_in_sfx(p); if (step == 0) { *data_offset = p - buff; @@ -776,7 +776,7 @@ get_elf_sfx_offset(struct archive_read *a, int64_t *sfx_offset, int compat) e_shentsize = (*dec16)(h + 0x3A); e_shnum = (*dec16)(h + 0x3C); e_shstrndx = (*dec16)(h + 0x3E); - if (e_shnum < e_shstrndx || e_shentsize < 0x28) + if (e_shnum <= e_shstrndx || e_shentsize < 0x28) break; } else { @@ -784,7 +784,7 @@ get_elf_sfx_offset(struct archive_read *a, int64_t *sfx_offset, int compat) e_shentsize = (*dec16)(h + 0x2E); e_shnum = (*dec16)(h + 0x30); e_shstrndx = (*dec16)(h + 0x32); - if (e_shnum < e_shstrndx || e_shentsize < 0x18) + if (e_shnum <= e_shstrndx || e_shentsize < 0x18) break; } @@ -838,7 +838,7 @@ get_elf_sfx_offset(struct archive_read *a, int64_t *sfx_offset, int compat) return (ARCHIVE_FATAL); } size_t data_sym_offset = strtab_size; - for (size_t offset = 0; offset < strtab_size - 6; offset++) { + for (size_t offset = 0; offset + 6 <= strtab_size; offset++) { if (memcmp(h + offset, ".data\00", 6) == 0) { data_sym_offset = offset; break;