git: bbaa5523c01a - main - linux(4): Skip unsupported anxiliary message

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Mon, 14 Aug 2023 12:47:17 UTC
The branch main has been updated by dchagin:

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

commit bbaa5523c01a11e1e322928639522b9ccfd19978
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2023-08-14 12:46:12 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2023-08-14 12:46:12 +0000

    linux(4): Skip unsupported anxiliary message
    
    Instead of returning error, skip unsupported anxiliary messages and
    fail if no one handled.
    
    MFC after:      1 week
---
 sys/compat/linux/linux_socket.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 1acd93122b8f..90dc25f2e653 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1728,7 +1728,7 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
 	struct sockaddr *sa;
 	caddr_t outbuf;
 	void *data, *udata;
-	int error;
+	int error, skiped;
 
 	error = copyin(msghdr, &l_msghdr, sizeof(l_msghdr));
 	if (error != 0)
@@ -1794,7 +1794,7 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
 	msg->msg_control = mtod(control, struct cmsghdr *);
 	msg->msg_controllen = control->m_len;
 	outbuf = PTRIN(l_msghdr.msg_control);
-	outlen = 0;
+	skiped = outlen = 0;
 	for (m = control; m != NULL; m = m->m_next) {
 		cm = mtod(m, struct cmsghdr *);
 		lcm->cmsg_type = bsd_to_linux_cmsg_type(p, cm->cmsg_type,
@@ -1814,12 +1814,13 @@ linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
 		}
 
 		if (lcm->cmsg_type == -1 ||
-		    cm->cmsg_level != SOL_SOCKET) {
+		    cm->cmsg_level == -1) {
 			LINUX_RATELIMIT_MSG_OPT2(
 			    "unsupported recvmsg cmsg level %d type %d",
 			    cm->cmsg_level, cm->cmsg_type);
-			error = EINVAL;
-			goto bad;
+			/* Skip unsupported messages */
+			skiped++;
+			continue;
 		}
 
 		switch (cm->cmsg_type) {
@@ -1877,6 +1878,10 @@ err:
 		if (error != 0)
 			goto bad;
 	}
+	if (outlen == 0 && skiped > 0) {
+		error = EINVAL;
+		goto bad;
+	}
 	l_msghdr.msg_controllen = outlen;
 
 out: