From 09cfb46a6509eb22948ca3c60cde3bab2b821d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Alba=20Vives?= Date: Sun, 29 Mar 2026 07:11:11 +0000 Subject: [PATCH 1/4] staging: vc04_services: vchiq-mmal: validate component index in event_to_host_cb() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit event_to_host_cb() uses msg->u.event_to_host.client_component as an index into the instance->component[] array (size VCHIQ_MMAL_MAX_COMPONENTS = 64) without bounds validation. While the kernel generally trusts the hardware it is bound to, a bounds check here hardens the driver against potential firmware bugs that could otherwise cause an uncontrolled out-of-bounds array access and kernel crash. Add a bounds check on comp_idx before using it as an array index and move the component pointer assignment after the validation. Use pr_err_ratelimited() to avoid log flooding. Note: this file does not currently have access to a struct device, so dev_err() is not available. Cc: stable@vger.kernel.org Fixes: b18ee53ad297 ("staging: bcm2835: Break MMAL support out from camera") Signed-off-by: Sebastián Alba Vives --- drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 190d4808ffd90a..ec42af0ed45a0f 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -478,12 +478,19 @@ static void event_to_host_cb(struct vchiq_mmal_instance *instance, struct mmal_msg *msg, u32 msg_len) { int comp_idx = msg->u.event_to_host.client_component; - struct vchiq_mmal_component *component = - &instance->component[comp_idx]; + struct vchiq_mmal_component *component; struct vchiq_mmal_port *port = NULL; struct mmal_msg_context *msg_context; u32 port_num = msg->u.event_to_host.port_num; + if (comp_idx < 0 || comp_idx >= VCHIQ_MMAL_MAX_COMPONENTS) { + pr_err_ratelimited("%s: component index %d out of range\n", + __func__, comp_idx); + return; + } + + component = &instance->component[comp_idx]; + if (msg->u.buffer_from_host.drvbuf.magic == MMAL_MAGIC) { pr_err("%s: MMAL_MSG_TYPE_BUFFER_TO_HOST with bad magic\n", __func__); From d70dd9f17640daa925cfa4e061eb46d4462cf56f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Alba=20Vives?= Date: Sun, 29 Mar 2026 07:11:43 +0000 Subject: [PATCH 2/4] staging: vc04_services: vchiq-mmal: add buffer size check in inline_receive() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit inline_receive() copies payload data from a VCHIQ message into a destination buffer using payload_in_message as the copy length, but never validates that this length fits within the destination buffer (msg_context->u.bulk.buffer->buffer_size). While the caller validates payload_in_message <= MMAL_VC_SHORT_DATA (128) to prevent overreading the source, the destination buffer may be smaller than 128 bytes. This is inconsistent with bulk_receive() which does check buffer_size before copying. Add a bounds check against buffer_size and truncate the copy length if it exceeds the destination capacity, matching the defensive pattern used in bulk_receive(). Use pr_warn_ratelimited() for the truncation warning. Cc: stable@vger.kernel.org Fixes: b18ee53ad297 ("staging: bcm2835: Break MMAL support out from camera") Signed-off-by: Sebastián Alba Vives --- .../vc04_services/vchiq-mmal/mmal-vchiq.c | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index ec42af0ed45a0f..80a55ff0cadf48 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -369,12 +369,26 @@ static int inline_receive(struct vchiq_mmal_instance *instance, struct mmal_msg *msg, struct mmal_msg_context *msg_context) { + u32 payload_len = msg->u.buffer_from_host.payload_in_message; + + /* + * Ensure the payload fits within the destination buffer. + * The caller already validates payload_len <= MMAL_VC_SHORT_DATA + * against the source, but the destination buffer may be smaller. + * bulk_receive() performs this check; inline_receive() must too. + */ + if (payload_len > msg_context->u.bulk.buffer->buffer_size) { + payload_len = msg_context->u.bulk.buffer->buffer_size; + pr_warn_ratelimited("inline_receive: payload truncated (%u > %lu)\n", + msg->u.buffer_from_host.payload_in_message, + msg_context->u.bulk.buffer->buffer_size); + } + memcpy(msg_context->u.bulk.buffer->buffer, msg->u.buffer_from_host.short_data, - msg->u.buffer_from_host.payload_in_message); + payload_len); - msg_context->u.bulk.buffer_used = - msg->u.buffer_from_host.payload_in_message; + msg_context->u.bulk.buffer_used = payload_len; return 0; } From 2fcaebeeacb2a312f1a0a30f41240d82fc9c3721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Alba=20Vives?= Date: Sun, 29 Mar 2026 07:12:53 +0000 Subject: [PATCH 3/4] staging: vc04_services: vchiq-mmal: prevent stack overflow in port_parameter_set() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit port_parameter_set() copies value_size bytes from the caller-supplied value buffer into the stack-allocated struct mmal_msg's port_parameter_set.value field, which is u32[96] (384 bytes). There is no bounds check on value_size before the memcpy. While current in-tree callers pass small fixed-size structures, the function is exported via EXPORT_SYMBOL_GPL and accessible to any GPL kernel module. A caller passing value_size > 384 would overflow the stack-allocated mmal_msg structure. Add a bounds check rejecting value_size larger than the value field. Cc: stable@vger.kernel.org Fixes: b18ee53ad297 ("staging: bcm2835: Break MMAL support out from camera") Signed-off-by: Sebastián Alba Vives --- drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 80a55ff0cadf48..1fedd675311dbe 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -1363,6 +1363,14 @@ static int port_parameter_set(struct vchiq_mmal_instance *instance, struct mmal_msg *rmsg; struct vchiq_header *rmsg_handle; + if (value_size > + sizeof(m.u.port_parameter_set.value)) { + pr_err_ratelimited("port_parameter_set: value_size %u exceeds max %zu\n", + value_size, + sizeof(m.u.port_parameter_set.value)); + return -EINVAL; + } + m.h.type = MMAL_MSG_TYPE_PORT_PARAMETER_SET; m.u.port_parameter_set.component_handle = port->component->handle; From 1806494a5bff18b79f1e1ed2009b94614724094d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Alba=20Vives?= Date: Sun, 29 Mar 2026 07:13:21 +0000 Subject: [PATCH 4/4] staging: vc04_services: vchiq-mmal: fix integer underflow in port_parameter_get() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit port_parameter_get() subtracts 2 * sizeof(u32) from the VideoCore firmware's reply size field to compute the parameter value size. If the firmware returns a size smaller than 8, the subtraction wraps around to a large value due to unsigned integer underflow. The underflowed size is then used in a comparison that selects the wrong copy path and stored back to the caller via *value_size, propagating a bogus size to subsequent operations. Add a minimum size check before the subtraction and return -EPROTO if the reply is malformed. Cc: stable@vger.kernel.org Fixes: b18ee53ad297 ("staging: bcm2835: Break MMAL support out from camera") Signed-off-by: Sebastián Alba Vives --- drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 1fedd675311dbe..d1dc509b9b223a 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -1438,6 +1438,10 @@ static int port_parameter_get(struct vchiq_mmal_instance *instance, /* port_parameter_get_reply.size includes the header, * whilst *value_size doesn't. */ + if (rmsg->u.port_parameter_get_reply.size < (2 * sizeof(u32))) { + ret = -EPROTO; + goto release_msg; + } rmsg->u.port_parameter_get_reply.size -= (2 * sizeof(u32)); if (ret || rmsg->u.port_parameter_get_reply.size > *value_size) {