git: bcff2fdf8ee4 - stable/13 - freebsd32: Fix a double copyin in sendmsg() and recvmsg()
Mark Johnston
markj at FreeBSD.org
Sun Sep 26 15:55:44 UTC 2021
The branch stable/13 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=bcff2fdf8ee4b5053a5c7a7221879d2caf046b2b
commit bcff2fdf8ee4b5053a5c7a7221879d2caf046b2b
Author: Mark Johnston <markj at FreeBSD.org>
AuthorDate: 2021-09-19 17:45:09 +0000
Commit: Mark Johnston <markj at 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 at 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);
More information about the dev-commits-src-all
mailing list