rtsock: fix a stack overflow

struct sockaddr is not sufficient for buffer that can hold any
sockaddr_* structure. struct sockaddr_storage should be used.

Test:
ifconfig epair create
ifconfig epair0a inet6 add 2001:db8::1 up
ndp -s 2001:db8::2 02:86:98:2e:96:0b proxy # this triggers kernel stack overflow

Reviewed by:	markj, kp
Differential Revision:	https://reviews.freebsd.org/D35188
This commit is contained in:
Kurosawa Takahiro 2022-05-13 19:58:11 +02:00 committed by Kristof Provost
parent d966efcc08
commit 9573cc3555

View File

@ -786,7 +786,7 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
* TODO: move this logic to userland.
*/
if (rtm->rtm_flags & RTF_ANNOUNCE) {
struct sockaddr laddr;
struct sockaddr_storage laddr;
if (nh->nh_ifp != NULL &&
nh->nh_ifp->if_type == IFT_PROPVIRTUAL) {
@ -796,17 +796,17 @@ handle_rtm_get(struct rt_addrinfo *info, u_int fibnum,
RT_ALL_FIBS);
if (ifa != NULL)
rt_maskedcopy(ifa->ifa_addr,
&laddr,
(struct sockaddr *)&laddr,
ifa->ifa_netmask);
} else
rt_maskedcopy(nh->nh_ifa->ifa_addr,
&laddr,
(struct sockaddr *)&laddr,
nh->nh_ifa->ifa_netmask);
/*
* refactor rt and no lock operation necessary
*/
rc->rc_rt = (struct rtentry *)rnh->rnh_matchaddr(&laddr,
&rnh->head);
rc->rc_rt = (struct rtentry *)rnh->rnh_matchaddr(
(struct sockaddr *)&laddr, &rnh->head);
if (rc->rc_rt == NULL) {
RIB_RUNLOCK(rnh);
return (ESRCH);