Writing a file near 4 GiB causes an overflow when we calculate the
number of block pointers we need to store, which leads to us allocating
the wrong amount of memory to store them.
This is visible with ASan:
Exercising: libarchive 3.9.0dev zlib/1.3.1 liblzma/5.4.4 bz2lib/1.0.8 libzstd/1.5.6 cng/2.0 libb2/bundled
706: test_write_format_iso9660_zisofs_overflow
=================================================================
==40444==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x08c004b4 at pc 0x006acb3b bp 0x002edb44 sp 0x002edb38
WRITE of size 1 at 0x08c004b4 thread T0
#0 0x006acb3a in archive_le32enc libarchive\archive_endian.h:219
#1 0x006c81d0 in zisofs_write_to_temp libarchive\archive_write_set_format_iso9660.c:7760
#2 0x006ca1bd in write_iso9660_data libarchive\archive_write_set_format_iso9660.c:1785
Crafted TOC with a base64-encoded <name> of odd length, which used to
make strappend_base64() read past the character-data buffer. The trailing
incomplete base64 character is dropped; the rest still decodes.
tar: mark bsdtar as long-path aware on Windows
tar -C/--directory option calls SetCurrentDirectoryW(), which is limited to MAX_PATH (260) characters unless the process opts in to longpath support via an application manifest and enables a registry setting or sets an option in developer settings.
Verify that symlink creations and overwriting works, i.e. that dangling
symlinks are properly overwritten.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Verify that -u does not override files which have a newer timestamp.
This also verifies that creation of timestamps properly works.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Verify that -f does not create new files and also does not override
files which have a newer timestamp.
This also verifies that creation of timestamps properly works.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
bsdtar's -C/--directory option calls SetCurrentDirectoryW(), which is
limited to MAX_PATH (260) characters unless the process opts in to long
path support via an application manifest declaring longPathAware.
Extracting into (or changing into) a directory whose path exceeds 260
characters fails with "could not chdir".
Embed a longPathAware application manifest into bsdtar.exe so these
operations work for long destination paths. Both Windows build systems
(CMake and the autotools/Makefile.am build) embed it, using different
mechanisms per toolchain:
- MinGW/Clang (GNU ld) do not generate an application manifest, so it
is compiled from a resource script (bsdtar.rc) via windres. This
manifest replaces the toolchain default, so it also declares the
asInvoker execution level explicitly.
- MSVC's linker already embeds a manifest (resource id 1); a duplicate
RT_MANIFEST resource fails to link (CVT1100). Instead the manifest is
merged into the linker's default manifest (asInvoker) by adding it to
the target sources.
The cab reader does not support multi volume archives, but it should be
able to read the files to print information about content.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
The archive_integer.h header offers various integer operations to
libarchive, utilizing system functionality where possible.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Add a 7z regression test for malformed SubStreamsInfo metadata that
declares more than one unpack stream without the kSize data needed to
describe those streams.
Store the archive as a .7z.uu file, matching the existing malformed
7z tests.
A malformed RAR5 archive with data_size=1 forces bytes_remaining
(ssize_t) to wrap to -2 when a compressed block header consumes
to_skip=3 bytes (CWE-191). That negative value is then implicitly
cast to size_t ~0 inside malloc(), requesting a ~16-exabyte
allocation — confirmed heap buffer overflow via ASAN/UBSan on a
48-byte crafted archive requiring no authentication.
Reproducer: 48-byte crafted RAR5 archive; ASAN confirms
"allocation-size-too-big 0xfffffffffffffffe".
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Verify that afio headers are detected even on unfortunate filter read
splits, i.e. when magic is found but rest of header has yet to be
retrieved.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
process_base_block() returned ARCHIVE_RETRY for HEAD_MAIN (and
HFL_SKIP_IF_UNKNOWN) blocks without consuming the body bytes the
sub-parser did not read. rar5_read_header() then re-parsed the same
region, turning an O(1) skip into O(N) and letting a crafted RAR5 file
stall the reader (GHSA-9h2c-464f-j3hj).
Record the block body start and skip any unconsumed bytes through a
small helper rar5_skip_remaining_block() before returning ARCHIVE_RETRY.
Add two regression tests derived from test_read_format_rar5_stored, each
with extra unread bytes appended to a no-data block's body (HEAD_MAIN and
an unknown HFL_SKIP_IF_UNKNOWN block); both fail on master and pass with
the fix.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Rock Ridge rr_move functionality for paths with a depth larger than 8
has a few bugs in it. For one, it might loop over the same entries over
and over. And second, rr_move/ directory entries are not verified to be
unique. Both issues can lead to NULL pointer dereferences.
Add a test case which highlights the NULL pointer dereference.
Based on issue #2936.
It is possible to trigger an endless loop on 32 bit systems due to
a triggerable integer overflow.
Add a regression test for this.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Make sure that empty wide character names do not lead to out of boundary
accesses.
Reported by shura-turtle.
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Low-distance repeat state is scoped to the current RAR3 LZ table. Reusing it after a new table starts can make the next match use the wrong offset, producing incorrect output and a file CRC error.
Reset lastlowoffset and numlowoffsetrepeats when parsing a new LZ table. Add a small handcrafted RAR3 fixture that leaves a low-distance repeat pending, switches tables, and verifies the decoded bytes after the boundary.
RAR3 recovery records can be stored as NEWSUB RR blocks with payloads larger than the old 1 MiB extended-header limit. These records are metadata-only for this reader, so after validating the header and guarding against header-size plus payload-size overflow, consume the remaining header bytes and payload instead of rejecting the archive.
Add a reference archive with a NEWSUB RR payload just over 1 MiB, and keep the malformed huge-size case covering the overflow/truncation path.