Hi Guillem,

Thanks for the correction — I apologize for the error. I've now located
the source (unace_1.2b.orig.tar.gz) and mapped the issue. Here is the
source-level root cause and a proposed patch.

ROOT CAUSE (source level)
-------------------------

The bug is in read_arc_head() in unace.c. The function scans a
size_buf (1024) byte heap buffer for the 7-byte ACE magic signature
"**ACE**" (acesign_len = 7, defined in acestruc.h):

memset(buf, 0, size_buf);
...
fpos += read(archan, &buf[buf_pos], size_buf - buf_pos);

for (i = 0; i < size_buf; i++) // iterates 0..1023
{
if (!memcmp(acesign, &buf[i], acesign_len)) // 7-byte comparison
...
}

At offsets i = 1018 through 1023, the 7-byte memcmp reads 1 to 6 bytes
past the end of the 1024-byte buffer. (My original report incorrectly
described this as a 4-byte uint32_t comparison based on the binary
analysis — the source shows it is actually a 7-byte memcmp, making the
over-read larger than initially reported: up to 6 bytes, not 3.)

PROPOSED PATCH
--------------

--- a/unace.c
+++ b/unace.c
@@ -211,7 +211,7 @@
old_fpos = fpos;
fpos += read(archan, &buf[buf_pos], size_buf - buf_pos);

- for (i = 0; i < size_buf; i++) // look for the acesign
+ for (i = 0; i <= size_buf - acesign_len; i++) // look for the acesign
{
if (!memcmp(acesign, &buf[i], acesign_len))
{

This stops the loop at offset 1018, so the last memcmp reads bytes
1018..1024 — exactly within bounds.

Best regards,
Xiang Chen

Reply via email to