kyua run under WITH_ASAN= built world reports a global-buffer-overflow during cpio test.

From: Mark Millard <marklmi_at_yahoo.com>
Date: Wed, 12 Jan 2022 09:54:19 UTC
For the below it appears that the report from UBSAN is accurate.

==85511==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000010753ca at pc 0x000001139bda bp 0x7fffffffc2b0 sp 0x7fffffffc2a8
READ of size 1 at 0x0000010753ca thread T0
    #0 0x1139bd9 in hexdump /usr/main-src/contrib/libarchive/test_utils/test_main.c:875:35
    #1 0x113b73c in assertion_text_file_contents /usr/main-src/contrib/libarchive/test_utils/test_main.c:1182:3
    #2 0x1125d46 in basic_cpio /usr/main-src/contrib/libarchive/cpio/test/test_basic.c:84:2
    #3 0x11259dc in test_basic /usr/main-src/contrib/libarchive/cpio/test/test_basic.c:229:2
    #4 0x1144943 in test_run /usr/main-src/contrib/libarchive/test_utils/test_main.c:3561:2
    #5 0x1144943 in main /usr/main-src/contrib/libarchive/test_utils/test_main.c:4062:9

0x0000010753ca is located 54 bytes to the left of global variable '<string literal>' defined in '/usr/main-src/contrib/libarchive/cpio/test/test_basic.c:229:13' (0x1075400) of size 5
  '<string literal>' is ascii string 'copy'
0x0000010753ca is located 22 bytes to the left of global variable '<string literal>' defined in '/usr/main-src/contrib/libarchive/cpio/test/test_basic.c:228:38' (0x10753e0) of size 9
  '<string literal>' is ascii string '1 block
'
0x0000010753ca is located 0 bytes to the right of global variable '<string literal>' defined in '/usr/main-src/contrib/libarchive/cpio/test/test_basic.c:220:18' (0x10753c0) of size 10
  '<string literal>' is ascii string '2 blocks
'
SUMMARY: AddressSanitizer: global-buffer-overflow /usr/main-src/contrib/libarchive/test_utils/test_main.c:875:35 in hexdump
Shadow bytes around the buggy address:
  0x40000020ea20: f9 f9 f9 f9 02 f9 f9 f9 00 01 f9 f9 00 02 f9 f9
  0x40000020ea30: 00 00 00 00 00 00 02 f9 f9 f9 f9 f9 00 f9 f9 f9
  0x40000020ea40: 00 01 f9 f9 00 00 00 00 00 00 01 f9 f9 f9 f9 f9
  0x40000020ea50: 06 f9 f9 f9 07 f9 f9 f9 00 00 00 00 00 07 f9 f9
  0x40000020ea60: f9 f9 f9 f9 04 f9 f9 f9 05 f9 f9 f9 00 00 00 00
=>0x40000020ea70: 00 05 f9 f9 f9 f9 f9 f9 00[02]f9 f9 00 01 f9 f9
  0x40000020ea80: 05 f9 f9 f9 01 f9 f9 f9 00 01 f9 f9 00 05 f9 f9
  0x40000020ea90: 00 02 f9 f9 00 f9 f9 f9 00 02 f9 f9 07 f9 f9 f9
  0x40000020eaa0: 00 01 f9 f9 07 f9 f9 f9 00 02 f9 f9 00 02 f9 f9
  0x40000020eab0: 00 03 f9 f9 00 01 f9 f9 00 04 f9 f9 00 00 00 00
  0x40000020eac0: 00 00 00 03 f9 f9 f9 f9 00 00 00 f9 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==85511==ABORTING

Well, contrib/libarchive/cpio/test/test_basic.c:84 is doing:

        assertTextFileContents(se, "pack.err");

which involves, in turn:

int
assertion_text_file_contents(const char *filename, int line, const char *buff, const char *fn)
{
. . .
        s = (int)strlen(buff);
        contents = malloc(s * 2 + 128);
        n = (int)fread(contents, 1, s * 2 + 128 - 1, f);
. . .
        if (n > 0) {
                hexdump(contents, buff, n, 0);
. . .

Nothing about the code seems to constrain n to fit the
size of the space for "pack.err" (9 bytes of "global"
space).

The report is for the ref[i + j] in the code:

static void
hexdump(const char *p, const char *ref, size_t l, size_t offset)
{
. . .
                for (j = 0; j < 16 && i + j < l; j++) {
                        if (ref != NULL && p[i + j] != ref[i + j])
. . .

where ref points to the space for "pack.err" and l was
given a copy of the value of n in the previously shown
code.

The i + j < l constraint need not avoid the code doing
ref[i + j] in a way that reaches outside the space for
"pack.err" --because of the supplied value of n (a.k.a. l)
not being sufficient to respect the space for "pack.err".


===
Mark Millard
marklmi at yahoo.com