CVE-2026-46016
Description
In the Linux kernel, the following vulnerability has been resolved:
remoteproc: xlnx: Only access buffer information if IPI is buffered
In the receive callback check if message is NULL to prevent possibility of crash by NULL pointer dereferencing.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A NULL-pointer dereference vulnerability in the Linux kernel's Xilinx remoteproc driver can be triggered when receiving a non-buffered IPI message.
Vulnerability
In the Linux kernel, a vulnerability exists in the xlnx remoteproc driver's receive callback (CVE-2026-46016). The issue is that the code does not properly check if the received message is NULL before accessing its buffer information when Inter-Processor Interrupt (IPI) messages are not buffered. This can lead to a NULL pointer dereference crash. The affected versions are those prior to the patch commit 5d1451cb2cf6 [1].
Exploitation
An attacker needs to be able to send a crafted IPI message to a system using the Xilinx remoteproc driver. The message must be of a type that is not buffered, causing the receive callback to attempt to access data from a NULL pointer. No authentication or special privileges are required from the attacker if they can communicate over the relevant hardware interface (e.g., from a remote processor or through a local application that can trigger the IPI).
Impact
Successful exploitation results in a kernel NULL pointer dereference, leading to a denial of service (system crash or hang). The impact is limited to availability; there is no information disclosure or privilege escalation indicated.
Mitigation
The vulnerability is fixed in Linux kernel commit 5d1451cb2cf6 [1]. Users should apply the patch or update to a kernel version that includes this commit. No workaround is documented in the reference.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
1006d0bed2552fremoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index 0b7b173d0d260a..b30f660a1c5532 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
5d1451cb2cf6remoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index feca6de68da28e..425b905dc86dc2 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -179,17 +179,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
8242579859a7remoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index b71ce69afe9f41..f949749e50b0cc 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
38dd6ccfdfbbremoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index 148d8c622566dd..5e92dc51f1c082 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
7ddbf2111677remoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index c165422d06516b..6a64e5909f6ae2 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
8242579859a7remoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index b71ce69afe9f41..f949749e50b0cc 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
5d1451cb2cf6remoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index feca6de68da28e..425b905dc86dc2 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -179,17 +179,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
06d0bed2552fremoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index 0b7b173d0d260a..b30f660a1c5532 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
38dd6ccfdfbbremoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index 148d8c622566dd..5e92dc51f1c082 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
7ddbf2111677remoteproc: xlnx: Only access buffer information if IPI is buffered
1 file changed · +11 −10
drivers/remoteproc/xlnx_r5_remoteproc.c+11 −10 modifieddiff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index c165422d06516b..6a64e5909f6ae2 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -232,17 +232,19 @@ static void zynqmp_r5_mb_rx_cb(struct mbox_client *cl, void *msg) ipi = container_of(cl, struct mbox_info, mbox_cl); - /* copy data from ipi buffer to r5_core */ + /* copy data from ipi buffer to r5_core if IPI is buffered. */ ipi_msg = (struct zynqmp_ipi_message *)msg; - buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; - len = ipi_msg->len; - if (len > IPI_BUF_LEN_MAX) { - dev_warn(cl->dev, "msg size exceeded than %d\n", - IPI_BUF_LEN_MAX); - len = IPI_BUF_LEN_MAX; + if (ipi_msg) { + buf_msg = (struct zynqmp_ipi_message *)ipi->rx_mc_buf; + len = ipi_msg->len; + if (len > IPI_BUF_LEN_MAX) { + dev_warn(cl->dev, "msg size exceeded than %d\n", + IPI_BUF_LEN_MAX); + len = IPI_BUF_LEN_MAX; + } + buf_msg->len = len; + memcpy(buf_msg->data, ipi_msg->data, len); } - buf_msg->len = len; - memcpy(buf_msg->data, ipi_msg->data, len); /* received and processed interrupt ack */ if (mbox_send_message(ipi->rx_chan, NULL) < 0) -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing NULL-pointer check in the mailbox receive callback allows dereferencing a NULL message pointer when IPI is unbuffered."
Attack vector
An attacker who can send a mailbox message to a Xilinx ZynqMP R5 remoteproc instance may trigger the `zynqmp_r5_mb_rx_cb` callback with a NULL `msg` pointer. The original code unconditionally cast `msg` to `struct zynqmp_ipi_message *` and then accessed `ipi_msg->len`, causing a NULL-pointer dereference and kernel crash. This can be achieved by sending an unbuffered IPI message to the target R5 core via the mailbox subsystem [patch_id=2660413].
Affected code
The vulnerable function is `zynqmp_r5_mb_rx_cb` in `drivers/remoteproc/xlnx_r5_remoteproc.c` [patch_id=2660413]. The fault lies in the unconditional cast of the `msg` parameter to `struct zynqmp_ipi_message *` followed by `ipi_msg->len` access without a NULL check.
What the fix does
The patch wraps the buffer-copy logic inside an `if (ipi_msg)` guard so that `ipi_msg->len` and `memcpy` are only reached when `msg` is non-NULL [patch_id=2660413]. If the message pointer is NULL, the callback now skips the copy and proceeds directly to the interrupt-acknowledgment step. This prevents the NULL-pointer dereference that previously occurred when an unbuffered IPI was received.
Preconditions
- configThe system must use the Xilinx ZynqMP remoteproc driver with mailbox-based IPI communication.
- inputAn attacker must be able to send a mailbox message (or trigger the receive callback) with a NULL message pointer to the target R5 core.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/06d0bed2552fd0dae27d374d4492a2b672e24eednvd
- git.kernel.org/stable/c/38dd6ccfdfbbe865569a52fe1ba9fa1478f672e6nvd
- git.kernel.org/stable/c/5d1451cb2cf6f3d9884d76035a1460aa9bb4b053nvd
- git.kernel.org/stable/c/7ddbf21116770b7011f2bb0a6056b7604b24c497nvd
- git.kernel.org/stable/c/8242579859a78c801bb626e9aa4823aca93e28e7nvd
News mentions
0No linked articles in our index yet.