Bug 1807781 - false positive "may be used uninitialized" warning
Summary: false positive "may be used uninitialized" warning
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel-tools
Version: rawhide
Hardware: s390x
OS: Unspecified
Target Milestone: ---
Assignee: Justin M. Forbes
QA Contact: Fedora Extras Quality Assurance
Depends On:
Blocks: ZedoraTracker 1793473
TreeView+ depends on / blocked
Reported: 2020-02-27 09:03 UTC by Dan Horák
Modified: 2020-04-06 18:23 UTC (History)
16 users (show)

Fixed In Version: kernel-tools-5.6.0-300.fc32
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Last Closed: 2020-04-06 18:23:06 UTC
Type: Bug

Attachments (Terms of Use)
preprocessed source (241.37 KB, text/plain)
2020-02-27 09:03 UTC, Dan Horák
no flags Details

Description Dan Horák 2020-02-27 09:03:57 UTC
Created attachment 1666154 [details]
preprocessed source

Description of problem:
gcc produces a false positive "may be used uninitialized" warning when compiling tools/lib/bpf/netlink.c in the kernel.

The code (https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/netlink.c#n187) is roughly

__u32 nl_pid;
sock = libbpf_netlink_open(&nl_pid);
ret = bpf_netlink_recv(sock, nl_pid, seq, NULL, NULL, NULL);

and gcc prints

netlink.c: In function ‘bpf_set_link_xdp_fd’:
netlink.c:187:8: error: ‘nl_pid’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  187 |  ret = bpf_netlink_recv(sock, nl_pid, seq, NULL, NULL, NULL);
      |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
netlink.c: In function ‘bpf_get_link_xdp_info’:
netlink.c:334:9: error: ‘nl_pid’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
  334 |  return bpf_netlink_recv(sock, nl_pid, seq, __dump_link_nlmsg,
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  335 |     dump_link_nlmsg, cookie);
      |     ~~~~~~~~~~~~~~~~~~~~~~~~
netlink.c:259:8: note: ‘nl_pid’ was declared here
  259 |  __u32 nl_pid;
      |        ^~~~~~
cc1: all warnings being treated as errors

The full command line is

gcc -Wp,-MD,staticobjs/.netlink.o.d -Wp,-MT,staticobjs/netlink.o -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -fcommon -m64 -march=zEC12 -mtune=z13 -fasynchronous-unwind-tables -fstack-clash-protection -DHAVE_LIBELF_MMAP_SUPPORT -Wbad-function-cast -Wdeclaration-after-statement -Wformat-security -Wformat-y2k -Winit-self -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wno-system-headers -Wold-style-definition -Wpacked -Wredundant-decls -Wstrict-prototypes -Wswitch-default -Wswitch-enum -Wundef -Wwrite-strings -Wformat -Wstrict-aliasing=3 -Wshadow -Werror -Wall -fPIC -I. -I/home/nfs/dhorak/kernel-tools/kernel-5.5.fc33/linux-5.5/tools/include -I/home/nfs/dhorak/kernel-tools/kernel-5.5.fc33/linux-5.5/tools/arch/s390/include/uapi -I/home/nfs/dhorak/kernel-tools/kernel-5.5.fc33/linux-5.5/tools/include/uapi -fvisibility=hidden -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D"BUILD_STR(s)=#s" -c -o staticobjs/netlink.o netlink.c

Version-Release number of selected component (if applicable):

Comment 1 Dan Horák 2020-03-23 10:54:37 UTC
still there with gcc-10.0.1-0.9.fc33.s390x

Comment 2 Dan Horák 2020-03-23 16:26:55 UTC
Jakub expects this is related to s390x inlining heuristics. The problem can be produced with 
"--param=inline-min-speedup=2 --param=max-inline-insns-auto=80"
added to CFLAGS on eg. ppc64le too.

Jeremy, Justin, I would suggest to omit the -Werror option from the build flags.

Comment 3 Jeff Law 2020-03-23 18:44:00 UTC
Another approach if they don't want to remove the -Werror would be to use the pragma mechanisms to disable the warning in the place where it happens.

Something like this

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized
<code with the false positive>
#pragma GCC diagnostic pop

Comment 4 Jakub Jelinek 2020-03-23 19:46:44 UTC
BTW, the reason for the warning is that the compiler doesn't know what the authors of netlink.c assume, namely that if socket or bind or getsockname return a negative return value, then errno (expanded as *__errno_location ())
will be in the range [1, INT_MAX].
GCC right now has no attribute or whatever other way to express such invariant nor are those functions builtin for which it would hardcode such knowledge.
So, if the function initializes what the pointer points to only in the ultimate success case and the compiler doesn't know that all the early exits that return -errno (and will keep what the pointer points to uninitialized)
will return negative, then it has to emit the maybe uninitialized warning and the only reason why it isn't emitted otherwise is that the function isn't inlined.

Now, perhaps this is quite frequent special case and we could have some attribute that C libraries could ensure such behavior and teach VRP about that, but that doesn't look like GCC 10 material at this point.

Comment 5 Jakub Jelinek 2020-03-23 19:49:25 UTC
IMHO the best way to workaround the warning is to *nl_pid = 0; at the start of libbpf_netlink_open or initialize nl_pid to some value in the callers before calling that function.
Or one can __u32 nl_pid = nl_pid; to disable the warning while keeping it uninitialized.

Comment 6 Jeremy Cline 2020-04-06 18:23:06 UTC
Sorry for the glacial response. I've finally gotten around to sending a fix upstream[0] and I've built kernel-tools for Fedora 32.


Note You need to log in before you can comment on or make changes to this bug.