Bug 114494 - false-positive with -O2 -Wstringop-overflow=2 -fsanitize=address
Summary: false-positive with -O2 -Wstringop-overflow=2 -fsanitize=address
Status: RESOLVED DUPLICATE of bug 99673
Alias: None
Product: gcc
Classification: Unclassified
Component: sanitizer (show other bugs)
Version: 13.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: Wstringop-overflow
  Show dependency treegraph
 
Reported: 2024-03-27 06:20 UTC by Akihiko Odaki
Modified: 2024-04-03 05:21 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Akihiko Odaki 2024-03-27 06:20:01 UTC
Building https://gitlab.com/qemu-project/qemu/-/commits/v9.0.0-rc1?ref_type=tags causes the following warning:

cc -m64 -mcx16 -Ilibcommon.fa.p -Isubprojects/dtc/libfdt -I../subprojects/dtc/libfdt -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/sysprof-6 -I/usr/include/gio-unix-2.0 -fdiagnostics-color=auto -Wall -Winvalid-pch -Werror -std=gnu11 -O2 -g -fsanitize=address -fstack-protector-strong -Wempty-body -Wendif-labels -Wexpansion-to-defined -Wformat-security -Wformat-y2k -Wignored-qualifiers -Wimplicit-fallthrough=2 -Winit-self -Wmissing-format-attribute -Wmissing-prototypes -Wnested-externs -Wold-style-declaration -Wold-style-definition -Wredundant-decls -Wshadow=local -Wstrict-prototypes -Wtype-limits -Wundef -Wvla -Wwrite-strings -Wno-missing-include-dirs -Wno-psabi -Wno-shift-negative-value -isystem /home/me/qemu/linux-headers -isystem linux-headers -iquote . -iquote /home/me/qemu -iquote /home/me/qemu/include -iquote /home/me/qemu/host/include/x86_64 -iquote /home/me/qemu/host/include/generic -iquote /home/me/qemu/tcg/i386 -pthread -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fno-strict-aliasing -fno-common -fwrapv -ftrivial-auto-var-init=zero -fzero-call-used-regs=used-gpr -fPIE -MD -MQ libcommon.fa.p/hw_net_rtl8139.c.o -MF libcommon.fa.p/hw_net_rtl8139.c.o.d -o libcommon.fa.p/hw_net_rtl8139.c.o -c ../hw/net/rtl8139.c
../hw/net/rtl8139.c: In function 'rtl8139_io_writeb':
../hw/net/rtl8139.c:2273:17: error: writing 8 bytes into a region of size 0 [-Werror=stringop-overflow=]
 2273 |                 memcpy(data_to_checksum, saved_ip_header + 12, 8);

Below is a minimized reproduction case:
gcc -O2 -Wstringop-overflow=2 -fsanitize=address -c -x c - <<EOF
#include <string.h>

struct ip_header {
    char  ip_ver_len;
};

void rtl8139_cplus_transmit_one(char *saved_buffer)
{
    struct ip_header *ip;
    int hlen;

    char *eth_payload_data = saved_buffer + 4;

    ip = (struct ip_header*)eth_payload_data;

    hlen = ip->ip_ver_len;
    if (hlen < sizeof(struct ip_header)) {
        return;
    }

    char saved_ip_header[1];
    memcpy(saved_ip_header, eth_payload_data, hlen);
    memcpy(eth_payload_data + hlen, saved_ip_header, 1);
}
EOF
Comment 1 Andrew Pinski 2024-03-27 06:24:01 UTC
Please note this part of the documentation:
Note that sanitizers tend to increase the rate of false positive warnings, most notably those around -Wmaybe-uninitialized. We recommend against combining -Werror and [the use of] sanitizers.


https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Instrumentation-Options.html#index-fsanitize_003daddress
Comment 2 Andrew Pinski 2024-03-27 06:27:55 UTC
Note the minimized testcase seems to be a real issue. hlen can either be 1 (the only value that works) or more than 1.
Comment 3 Akihiko Odaki 2024-03-27 06:33:28 UTC
(In reply to Andrew Pinski from comment #2)
> Note the minimized testcase seems to be a real issue. hlen can either be 1
> (the only value that works) or more than 1.

Below is the the error message for the minimized testcase:

<stdin>: In function 'rtl8139_cplus_transmit_one':
<stdin>:23:5: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=]
<stdin>:4:11: note: at offset 1 into destination object 'ip_ver_len' of size 1

It does not seem to care if hlen == 1 or not.
Comment 4 Andrew Pinski 2024-03-27 07:37:08 UTC
Dup of bug 99673.

```
  _14 = &MEM[(struct ip_header *)saved_buffer_5(D) + 4B].ip_ver_len;
...
  _3 = _14 + _2;
...
  MEM[(char * {ref-all})_3] = _10;
```

Without -fsanitize=address, there is no `&MEM[(struct ip_header *)saved_buffer_5(D) + 4B].ip_ver_len` but rather just `eth_payload_data_6 = saved_buffer_5(D) + 4`.

See the duplicate bug for more analysis of the issue.

*** This bug has been marked as a duplicate of bug 99673 ***
Comment 5 Hans-Peter Nilsson 2024-04-01 18:18:43 UTC
(In reply to Akihiko Odaki from comment #0)
>     if (hlen < sizeof(struct ip_header)) {

Is this a typo for "if (hlen > sizeof(struct ip_header)) {" which makes a bot more sense to me?

(I can't find it in Linux/drivers, so can't check "upstream" status.)
Comment 6 Akihiko Odaki 2024-04-03 05:21:06 UTC
(In reply to Hans-Peter Nilsson from comment #5)
> (In reply to Akihiko Odaki from comment #0)
> >     if (hlen < sizeof(struct ip_header)) {
> 
> Is this a typo for "if (hlen > sizeof(struct ip_header)) {" which makes a
> bot more sense to me?
> 
> (I can't find it in Linux/drivers, so can't check "upstream" status.)

It is not Linux but QEMU. Please look at: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114494#c0