net/bluetooth/hci_event.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
There is a BUG: KMSAN: uninit-value in hci_cmd_complete_evt() due to a
malformed HCI event packet received from userspace.
The existing code in hci_event_packet() checks that the buffer is large
enough to contain the event header, and checks that the hdr's Event Code
is valid, but does not check the hdr's Parameter Total Length. So,
syzbot’s event packet passes through and uses the un-init values in
hci_event_func() => hci_cmd_complete_evt().
Reported-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a9a4bedfca6aa9d7fa24
Tested-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
Fixes: a9de9248064bf ("[Bluetooth] Switch from OGF+OCF to using only opcodes")
Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
---
net/bluetooth/hci_event.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d790b0d4eb9a..5e1498cc04cd 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -7565,7 +7565,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_req_complete_t req_complete = NULL;
hci_req_complete_skb_t req_complete_skb = NULL;
struct sk_buff *orig_skb = NULL;
- u8 status = 0, event, req_evt = 0;
+ u8 status = 0, event, req_evt = 0, len;
u16 opcode = HCI_OP_NOP;
if (skb->len < sizeof(*hdr)) {
@@ -7585,6 +7585,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
goto done;
}
+ len = hdr->plen;
+ if (len != skb->len - HCI_EVENT_HDR_SIZE) {
+ bt_dev_warn(hdev, "Unexpected HCI Parameter Length 0x%2.2x",
+ len);
+ goto done;
+ }
+
/* Only match event if command OGF is not for LE */
if (hdev->req_skb &&
hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
--
2.43.0
Hi Raphael,
On Wed, Oct 22, 2025 at 6:38 PM Raphael Pinsonneault-Thibeault
<rpthibeault@gmail.com> wrote:
>
> There is a BUG: KMSAN: uninit-value in hci_cmd_complete_evt() due to a
> malformed HCI event packet received from userspace.
>
> The existing code in hci_event_packet() checks that the buffer is large
> enough to contain the event header, and checks that the hdr's Event Code
> is valid, but does not check the hdr's Parameter Total Length. So,
> syzbot’s event packet passes through and uses the un-init values in
> hci_event_func() => hci_cmd_complete_evt().
It does checks the length:
if (skb->len < ev->min_len) {
bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
event, skb->len, ev->min_len);
return;
}
> Reported-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=a9a4bedfca6aa9d7fa24
> Tested-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
> Fixes: a9de9248064bf ("[Bluetooth] Switch from OGF+OCF to using only opcodes")
> Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
> ---
> net/bluetooth/hci_event.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index d790b0d4eb9a..5e1498cc04cd 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -7565,7 +7565,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
> hci_req_complete_t req_complete = NULL;
> hci_req_complete_skb_t req_complete_skb = NULL;
> struct sk_buff *orig_skb = NULL;
> - u8 status = 0, event, req_evt = 0;
> + u8 status = 0, event, req_evt = 0, len;
> u16 opcode = HCI_OP_NOP;
>
> if (skb->len < sizeof(*hdr)) {
> @@ -7585,6 +7585,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
> goto done;
> }
>
> + len = hdr->plen;
> + if (len != skb->len - HCI_EVENT_HDR_SIZE) {
> + bt_dev_warn(hdev, "Unexpected HCI Parameter Length 0x%2.2x",
> + len);
> + goto done;
> + }
Looks like a big hammer for a uninitialized value, which I assume is
from the following code:
if (i == ARRAY_SIZE(hci_cc_table)) {
/* Unknown opcode, assume byte 0 contains the status, so
* that e.g. __hci_cmd_sync() properly returns errors
* for vendor specific commands send by HCI drivers.
* If a vendor doesn't actually follow this convention we may
* need to introduce a vendor CC table in order to properly set
* the status.
*/
*status = skb->data[0];
}
That one is accessing skb->data without first checking it like
hci_cc_skb_pull like all other event handlers are doing, if that is
really the case then something like the following should make it go
away:
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index bae8c219341a..e71fbdebffae 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4219,6 +4219,13 @@ static void hci_cmd_complete_evt(struct hci_dev
*hdev, void *data,
}
if (i == ARRAY_SIZE(hci_cc_table)) {
+ if (!skb->len) {
+ bt_dev_err(hdev, "unexpected cc 0x%4.4x with no status",
+ *opcode);
+ *status = HCI_ERROR_UNSPECIFIED;
+ return;
+ }
+
/* Unknown opcode, assume byte 0 contains the status, so
* that e.g. __hci_cmd_sync() properly returns errors
* for vendor specific commands send by HCI drivers.
> +
> /* Only match event if command OGF is not for LE */
> if (hdev->req_skb &&
> hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
> --
> 2.43.0
>
--
Luiz Augusto von Dentz
In hci_cmd_complete_evt(), if the command complete event has an unknown
opcode, we assume the first byte of the remaining skb->data contains the
return status. However, parameter data has previously been pulled in
hci_event_func(), which may leave the skb empty. If so, using skb->data[0]
for the return status uses un-init memory.
The fix is to check skb->len before using skb->data.
Reported-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a9a4bedfca6aa9d7fa24
Tested-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
Fixes: afcb3369f46ed ("Bluetooth: hci_event: Fix vendor (unknown) opcode status handling")
Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
---
changes in v2:
- check skb->len before accessing skb->data in hci_cmd_complete_evt().
- remove v1\ufffd\ufffd\ufffds changes
- update commit message and Fixes tag
Thank you for the response Luiz. I didn\ufffd\ufffd\ufffdt want to spam you or the ML
with another reply since you were very clear.
net/bluetooth/hci_event.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index d790b0d4eb9a..d2ac95a824db 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -4211,6 +4211,13 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
}
if (i == ARRAY_SIZE(hci_cc_table)) {
+ if (!skb->len) {
+ bt_dev_err(hdev, "Unexpected cc 0x%4.4x with no status",
+ *opcode);
+ *status = HCI_ERROR_UNSPECIFIED;
+ return;
+ }
+
/* Unknown opcode, assume byte 0 contains the status, so
* that e.g. __hci_cmd_sync() properly returns errors
* for vendor specific commands send by HCI drivers.
--
2.43.0
On Wed, Oct 22, 2025 at 06:34:16PM -0400, Raphael Pinsonneault-Thibeault wrote:
> There is a BUG: KMSAN: uninit-value in hci_cmd_complete_evt() due to a
> malformed HCI event packet received from userspace.
>
> The existing code in hci_event_packet() checks that the buffer is large
> enough to contain the event header, and checks that the hdr's Event Code
> is valid, but does not check the hdr's Parameter Total Length. So,
> syzbot’s event packet passes through and uses the un-init values in
> hci_event_func() => hci_cmd_complete_evt().
>
> Reported-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=a9a4bedfca6aa9d7fa24
> Tested-by: syzbot+a9a4bedfca6aa9d7fa24@syzkaller.appspotmail.com
> Fixes: a9de9248064bf ("[Bluetooth] Switch from OGF+OCF to using only opcodes")
> Signed-off-by: Raphael Pinsonneault-Thibeault <rpthibeault@gmail.com>
> ---
> net/bluetooth/hci_event.c | 9 ++++++++-
> 1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index d790b0d4eb9a..5e1498cc04cd 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -7565,7 +7565,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
> hci_req_complete_t req_complete = NULL;
> hci_req_complete_skb_t req_complete_skb = NULL;
> struct sk_buff *orig_skb = NULL;
> - u8 status = 0, event, req_evt = 0;
> + u8 status = 0, event, req_evt = 0, len;
> u16 opcode = HCI_OP_NOP;
>
> if (skb->len < sizeof(*hdr)) {
> @@ -7585,6 +7585,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
> goto done;
> }
>
> + len = hdr->plen;
> + if (len != skb->len - HCI_EVENT_HDR_SIZE) {
> + bt_dev_warn(hdev, "Unexpected HCI Parameter Length 0x%2.2x",
> + len);
> + goto done;
> + }
> +
> /* Only match event if command OGF is not for LE */
> if (hdev->req_skb &&
> hci_opcode_ogf(hci_skb_opcode(hdev->req_skb)) != 0x08 &&
> --
> 2.43.0
>
>
Hi,
This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him
a patch that has triggered this response. He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created. Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.
You are receiving this message because of the following common error(s)
as indicated below:
- You have marked a patch with a "Fixes:" tag for a commit that is in an
older released kernel, yet you do not have a cc: stable line in the
signed-off-by area at all, which means that the patch will not be
applied to any older kernel releases. To properly fix this, please
follow the documented rules in the
Documentation/process/stable-kernel-rules.rst file for how to resolve
this.
If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.
thanks,
greg k-h's patch email bot
© 2016 - 2026 Red Hat, Inc.