libuv / libuv

Cross-platform asynchronous I/O

Home Page:https://libuv.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`-Wstringop-overread` warning with libuv v1.48.0 (`unix/tcp.c:295`) with IBM AT17.0 (GCC 13.2.1)

johnsonjh opened this issue · comments

Using libuv v1.48.0 built with IBM AT release 17.0 (GCC version 13.2.1 20231004 (Advance-Toolchain 17.0-1) [83a521d872f5]), cross-compiling DPS8M (master, full LTO build) to Linux/POWER, we're receiving the following warning from IBM AT:

In function 'uv__tcp_connect',
    inlined from 'uv_tcp_connect' at ../../libuv-local/libuv-v1.48.0/src/uv-common.c:410:10,
    inlined from 'fnpuv_dial_out' at fnpuv.c:1160:5,
    inlined from 'wcd' at dps8_fnp2_iomcmd.c:226:13,
    inlined from 'interruptL66_CS_to_FNP' at dps8_fnp2_iomcmd.c:1370:23,
    inlined from 'interruptL66' at dps8_fnp2_iomcmd.c:1654:9,
    inlined from 'processMBX' at dps8_fnp2_iomcmd.c:2318:14,
    inlined from 'fnpCmd' at dps8_fnp2_iomcmd.c:2432:9,
    inlined from 'fnp_iom_cmd' at dps8_fnp2_iomcmd.c:2458:12:
../../libuv-local/libuv-v1.48.0/src/unix/tcp.c:295:5: warning: '__builtin_memcpy' reading 28 bytes from a region of size 16 [-Wstringop-overread]
  295 |     memcpy(&tmp6, addr, sizeof(tmp6));
      |     ^
fnpuv.c: In function 'fnp_iom_cmd':
fnpuv.c:1104:24: note: source object 'dest' of size 16
 1104 |     struct sockaddr_in dest;
      |                        ^

This warning only occurs when using our local libuv builder targets to bring libuv into our source tree and build it allowing for full inlining and link-time optimization.

I've not yet investigated further, so I've not completely ruled out potential issues with our code or with IBM's compiler, but I am pretty sure we are doing it correctly.

(I'll follow up shortly with a comment explaining the full steps to easily reproduce on Linux/x86_64 systems using AT17 to cross-compile to Linux/POWER using in-tree libuv, since it might not be trivially obvious how to do so.)

it looks like the code in question is:

  if (uv__is_ipv6_link_local(addr)) {
    memcpy(&tmp6, addr, sizeof(tmp6));
    if (tmp6.sin6_scope_id == 0) {
      tmp6.sin6_scope_id = uv__ipv6_link_local_scope_id();
      addr = (void*) &tmp6;
    }
  }

Obviously sizeof(struct sockaddr) is 16 and sizeof(struct sockaddr_in6) is 28, but since we're using IPv4 here, so I can't imagine this code would ever execute and cause us a problem.

It looks like a false positive. uv__is_ipv6_link_local() returns true if and only if addr.sa_family == AF_INET6. That block isn't executed when it's AF_INET or anything else.

Agreed, I'll close this unless I discover otherwise.