Date: Wed, 23 Dec 2020 16:17:43 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 92be2847e845 - rtsock: Avoid copying uninitialized padding bytes Message-ID: <202012231617.0BNGHhIQ055129@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=92be2847e845ba90e4da028cfd7f5a8013919f90 commit 92be2847e845ba90e4da028cfd7f5a8013919f90 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2020-12-23 16:15:11 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2020-12-23 16:16:40 +0000 rtsock: Avoid copying uninitialized padding bytes When copying sockaddrs out to userspace, we pad them to a multiple of the platform alignment (sizeof(long)). However, some sockaddr sizes, such as struct sockaddr_dl, are not an integer multiple of the alignment, so we may end up copying out uninitialized bytes. Fix this by always bouncing through a pre-zeroed sockaddr_storage. Reported by: KASAN Reviewed by: melifaro MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D27729 --- sys/net/rtsock.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 4c35642866c9..5acfd658caf6 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1258,12 +1258,12 @@ rtsock_fix_netmask(const struct sockaddr *dst, const struct sockaddr *smask, static struct mbuf * rtsock_msg_mbuf(int type, struct rt_addrinfo *rtinfo) { + struct sockaddr_storage ss; struct rt_msghdr *rtm; struct mbuf *m; int i; struct sockaddr *sa; #ifdef INET6 - struct sockaddr_storage ss; struct sockaddr_in6 *sin6; #endif int len, dlen; @@ -1308,13 +1308,17 @@ rtsock_msg_mbuf(int type, struct rt_addrinfo *rtinfo) if ((sa = rtinfo->rti_info[i]) == NULL) continue; rtinfo->rti_addrs |= (1 << i); + dlen = SA_SIZE(sa); + KASSERT(dlen <= sizeof(ss), + ("%s: sockaddr size overflow", __func__)); + bzero(&ss, sizeof(ss)); + bcopy(sa, &ss, sa->sa_len); + sa = (struct sockaddr *)&ss; #ifdef INET6 if (sa->sa_family == AF_INET6) { - sin6 = (struct sockaddr_in6 *)&ss; - bcopy(sa, sin6, sizeof(*sin6)); - if (sa6_recoverscope(sin6) == 0) - sa = (struct sockaddr *)sin6; + sin6 = (struct sockaddr_in6 *)sa; + (void)sa6_recoverscope(sin6); } #endif m_copyback(m, len, dlen, (caddr_t)sa); @@ -1342,12 +1346,11 @@ rtsock_msg_mbuf(int type, struct rt_addrinfo *rtinfo) static int rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int *plen) { - int i; - int len, buflen = 0, dlen; + struct sockaddr_storage ss; + int len, buflen = 0, dlen, i; caddr_t cp = NULL; struct rt_msghdr *rtm = NULL; #ifdef INET6 - struct sockaddr_storage ss; struct sockaddr_in6 *sin6; #endif #ifdef COMPAT_FREEBSD32 @@ -1414,12 +1417,15 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo, struct walkarg *w, int * #endif dlen = SA_SIZE(sa); if (cp != NULL && buflen >= dlen) { + KASSERT(dlen <= sizeof(ss), + ("%s: sockaddr size overflow", __func__)); + bzero(&ss, sizeof(ss)); + bcopy(sa, &ss, sa->sa_len); + sa = (struct sockaddr *)&ss; #ifdef INET6 if (sa->sa_family == AF_INET6) { - sin6 = (struct sockaddr_in6 *)&ss; - bcopy(sa, sin6, sizeof(*sin6)); - if (sa6_recoverscope(sin6) == 0) - sa = (struct sockaddr *)sin6; + sin6 = (struct sockaddr_in6 *)sa; + (void)sa6_recoverscope(sin6); } #endif bcopy((caddr_t)sa, cp, (unsigned)dlen);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012231617.0BNGHhIQ055129>