summaryrefslogtreecommitdiff
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 4c35642866c9f..5acfd658caf60 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);