Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Sep 2021 15:56:28 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: 0d2b77383b02 - stable/12 - freebsd32: Fix a double copyin in sendmsg() and recvmsg()
Message-ID:  <202109261556.18QFuSuq008883@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/12 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=0d2b77383b021646b91b90a4c2a0816af5688553

commit 0d2b77383b021646b91b90a4c2a0816af5688553
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:56:11 +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 fea30190e672..68a17f4fb004 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1204,19 +1204,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);
@@ -1349,19 +1345,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?202109261556.18QFuSuq008883>