netinet: prevent NULL pointer dereference in in_aifaddr_ioctl()
It appears that maliciously crafted ifaliasreq can lead to NULL
pointer dereference in in_aifaddr_ioctl(). In order to replicate
that, one needs to
- Ensure that carp(4) is not loaded
- Issue SIOCAIFADDR call setting ifra_vhid field of the request to a negative value.
A repro code would look like this.
int main() {
struct ifaliasreq req; struct sockaddr_in sin, mask; int fd, error; bzero(&sin, sizeof(struct sockaddr_in)); bzero(&mask, sizeof(struct sockaddr_in)); sin.sin_len = sizeof(struct sockaddr_in); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr("192.168.88.2"); mask.sin_len = sizeof(struct sockaddr_in); mask.sin_family = AF_INET; mask.sin_addr.s_addr = inet_addr("255.255.255.0"); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) return (-1); memset(&req, 0, sizeof(struct ifaliasreq)); strlcpy(req.ifra_name, "lo0", sizeof(req.ifra_name)); memcpy(&req.ifra_addr, &sin, sin.sin_len); memcpy(&req.ifra_mask, &mask, mask.sin_len); req.ifra_vhid = -1; return ioctl(fd, SIOCAIFADDR, (char *)&req);
}
To fix, discard both positive and negative vhid values in
in_aifaddr_ioctl, if carp(4) is not loaded. This prevents NULL pointer
dereference and kernel panic.
Reviewed by: imp@
Pull Request: https://github.com/freebsd/freebsd-src/pull/530