Created attachment 1666154 [details]
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
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):
still there with gcc-10.0.1-0.9.fc33.s390x
Jakub expects this is related to s390x inlining heuristics. The problem can be produced with
added to CFLAGS on eg. ppc64le too.
Jeremy, Justin, I would suggest to omit the -Werror option from the build flags.
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
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.
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.
Sorry for the glacial response. I've finally gotten around to sending a fix upstream and I've built kernel-tools for Fedora 32.