From b8b6b8b498f47d92345456291bc08d96089c335b Mon Sep 17 00:00:00 2001 From: hanzj Date: Sat, 30 May 2026 23:50:45 +0800 Subject: [PATCH] arch/sim: Fix OOB read/write in usrsock_ioctl_handler usrsock_ioctl_handler() copies req->arglen bytes from the request payload into the fixed-size usrsock->out buffer without validating that the payload fits either the received request or the destination buffer. This is the same class of vulnerability as the one already fixed in nrf91_modem_sock.c (commit a43fb69283). Add three checks before the copy: - len >= sizeof(*req): ensure the full request header is present. - copylen <= len - sizeof(*req): payload must fit the received data. - copylen <= SIM_USRSOCK_BUFSIZE - sizeof(*ack): payload must fit the destination buffer. Signed-off-by: hanzj --- arch/sim/src/sim/sim_usrsock.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/sim/src/sim/sim_usrsock.c b/arch/sim/src/sim/sim_usrsock.c index 17ce01baa4e98..c8210d0336149 100644 --- a/arch/sim/src/sim/sim_usrsock.c +++ b/arch/sim/src/sim/sim_usrsock.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -357,15 +358,32 @@ static int usrsock_ioctl_handler(struct usrsock_s *usrsock, { const struct usrsock_request_ioctl_s *req = data; struct usrsock_message_datareq_ack_s *ack; + size_t copylen; int ret; + if (len < sizeof(*req)) + { + nerr("ERROR: ioctl request too short: %zu < %zu\n", + len, sizeof(*req)); + return -EINVAL; + } + + copylen = req->arglen; + if (copylen > len - sizeof(*req) || + copylen > SIM_USRSOCK_BUFSIZE - sizeof(*ack)) + { + nerr("ERROR: ioctl arglen invalid: %zu (len=%zu bufsize=%zu)\n", + copylen, len, (size_t)SIM_USRSOCK_BUFSIZE); + return -EINVAL; + } + ack = (struct usrsock_message_datareq_ack_s *)usrsock->out; - memcpy(ack + 1, req + 1, req->arglen); + memcpy(ack + 1, req + 1, copylen); ret = host_usrsock_ioctl(req->usockid, req->cmd, (unsigned long)(ack + 1)); return usrsock_send_dack(usrsock, ack, req->head.xid, ret, - req->arglen, req->arglen); + copylen, copylen); } static int usrsock_shutdown_handler(struct usrsock_s *usrsock,