Bug 457094

Summary: Unititialized memory false positive - ioctl(SIOCSIFADDR) with IPv6
Product: [Developer tools] valgrind Reporter: Ian Pilcher <arequipeno>
Component: memcheckAssignee: Julian Seward <jseward>
Status: REPORTED ---    
Severity: normal    
Priority: NOR    
Version First Reported In: 3.19.0   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description Ian Pilcher 2022-07-24 21:17:18 UTC
It seems that Valgrind does not know about struct in6_ifreq, which is used when manipulating IPv6 addresses with ioctl().  (See netdevice(7).)  Thus, the following code causes Valgrind to incorrectly detect use of unitialized memory:

static void ipou_set_tun_ip6(void)
{
	struct in6_ifreq ifr6;

	memset(&ifr6, 0, sizeof ifr6);
	ifr6.ifr6_addr = ipou_tun_addr6;
	ifr6.ifr6_prefixlen = ipou_tun_pfx6;
	ifr6.ifr6_ifindex = ipou_tun_index;

	if (ioctl(ipou_socket_fd, SIOCSIFADDR, &ifr6) < 0)
		IPOU_FATAL("ioctl failed: SIOCSIFADDR: %m");
}

(ipou_socket_fd is an AF_INET6 socket.)

The error reported is:

==12298== Syscall param ioctl(SIOCSIF*ADDR) points to uninitialised byte(s)
==12298==    at 0x499776F: ioctl (in /usr/lib64/libc.so.6)
==12298==    by 0x4082C1: ipou_set_tun_ip6 (tun.c:70)
==12298==    by 0x4085EF: ipou_tun_setup (tun.c:123)
==12298==    by 0x402991: ipou_client_hello (client.c:99)
==12298==    by 0x4029CF: ipou_client_setup (client.c:110)
==12298==    by 0x405765: main (main.c:51)
==12298==  Address 0x1fff000298 is on thread 1's stack
==12298==  in frame #1, created by ipou_set_tun_ip6 (tun.c:62)
==12298==

The error can be suppressed by ensuring that the initialized block passed to ioctl() is at least as large as a struct ifreq.

static void ipou_set_tun_ip6(void)
{
	union { struct in6_ifreq ifr6; struct ifreq ifr; } req;

	memset(&req, 0, sizeof req);
	req.ifr6.ifr6_addr = ipou_tun_addr6;
	req.ifr6.ifr6_prefixlen = ipou_tun_pfx6;
	req.ifr6.ifr6_ifindex = ipou_tun_index;

	if (ioctl(ipou_socket_fd, SIOCSIFADDR, &req.ifr6) < 0)
		IPOU_FATAL("ioctl failed: SIOCSIFADDR: %m");
}