libbitcoin / libbitcoin-system

Bitcoin Cross-Platform C++ Development Toolkit
https://libbitcoin.info/
Other
1.3k stars 379 forks source link

gcc 13.2.0: bogus Wstringop-overflow in qrencode MQRspec_createFrame (-O3 only) #1541

Open evoskuil opened 2 hours ago

evoskuil commented 2 hours ago
static unsigned char *MQRspec_createFrame(int version)
{
    unsigned char *frame, *p, *q;
    int width;
    int x, y;

    width = mqrspecCapacity[version].width;
    frame = (unsigned char *)malloc((size_t)(width * width));
    if(frame == NULL) return NULL;

    memset(frame, 0, (size_t)(width * width));
    /* Finder pattern */
    putFinderPattern(frame, width, 0, 0);
    /* Separator */
    p = frame;
    for(y = 0; y < 7; y++) {
        p[7] = 0xc0;
        p += width;
    }
    memset(frame + width * 7, 0xc0, 8);
    /* Mask format information area */
    memset(frame + width * 8 + 1, 0x84, 8);
    p = frame + width + 8;
    for(y = 0; y < 7; y++) {
        *p = 0x84;
        p += width;
    }
    /* Timing pattern */
    p = frame + 8;
    q = frame + width * 8;
    for(x = 1; x < width-7; x++) {
        *p =  0x90 | (x & 1);
        *q =  0x90 | (x & 1);
        p++;
        q += width;
    }

    return frame;
}

In relation to the above code, the warnings below imply that frame + width * 7 and frame + width * 8 + 1 may be zero, which cannot be the case. The minimum non-zero value for width is 21, and if when it is zero frame == NULL.

    width = mqrspecCapacity[version].width;
    frame = (unsigned char *)malloc((size_t)(width * width));
    if(frame == NULL) return NULL;
In function 'memset',
    inlined from 'MQRspec_createFrame' at src/wallet/addresses/qrencode/mqrspec.c:206:2,
    inlined from 'MQRspec_newFrame' at src/wallet/addresses/qrencode/mqrspec.c:231:9:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:59:10: warning: '__builtin___memset_chk' writing 8 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
   59 |   return __builtin___memset_chk (__dest, __ch, __len,
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   60 |                                  __glibc_objsize0 (__dest));
      |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
In function 'memset',
    inlined from 'MQRspec_createFrame' at src/wallet/addresses/qrencode/mqrspec.c:208:2,
    inlined from 'MQRspec_newFrame' at src/wallet/addresses/qrencode/mqrspec.c:231:9:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:59:10: warning: '__builtin___memset_chk' writing 8 bytes into a region of size 0 overflows the destination [-Wstringop-overflow=]
   59 |   return __builtin___memset_chk (__dest, __ch, __len,
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   60 |                                  __glibc_objsize0 (__dest));
      |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
evoskuil commented 2 hours ago

See also https://github.com/libbitcoin/libbitcoin-system/issues/1540

evoskuil commented 2 hours ago

See our gcc12 bogus Wstringop-overflow warnings that are now gone in gcc 13.