drivers/greybus/operation.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
gb_connection_recv() accepts a received message whose advertised size is
smaller than struct gb_operation_msg_hdr. In particular, a header with a
size of zero passes the incomplete-message check and reaches
gb_operation_create_incoming().
The subtraction used to derive the request payload size then underflows.
When gb_operation_message_alloc() adds the header size, the result wraps
to zero, bypassing the maximum-buffer-size check. kzalloc(0) returns
ZERO_SIZE_PTR and gb_operation_message_init() subsequently dereferences
it.
Reject advertised sizes smaller than the message header. Also check the
payload size before adding the header size, so that the size calculation
cannot wrap and bypass the buffer-size limit.
This issue was found using a locally modified syzkaller. The
analysis and fix were assisted by GPT-5.6.
Fixes: d90c25b0a279 ("greybus: let operation layer examine incoming data")
Assisted-by: Codex:gpt-5.6
Signed-off-by: Yang Zi <2959243019@qq.com>
---
drivers/greybus/operation.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/greybus/operation.c b/drivers/greybus/operation.c
index 7e12ffb2dd60..47d67c681fc4 100644
--- a/drivers/greybus/operation.c
+++ b/drivers/greybus/operation.c
@@ -364,13 +364,14 @@ gb_operation_message_alloc(struct gb_host_device *hd, u8 type,
{
struct gb_message *message;
struct gb_operation_msg_hdr *header;
- size_t message_size = payload_size + sizeof(*header);
+ size_t message_size;
- if (message_size > hd->buffer_size_max) {
- dev_warn(&hd->dev, "requested message size too big (%zu > %zu)\n",
- message_size, hd->buffer_size_max);
+ if (payload_size > hd->buffer_size_max - sizeof(*header)) {
+ dev_warn(&hd->dev, "requested payload size too big (%zu > %zu)\n",
+ payload_size, hd->buffer_size_max - sizeof(*header));
return NULL;
}
+ message_size = payload_size + sizeof(*header);
/* Allocate the message structure and buffer. */
message = kmem_cache_zalloc(gb_message_cache, gfp_flags);
@@ -1047,6 +1048,11 @@ void gb_connection_recv(struct gb_connection *connection,
/* Use memcpy as data may be unaligned */
memcpy(&header, data, sizeof(header));
msg_size = le16_to_cpu(header.size);
+ if (msg_size < sizeof(header)) {
+ dev_err_ratelimited(dev, "%s: short message received (%zu < %zu)\n",
+ connection->name, msg_size, sizeof(header));
+ return;
+ }
if (size < msg_size) {
dev_err_ratelimited(dev,
"%s: incomplete message 0x%04x of type 0x%02x received (%zu < %zu)\n",
--
2.55.0
On Fri, Sep 04, 2026 at 04:08:20PM +0800, Yang Zi wrote:
> gb_connection_recv() accepts a received message whose advertised size is
> smaller than struct gb_operation_msg_hdr. In particular, a header with a
> size of zero passes the incomplete-message check and reaches
> gb_operation_create_incoming().
>
> The subtraction used to derive the request payload size then underflows.
> When gb_operation_message_alloc() adds the header size, the result wraps
> to zero, bypassing the maximum-buffer-size check. kzalloc(0) returns
> ZERO_SIZE_PTR and gb_operation_message_init() subsequently dereferences
> it.
>
> Reject advertised sizes smaller than the message header. Also check the
> payload size before adding the header size, so that the size calculation
> cannot wrap and bypass the buffer-size limit.
>
> This issue was found using a locally modified syzkaller. The
> analysis and fix were assisted by GPT-5.6.
>
> Fixes: d90c25b0a279 ("greybus: let operation layer examine incoming data")
This one should also be backported:
Cc: stable@vger.kernel.org
> Assisted-by: Codex:gpt-5.6
> Signed-off-by: Yang Zi <2959243019@qq.com>
> ---
You should put a short change log here (after ---) when revising
patches.
No need to resend this time, but keep in mind for the future.
Reviewed-by: Johan Hovold <johan@kernel.org>
Johan
© 2016 - 2026 Red Hat, Inc.