This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 2777d0d058a net/socket: validate msg_iovlen against IOV_MAX and 
non-zero in sendmsg/recvmsg
2777d0d058a is described below

commit 2777d0d058a78a78ac0a1392612f8a651b97e818
Author: Swatantra Yadav <[email protected]>
AuthorDate: Sat Nov 7 14:14:10 2026 +0530

    net/socket: validate msg_iovlen against IOV_MAX and non-zero in 
sendmsg/recvmsg
    
    POSIX IEEE Std 1003.1 explicitly specifies for both sendmsg() and recvmsg():
    "[EMSGSIZE] The msg_iovlen member of the msghdr structure is less than
    or equal to 0 or is greater than {IOV_MAX}."
    
    Neither psock_sendmsg() nor psock_recvmsg() validated msg->msg_iovlen.
    Passing msg_iovlen = 0 or msg_iovlen > IOV_MAX caused:
    1. In psock_recvmsg(), dereferencing msg->msg_iov->iov_base on an empty
       iovec array, or returning -EINVAL instead of the mandated -EMSGSIZE.
    2. In net/usrsock (usrsock_sendmsg.c), allocating an unbounded variable-
       length array on the kernel stack (struct iovec bufs[2 + 
msg->msg_iovlen]),
       leading to kernel stack overflow when msg_iovlen is large.
    3. In net/local (local_sendmsg.c) and net/rpmsg (rpmsg_sockif.c),
       executing zero-length loops, sending empty preambles, or unhandled
       states.
    4. Requiring individual lower-level drivers (inet, can, local_recvmsg) to
       redundantly duplicate ad-hoc checks for msg->msg_iovlen == 0.
    
    This patch adds upfront validation of msg->msg_iovlen against 0 and
    IOV_MAX in psock_sendmsg() and psock_recvmsg(), returning -EMSGSIZE on
    violation, while also ensuring psock is verified before dereferencing
    psock->s_type.
    
    Assisted-by: Google Gemini:gemini-3.8-flash
    Signed-off-by: Swatantra Yadav <[email protected]>
---
 net/socket/recvmsg.c | 25 +++++++++++++++++++------
 net/socket/sendmsg.c | 23 ++++++++++++++++++-----
 2 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/net/socket/recvmsg.c b/net/socket/recvmsg.c
index 9543c6b6f6e..318b63c34a1 100644
--- a/net/socket/recvmsg.c
+++ b/net/socket/recvmsg.c
@@ -28,6 +28,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <limits.h>
 
 #include <nuttx/cancelpt.h>
 #include <nuttx/fs/fs.h>
@@ -76,23 +77,35 @@ ssize_t psock_recvmsg(FAR struct socket *psock, FAR struct 
msghdr *msg,
   FAR void *msg_control;
   int ret;
 
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (psock == NULL || psock->s_conn == NULL)
+    {
+      return -EBADF;
+    }
+
   /* Verify that non-NULL pointers were passed */
 
-  if (msg == NULL || msg->msg_iov == NULL || msg->msg_iov->iov_base == NULL)
+  if (msg == NULL)
     {
       return -EINVAL;
     }
 
-  if (msg->msg_name != NULL && msg->msg_namelen <= 0)
+  /* POSIX: fail with EMSGSIZE if msg_iovlen <= 0 or > IOV_MAX */
+
+  if (msg->msg_iovlen == 0 || msg->msg_iovlen > IOV_MAX)
     {
-      return -EINVAL;
+      return -EMSGSIZE;
     }
 
-  /* Verify that the sockfd corresponds to valid, allocated socket */
+  if (msg->msg_iov == NULL || msg->msg_iov->iov_base == NULL)
+    {
+      return -EINVAL;
+    }
 
-  if (psock == NULL || psock->s_conn == NULL)
+  if (msg->msg_name != NULL && msg->msg_namelen <= 0)
     {
-      return -EBADF;
+      return -EINVAL;
     }
 
   /* Let logic specific to this address family handle the recvmsg()
diff --git a/net/socket/sendmsg.c b/net/socket/sendmsg.c
index 7ead5ca11b5..36aab568d67 100644
--- a/net/socket/sendmsg.c
+++ b/net/socket/sendmsg.c
@@ -29,6 +29,7 @@
 #include <sys/socket.h>
 #include <assert.h>
 #include <errno.h>
+#include <limits.h>
 #include <signal.h>
 
 #include <nuttx/cancelpt.h>
@@ -76,19 +77,31 @@
 ssize_t psock_sendmsg(FAR struct socket *psock, FAR const struct msghdr *msg,
                        int flags)
 {
+  /* Verify that the sockfd corresponds to valid, allocated socket */
+
+  if (psock == NULL || psock->s_conn == NULL)
+    {
+      return -EBADF;
+    }
+
   /* Verify that non-NULL pointers were passed */
 
-  if (msg == NULL || msg->msg_iov == NULL ||
-      (psock->s_type != SOCK_DGRAM && msg->msg_iov->iov_base == NULL))
+  if (msg == NULL)
     {
       return -EINVAL;
     }
 
-  /* Verify that the sockfd corresponds to valid, allocated socket */
+  /* POSIX: fail with EMSGSIZE if msg_iovlen <= 0 or > IOV_MAX */
 
-  if (psock == NULL || psock->s_conn == NULL)
+  if (msg->msg_iovlen == 0 || msg->msg_iovlen > IOV_MAX)
     {
-      return -EBADF;
+      return -EMSGSIZE;
+    }
+
+  if (msg->msg_iov == NULL ||
+      (psock->s_type != SOCK_DGRAM && msg->msg_iov->iov_base == NULL))
+    {
+      return -EINVAL;
     }
 
   /* Let logic specific to this address family handle the sendmsg()

Reply via email to