aboutsummaryrefslogtreecommitdiff
path: root/sys/ofed
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-05-03 16:51:04 +0000
committerMark Johnston <markj@FreeBSD.org>2021-05-17 17:43:07 +0000
commit1e066db6cdad4f3d4934bad487db68d3a7872727 (patch)
treed583d412be812686ef680fe130aea7055d029c43 /sys/ofed
parent3eebc6234b007e467d58f570e560c08385dd2319 (diff)
downloadsrc-1e066db6cdad4f3d4934bad487db68d3a7872727.tar.gz
src-1e066db6cdad4f3d4934bad487db68d3a7872727.zip
Add missing sockaddr length and family validation to various protocols
Several protocol methods take a sockaddr as input. In some cases the sockaddr lengths were not being validated, or were validated after some out-of-bounds accesses could occur. Add requisite checking to various protocol entry points, and convert some existing checks to assertions where appropriate. Reported by: syzkaller+KASAN Reviewed by: tuexen, melifaro Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29519 (cherry picked from commit f161d294b92732df6254a89f393ab24999e122bf)
Diffstat (limited to 'sys/ofed')
-rw-r--r--sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
index e7ae4e03365e..a38bdfcbed59 100644
--- a/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
+++ b/sys/ofed/drivers/infiniband/ulp/sdp/sdp_main.c
@@ -519,9 +519,9 @@ sdp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)nam;
- if (nam->sa_len != sizeof (*sin))
- return (EINVAL);
if (sin->sin_family != AF_INET)
+ return (EAFNOSUPPORT);
+ if (nam->sa_len != sizeof(*sin))
return (EINVAL);
if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
return (EAFNOSUPPORT);
@@ -617,10 +617,10 @@ sdp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)nam;
- if (nam->sa_len != sizeof (*sin))
+ if (nam->sa_len != sizeof(*sin))
return (EINVAL);
if (sin->sin_family != AF_INET)
- return (EINVAL);
+ return (EAFNOSUPPORT);
if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
return (EAFNOSUPPORT);
if ((error = prison_remote_ip4(td->td_ucred, &sin->sin_addr)) != 0)
@@ -932,6 +932,21 @@ sdp_send(struct socket *so, int flags, struct mbuf *m,
int error;
int cnt;
+ if (nam != NULL) {
+ if (nam->sa_family != AF_INET) {
+ if (control)
+ m_freem(control);
+ m_freem(m);
+ return (EAFNOSUPPORT);
+ }
+ if (nam->sa_len != sizeof(struct sockaddr_in)) {
+ if (control)
+ m_freem(control);
+ m_freem(m);
+ return (EINVAL);
+ }
+ }
+
error = 0;
ssk = sdp_sk(so);
KASSERT(m->m_flags & M_PKTHDR,