With code like:
struct sock_fprog bpf = {
.len = 3,
.filter = code,
};
setsockopt(sock, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &bpf, sizeof(bpf));
Valgrind complains:
==1903595== Syscall param socketcall.setsockopt(optval) points to uninitialised byte(s)
==1903595== at 0x4DFFA6A: setsockopt_syscall (setsockopt.c:29)
==1903595== by 0x4DFFA6A: setsockopt (setsockopt.c:95)
==1903595== by 0x113026: udp_bind4 (udp.c:75)
==1903595== by 0x11307A: udp_find_or_create_fd (udp.c:84)
...
==1903595== Address 0x1ffefffe82 is on thread 1's stack
==1903595== in frame #1, created by udp_bind4 (udp.c:20)
==1903595==
This is because, even at -O0, the six bytes of padding between .len and .code are uninitialised.
I can fix it with a work-around of:
union {
uint8_t buf[16];
struct sock_fprog fprog;
} bpf = {0};
bpf.fprog.len = 3;
bpf.fprog.filter = code;
setsockopt(sock, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &bpf, sizeof(bpf));
but it is ugly and I have many structs with padding causing these Valgrind errors.
Using static
zeroes the padding, but in many cases I need to use non-constant values.
What are my options to stop Valgrind complaining about these, without silencing any true positives?
This is similar to
https://bugs.kde.org/show_bug.cgi?id=435375
One workaround would be to memset your struct to 0. You could make that conditional by including "valgrind.h" and using the RUNNING_ON_VALGRIND macro.
It's hard to fix that sort of thing in Valgrind. We would have to handle every single kind of socket struct.