Date: Sun, 26 Sep 2021 15:55:44 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: bcff2fdf8ee4 - stable/13 - freebsd32: Fix a double copyin in sendmsg() and recvmsg() Message-ID: <202109261555.18QFtipl008675@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=bcff2fdf8ee4b5053a5c7a7221879d2caf046b2b commit bcff2fdf8ee4b5053a5c7a7221879d2caf046b2b Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-09-19 17:45:09 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-09-26 15:55:05 +0000 freebsd32: Fix a double copyin in sendmsg() and recvmsg() freebsd32_sendmsg() and freebsd32_recvmsg() both copyin the message header twice, once directly and once in freebsd32_copyinmsghdr(). The iovec length from the former is used when copying in msg_iov, but the rest of the kernel uses the iovec length from the latter. When kern_sendit() and kern_recvit() iterate over the iovec to compute the residual for I/O, they can therefore end up walking past the end of the copied in iovec, either resulting in a system call error, userspace memory corruption from uiomove() with invalid iovecs, or a kernel page fault if the copied-in iovec is followed by an unmapped KVA region. Reported by: syzbot+7cc64cd0c49605acd421@syzkaller.appspotmail.com Reviewed by: kib, emaste Sponsored by: The FreeBSD Foundation (cherry picked from commit fea1a98ead918b39280b586773a923e76194400b) --- sys/compat/freebsd32/freebsd32_misc.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index a4ae014dbe85..fd5ef9171982 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -1403,19 +1403,15 @@ int freebsd32_recvmsg(struct thread *td, struct freebsd32_recvmsg_args *uap) { struct msghdr msg; - struct msghdr32 m32; struct iovec *uiov, *iov; struct mbuf *control = NULL; struct mbuf **controlp; - int error; - error = copyin(uap->msg, &m32, sizeof(m32)); - if (error) - return (error); + error = freebsd32_copyinmsghdr(uap->msg, &msg); if (error) return (error); - error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, + error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); if (error) return (error); @@ -1548,19 +1544,15 @@ int freebsd32_sendmsg(struct thread *td, struct freebsd32_sendmsg_args *uap) { struct msghdr msg; - struct msghdr32 m32; struct iovec *iov; struct mbuf *control = NULL; struct sockaddr *to = NULL; int error; - error = copyin(uap->msg, &m32, sizeof(m32)); - if (error) - return (error); error = freebsd32_copyinmsghdr(uap->msg, &msg); if (error) return (error); - error = freebsd32_copyiniov(PTRIN(m32.msg_iov), m32.msg_iovlen, &iov, + error = freebsd32_copyiniov((void *)msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); if (error) return (error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202109261555.18QFtipl008675>