Module Name: src Committed By: roy Date: Wed Jun 24 12:27:51 UTC 2020
Modified Files: src/sys/net: rtsock_shared.c Log Message: Ensure sockaddrs have valid lengths for RO_MISSFILTER. Thanks to maxv@ for spotting this. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/sys/net/rtsock_shared.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/rtsock_shared.c diff -u src/sys/net/rtsock_shared.c:1.17 src/sys/net/rtsock_shared.c:1.18 --- src/sys/net/rtsock_shared.c:1.17 Fri Mar 13 16:37:12 2020 +++ src/sys/net/rtsock_shared.c Wed Jun 24 12:27:51 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock_shared.c,v 1.17 2020/03/13 16:37:12 christos Exp $ */ +/* $NetBSD: rtsock_shared.c,v 1.18 2020/06/24 12:27:51 roy Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.17 2020/03/13 16:37:12 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.18 2020/06/24 12:27:51 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -96,6 +96,9 @@ __KERNEL_RCSID(0, "$NetBSD: rtsock_share #include <compat/net/if.h> #include <compat/net/route.h> +#define _SA_MINSIZE (offsetof(struct sockaddr, sa_len) + \ + sizeof(((struct sockaddr *)0)->sa_len)) + #ifdef COMPAT_RTSOCK /* * These are used when #include-d from compat/common/rtsock_50.c @@ -244,12 +247,13 @@ COMPATNAME(route_filter)(struct mbuf *m, char *ep = cp + rop->rocb_missfilterlen; /* Ensure we can access sa_len */ - if (m->m_pkthdr.len < sizeof(*rtm) + - offsetof(struct sockaddr, sa_len) + sizeof(ss.ss_len)) + if (m->m_pkthdr.len < sizeof(*rtm) + _SA_MINSIZE) return EINVAL; m_copydata(m, sizeof(*rtm) + offsetof(struct sockaddr, sa_len), sizeof(ss.ss_len), &ss.ss_len); - if (m->m_pkthdr.len < sizeof(*rtm) + ss.ss_len) + if (ss.ss_len < _SA_MINSIZE || + ss.ss_len > sizeof(ss) || + m->m_pkthdr.len < sizeof(*rtm) + ss.ss_len) return EINVAL; /* Copy out the destination sockaddr */ m_copydata(m, sizeof(*rtm), ss.ss_len, &ss); @@ -1059,6 +1063,9 @@ route_ctloutput(int op, struct socket *s break; } sa = (struct sockaddr *)cp; + if (sa->sa_len < _SA_MINSIZE || + sa->sa_len >sizeof(struct sockaddr_storage)) + return EINVAL; cp += RT_XROUNDUP(sa->sa_len); } if (cp != ep) {