Merge pull request #3209 from datauwu/7zip-fix-sfx-boundary

7zip: fix SFX boundary checks
(cherry picked from commit d05e842435)
This commit is contained in:
Dustin L. Howett authored and Martin Matuska committed 2026-07-26 20:13:26 +02:00
1 parent 72455fd3e2
commit 1bd53b6538
5 files changed
+91 -4

No files matched your search

+2
View File
@@ -892,6 +892,8 @@ libarchive_test_EXTRA_DIST=\
libarchive/test/test_read_format_7zip_malformed_numfiles_oom.7z.uu \
libarchive/test/test_read_format_7zip_packinfo_digests.7z.uu \
libarchive/test/test_read_format_7zip_ppmd.7z.uu \
libarchive/test/test_read_format_7zip_sfx_boundary_elf.elf.uu \
libarchive/test/test_read_format_7zip_sfx_boundary_pe.exe.uu \
libarchive/test/test_read_format_7zip_sfx_elf.elf.uu \
libarchive/test/test_read_format_7zip_sfx_elf64trunc.elf.uu \
libarchive/test/test_read_format_7zip_sfx_modified_pe.exe.uu \
@@ -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;
+41
View File
@@ -1383,6 +1383,47 @@ DEFINE_TEST(test_read_format_7zip_sfx_elf)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
static void
test_sfx_boundary_empty_7z(const char *refname)
{
struct archive_entry *ae = NULL;
struct archive *a;
const int bs = 10240;
extract_reference_file(refname);
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,
archive_read_open_filename(a, refname, bs));
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualInt(0, archive_file_count(a));
assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_read_format_7zip_sfx_boundary_pe)
{
/*
* The embedded empty 7z archive starts at the final exact
* 32-byte scan window after the PE overlay offset.
*/
test_sfx_boundary_empty_7z(
"test_read_format_7zip_sfx_boundary_pe.exe");
}
DEFINE_TEST(test_read_format_7zip_sfx_boundary_elf)
{
/*
* The ELF section string table contains "\0.data\0", so
* ".data\0" starts at the final valid string-table position.
*/
test_sfx_boundary_empty_7z(
"test_read_format_7zip_sfx_boundary_elf.elf");
}
/*
* A truncated ELF 64-bit MSB file.
*/
@@ -0,0 +1,22 @@
begin 644 test_read_format_7zip_sfx_boundary_elf.elf
M?T5,1@(!`0````````````(`/@`!```````````````````````````"````
M`````````$```````$```P`!```N9&%T80``````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````````````````,`````
M````````````````````0``````````'````````````````````````````
M``````````````$````!```````````````````````````#````````(```
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````-WJ\KR<<``2-F]4/````````````````````````````````````````
6````````````````````````````````
`
end
@@ -0,0 +1,22 @@
begin 644 test_read_format_7zip_sfx_boundary_pe.exe
M35H`````````````````````````````````````````````````````````
M````````````````````0````%!%``!,`0$`````````````````X``"````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````+G1E
M>'0````````````````!`````@``````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````04%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04$W>KRO)QP`!(V;
6U0\`````````````````````````````
`
end