Bug 457094 - Unititialized memory false positive - ioctl(SIOCSIFADDR) with IPv6
Summary: Unititialized memory false positive - ioctl(SIOCSIFADDR) with IPv6
Status: REPORTED
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (other bugs)
Version First Reported In: 3.19.0
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-07-24 21:17 UTC by Ian Pilcher
Modified: 2022-07-24 21:17 UTC (History)
0 users

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
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");
}