Package: unace-nonfree
Version: 2.5-10
Severity: important
Tags: security

unace-nonfree 2.5 has an overlapping strcpy in the archive path processing
function. When processing an archive path containing '&' (0x26), the program
calls strcpy(ptr, ptr + 1) to shift the remaining string left by one byte.

Because source and destination overlap (src = dst + 1), this violates C11
section 7.24.2.3 and constitutes undefined behavior. On glibc 2.43+
(Ubuntu 26.04 / Debian trixie), the SIMD-optimized strcpy produces
observable data corruption in the filename buffer.

Root cause (function at offset 0xe7e0 in the stripped binary):

char *pcVar2 = strchr(param_1, 0x26); // find '&'
if (pcVar2 != NULL) {
strcpy(pcVar2, pcVar2 + 1); // UB: src overlaps dst
}

Trigger: any archive path containing '&', e.g.:
unace-nonfree l '/tmp/test&file.ace'

Reproduction:

python3 -c "
import struct, binascii
body = b'\x00' + struct.pack('<H', 0) + b'**ACE**' + b'\x14\x14\x00\x00'
body += struct.pack('<II', 0, 0) + b'\x00'
body = body.ljust(27, b'\x00')
crc = (binascii.crc32(body) ^ 0xFFFFFFFF) & 0xFFFF
header = struct.pack('<HH', crc, len(body)) + body
open('/tmp/test&file.ace', 'wb').write(header)
"
valgrind --tool=memcheck unace-nonfree l '/tmp/test&file.ace'

Expected valgrind output:
Source and destination overlap in strcpy(0x..., 0x...+1)

Observable data corruption with long paths:
$ unace-nonfree l
'/tmp/a&very_long_archive_name_showing_data_corruption.ace'
processing archive /tmp/a_showing_data_corruption.ace <-- GARBLED

Suggested fix: replace strcpy with memmove(ptr, ptr + 1, strlen(ptr + 1) +
1).
Since this is a binary-only package with no upstream, options include binary
patching, adding a package advisory, or considering removal.

The software is proprietary, authored by e-merge GmbH (defunct ~2000), and
unmaintained. There is no upstream to notify. A CVE ID has been requested
via MITRE CNA-LR.

Reply via email to