From a43fb69283d28cd1ce38a665b0b78472b31378c6 Mon Sep 17 00:00:00 2001 From: hanzj Date: Sat, 30 May 2026 23:12:07 +0800 Subject: [PATCH] arch/arm/nrf91: Fix OOB read/write in nrf91_usrsock_ioctl_handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nrf91_usrsock_ioctl_handler() copies req->arglen bytes from the request payload into the fixed-size usrsock->out buffer without validating that the payload actually fits either the received request or the destination buffer. A crafted ioctl request with an inflated arglen triggers: 1. OOB read — memcpy reads past the end of the received request. 2. OOB write — memcpy writes past the end of usrsock->out. 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 <= sizeof(usrsock->out) - sizeof(*ack): payload must fit the destination buffer. The recvfrom handler in the same file already performs the equivalent buffer-size check (line 892). Fixes #18515. Signed-off-by: hanzj --- arch/arm/src/nrf91/nrf91_modem_sock.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/nrf91/nrf91_modem_sock.c b/arch/arm/src/nrf91/nrf91_modem_sock.c index b6f22c271bb7b..e6d260e66428a 100644 --- a/arch/arm/src/nrf91/nrf91_modem_sock.c +++ b/arch/arm/src/nrf91/nrf91_modem_sock.c @@ -1111,16 +1111,29 @@ static int nrf91_usrsock_ioctl_handler(struct nrf91_usrsock_s *usrsock, { const struct usrsock_request_ioctl_s *req = data; struct usrsock_message_datareq_ack_s *ack = NULL; + size_t copylen; int ret = 0; + if (len < sizeof(*req)) + { + return -EINVAL; + } + ack = (struct usrsock_message_datareq_ack_s *)usrsock->out; - memcpy(ack + 1, req + 1, req->arglen); + copylen = req->arglen; + if (copylen > len - sizeof(*req) || + copylen > sizeof(usrsock->out) - sizeof(*ack)) + { + return -EINVAL; + } + + memcpy(ack + 1, req + 1, copylen); ret = nrf91_usrsock_ioctl(req->usockid, req->cmd, (unsigned long)(ack + 1)); return nrf91_usrsock_send_dack(usrsock, ack, req->head.xid, ret, - req->arglen, req->arglen); + copylen, copylen); } /****************************************************************************