Module Name: src Committed By: riastradh Date: Fri Jul 1 21:22:23 UTC 2022
Modified Files: src/sys/net: rtsock_shared.c Log Message: route(4): Use m_copydata, not misaligned mtod struct access. XXX Maybe this should check rtm_len too like route_output does. Reported-by: syzbot+d37eaf0a26097572b...@syzkaller.appspotmail.com https://syzkaller.appspot.com/bug?id=3cdfefd8b7938c9606ed68b4191e97fabdbd7b08 To generate a diff of this commit: cvs rdiff -u -r1.21 -r1.22 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.21 src/sys/net/rtsock_shared.c:1.22 --- src/sys/net/rtsock_shared.c:1.21 Wed Jun 29 23:15:08 2022 +++ src/sys/net/rtsock_shared.c Fri Jul 1 21:22:23 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock_shared.c,v 1.21 2022/06/29 23:15:08 riastradh Exp $ */ +/* $NetBSD: rtsock_shared.c,v 1.22 2022/07/01 21:22:23 riastradh 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.21 2022/06/29 23:15:08 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.22 2022/07/01 21:22:23 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -213,7 +213,7 @@ COMPATNAME(route_filter)(struct mbuf *m, struct rawcb *rp) { struct routecb *rop = (struct routecb *)rp; - struct rt_xmsghdr *rtm; + struct rt_xmsghdr rtm; KASSERT(m != NULL); KASSERT(proto != NULL); @@ -229,18 +229,19 @@ COMPATNAME(route_filter)(struct mbuf *m, /* Ensure we can access rtm_type */ if (m->m_len < - offsetof(struct rt_xmsghdr, rtm_type) + sizeof(rtm->rtm_type)) + offsetof(struct rt_xmsghdr, rtm_type) + sizeof(rtm.rtm_type)) return EINVAL; - rtm = mtod(m, struct rt_xmsghdr *); - if (rtm->rtm_type >= sizeof(rop->rocb_msgfilter) * CHAR_BIT) + m_copydata(m, offsetof(struct rt_xmsghdr, rtm_type), + sizeof(rtm.rtm_type), &rtm.rtm_type); + if (rtm.rtm_type >= sizeof(rop->rocb_msgfilter) * CHAR_BIT) return EINVAL; /* If the rtm type is filtered out, return a positive. */ if (rop->rocb_msgfilter != 0 && - !(rop->rocb_msgfilter & RTMSGFILTER(rtm->rtm_type))) + !(rop->rocb_msgfilter & RTMSGFILTER(rtm.rtm_type))) return EEXIST; - if (rop->rocb_missfilterlen != 0 && rtm->rtm_type == RTM_MISS) { + if (rop->rocb_missfilterlen != 0 && rtm.rtm_type == RTM_MISS) { __CTASSERT(RTAX_DST == 0); struct sockaddr_storage ss; struct sockaddr *dst = (struct sockaddr *)&ss, *sa; @@ -248,16 +249,16 @@ 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) + _SA_MINSIZE) + if (m->m_pkthdr.len < sizeof(rtm) + _SA_MINSIZE) return EINVAL; - m_copydata(m, sizeof(*rtm) + offsetof(struct sockaddr, sa_len), + m_copydata(m, sizeof(rtm) + offsetof(struct sockaddr, sa_len), sizeof(ss.ss_len), &ss.ss_len); if (ss.ss_len < _SA_MINSIZE || ss.ss_len > sizeof(ss) || - m->m_pkthdr.len < sizeof(*rtm) + ss.ss_len) + 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); + m_copydata(m, sizeof(rtm), ss.ss_len, &ss); /* Find a matching sockaddr in the filter */ while (cp < ep) {