Search code examples
cstructvalgrindpadding

How to initialise the padding in structs, so that Valgrind stops complaining


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?


Solution

  • 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.