git: c46697b9cb97 - main - freebsd32_sendmsg: fix control message ABI
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 24 Aug 2022 17:36:01 UTC
The branch main has been updated by brooks:
URL: https://cgit.FreeBSD.org/src/commit/?id=c46697b9cb97a14f61ac0a58758aab081b9e48c5
commit c46697b9cb97a14f61ac0a58758aab081b9e48c5
Author: Brooks Davis <brooks@FreeBSD.org>
AuthorDate: 2022-08-24 17:34:39 +0000
Commit: Brooks Davis <brooks@FreeBSD.org>
CommitDate: 2022-08-24 17:34:39 +0000
freebsd32_sendmsg: fix control message ABI
When a freebsd32 caller uses all or most allowed space for control
messages (MCLBYTES == 2K) then the message may no longer fit when
the messages are padded for 64-bit alignment. Historically we've just
shrugged and said there is no ABI guarantee. We ran into this on
CheriBSD where a capsicumized 64-bit nm would fail when called with more
than 64 files.
Fix this by not gratutiously capping size of mbuf data we'll allocate
to MCLBYTES and let m_get2 allocate up to MJUMPAGESIZE (4K or larger).
Instead of hard-coding a length check, let m_get2 do it and check for a
NULL return.
Reviewed by: markj, jhb, emaste
Sponsored by: DARPA, AFRL
Differential Revision: https://reviews.freebsd.org/D36322
---
sys/compat/freebsd32/freebsd32_misc.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index d1c44a4f9952..b4c212ecd38d 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1535,6 +1535,7 @@ freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen)
u_int msglen, outlen;
int error;
+ /* Enforce the size limit of the native implementation. */
if (buflen > MCLBYTES)
return (EINVAL);
@@ -1570,20 +1571,20 @@ freebsd32_copyin_control(struct mbuf **mp, caddr_t buf, u_int buflen)
outlen += CMSG_ALIGN(sizeof(*cm)) +
CMSG_ALIGN(msglen - FREEBSD32_ALIGN(sizeof(*cm)));
}
- if (error == 0 && outlen > MCLBYTES) {
- /*
- * XXXMJ This implies that the upper limit on 32-bit aligned
- * control messages is less than MCLBYTES, and so we are not
- * perfectly compatible. However, there is no platform
- * guarantee that mbuf clusters larger than MCLBYTES can be
- * allocated.
- */
- error = EINVAL;
- }
if (error != 0)
goto out;
+ /*
+ * Allocate up to MJUMPAGESIZE space for the re-aligned and
+ * re-padded control messages. This allows a full MCLBYTES of
+ * 32-bit sized and aligned messages to fit and avoids an ABI
+ * mismatch with the native implementation.
+ */
m = m_get2(outlen, M_WAITOK, MT_CONTROL, 0);
+ if (m == NULL) {
+ error = EINVAL;
+ goto out;
+ }
m->m_len = outlen;
md = mtod(m, void *);