mirror of
https://github.com/apache/nuttx.git
synced 2026-09-22 22:55:02 +08:00
arch/arm/nrf91: Fix OOB read/write in nrf91_usrsock_ioctl_handler
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 <hanzjian@zepp.com>
This commit is contained in:
@@ -1111,16 +1111,29 @@ static int nrf91_usrsock_ioctl_handler(struct nrf91_usrsock_s *usrsock,
|
|||||||
{
|
{
|
||||||
const struct usrsock_request_ioctl_s *req = data;
|
const struct usrsock_request_ioctl_s *req = data;
|
||||||
struct usrsock_message_datareq_ack_s *ack = NULL;
|
struct usrsock_message_datareq_ack_s *ack = NULL;
|
||||||
|
size_t copylen;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (len < sizeof(*req))
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
ack = (struct usrsock_message_datareq_ack_s *)usrsock->out;
|
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,
|
ret = nrf91_usrsock_ioctl(req->usockid,
|
||||||
req->cmd,
|
req->cmd,
|
||||||
(unsigned long)(ack + 1));
|
(unsigned long)(ack + 1));
|
||||||
|
|
||||||
return nrf91_usrsock_send_dack(usrsock, ack, req->head.xid, ret,
|
return nrf91_usrsock_send_dack(usrsock, ack, req->head.xid, ret,
|
||||||
req->arglen, req->arglen);
|
copylen, copylen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
Reference in New Issue
Block a user