diff --git a/sys/net/route.c b/sys/net/route.c --- a/sys/net/route.c +++ b/sys/net/route.c @@ -924,6 +924,17 @@ else bcopy(dst, ndst, dst->sa_len); + /* + * Zero the sockaddr alignment padding. The key is + * allocated RT_ROUNDUP(sa_len) bytes (rt_setgate) but + * only sa_len bytes were initialized; rt_msg_buffer() + * (rtsock.c) copies the full rounded length back to + * userland when replying to -- potentially + * unprivileged -- RTM_GET, disclosing stale heap data. + */ + bzero((char *)ndst + dst->sa_len, + RT_ROUNDUP(dst->sa_len) - dst->sa_len); + if (rtinfo->rti_info[RTAX_MPLS1] != NULL) rt_setshims(rt, rtinfo->rti_info); @@ -1224,7 +1235,16 @@ /* Set the gateway value. */ rt->rt_gateway = (struct sockaddr *)(space + dlen); - bcopy(gate, rt->rt_gateway, glen); + /* + * Copy only the valid bytes and zero the alignment padding: + * glen (RT_ROUNDUP) may exceed gate's valid content -- the + * final sockaddr of a route(4) message need not be padded -- + * and the full rounded length is copied back out by + * rt_msg_buffer() on RTM_GET replies. + */ + bcopy(gate, rt->rt_gateway, gate->sa_len); + bzero((char *)rt->rt_gateway + gate->sa_len, + glen - gate->sa_len); if (oldspace != NULL) { /*