ifconf(): correct handling of sockaddrs smaller than struct sockaddr.

Portable programs that use SIOCGIFCONF (e.g. traceroute) assume
that each pseudo ifreq is of length MAX(sizeof(struct ifreq),
sizeof(ifr_name) + ifr_addr.sa_len).  For short sockaddrs we copied
too much from the source sockaddr resulting in a heap leak.

I believe only one such sockaddr exists (struct sockaddr_sco which
is 8 bytes) and it is unclear if such sockaddrs end up on interfaces
in practice.  If it did, the result would be an 8 byte heap leak on
current architectures.

admbugs:	869
Reviewed by:	kib
Obtained from:	CheriBSD
MFC after:	3 days
Security:	kernel heap leak
Sponsored by:	DARPA, AFRL
Differential Revision:	https://reviews.freebsd.org/D14981
This commit is contained in:
Brooks Davis 2018-04-06 20:26:56 +00:00
parent 54095bf428
commit e7fdc72e95
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332151

View file

@ -3191,7 +3191,13 @@ ifconf(u_long cmd, caddr_t data)
continue;
addrs++;
if (sa->sa_len <= sizeof(*sa)) {
ifr.ifr_addr = *sa;
if (sa->sa_len < sizeof(*sa)) {
memset(&ifr.ifr_ifru.ifru_addr, 0,
sizeof(ifr.ifr_ifru.ifru_addr));
memcpy(&ifr.ifr_ifru.ifru_addr, sa,
sa->sa_len);
} else
ifr.ifr_ifru.ifru_addr = *sa;
sbuf_bcat(sb, &ifr, sizeof(ifr));
max_len += sizeof(ifr);
} else {