git: 755b9d539325 - main - ng_hci: build the devd notification in a stack buffer

From: Abdelkader Boudih <seuros_at_FreeBSD.org>
Date: Thu, 10 Sep 2026 15:25:30 UTC
The branch main has been updated by seuros:

URL: https://cgit.FreeBSD.org/src/commit/?id=755b9d5393253e1d5d3f9a894c18ac8bedb39b5d

commit 755b9d5393253e1d5d3f9a894c18ac8bedb39b5d
Author:     Abdelkader Boudih <seuros@FreeBSD.org>
AuthorDate: 2026-09-10 15:25:16 +0000
Commit:     Abdelkader Boudih <seuros@FreeBSD.org>
CommitDate: 2026-09-10 15:25:16 +0000

    ng_hci: build the devd notification in a stack buffer
    
    sbuf_new_auto() sleeps, and ng_hci_default_rcvmsg() can run under the
    raw HCI socket pcb mutex held across NG_SEND_MSG_PATH().
    
    Reported by:    WITNESS
    Fixes:          ad91d47db306
    
    Reviewed by:    glebius, adrian
    Differential Revision:  https://reviews.freebsd.org/D59550
---
 sys/netgraph/bluetooth/hci/ng_hci_main.c | 77 +++++++++++---------------------
 1 file changed, 26 insertions(+), 51 deletions(-)

diff --git a/sys/netgraph/bluetooth/hci/ng_hci_main.c b/sys/netgraph/bluetooth/hci/ng_hci_main.c
index 190cb80a1c4c..5ddbb940b1ca 100644
--- a/sys/netgraph/bluetooth/hci/ng_hci_main.c
+++ b/sys/netgraph/bluetooth/hci/ng_hci_main.c
@@ -126,6 +126,29 @@ ng_hci_append_bdaddr_to_sbuf(struct sbuf *sb, const bdaddr_t *ba)
 		ba->b[2], ba->b[1], ba->b[0]);
 } /* ng_hci_append_bdaddr_to_sbuf */
 
+static void
+ng_hci_notify_devd(node_p node, ng_hci_unit_p unit, const char *event)
+{
+	char		buf[NG_NODESIZ + 32];
+	struct sbuf	sb;
+
+	sbuf_new(&sb, buf, sizeof(buf), SBUF_FIXEDLEN);
+	sbuf_printf(&sb, "node=%s bdaddr=", NG_NODE_NAME(node));
+	ng_hci_append_bdaddr_to_sbuf(&sb, &unit->bdaddr);
+	sbuf_printf(&sb, "\n");
+
+	if (sbuf_finish(&sb) != 0)
+		log(LOG_WARNING,
+		    "hci: failed to signal %s to devd: "
+		    "%02x:%02x:%02x:%02x:%02x:%02x\n", event,
+		    unit->bdaddr.b[5], unit->bdaddr.b[4], unit->bdaddr.b[3],
+		    unit->bdaddr.b[2], unit->bdaddr.b[1], unit->bdaddr.b[0]);
+	else
+		devctl_notify("BLUETOOTH", "HCI", event, sbuf_data(&sb));
+
+	sbuf_delete(&sb);
+}
+
 /*****************************************************************************
  *****************************************************************************
  **                   Netgraph methods implementation
@@ -286,29 +309,7 @@ ng_hci_disconnect(hook_p hook)
 		unit->state &= ~(NG_HCI_UNIT_CONNECTED|NG_HCI_UNIT_INITED);
 
 		/* Signal power off to devd */
-		{
-			struct sbuf *sb;
-			sb = sbuf_new_auto();
-			sbuf_printf(sb, "node=%s bdaddr=",
-			    NG_NODE_NAME(NG_HOOK_NODE(hook)));
-			ng_hci_append_bdaddr_to_sbuf(sb, &unit->bdaddr);
-			sbuf_printf(sb, "\n");
-
-			if (sbuf_finish(sb) > 0) {
-				log(LOG_WARNING,
-					"hci: failed to signal bt device " \
-					"power off to devd: " \
-					"%02x:%02x:%02x:%02x:%02x:%02x\n",
-					unit->bdaddr.b[5], unit->bdaddr.b[4],
-					unit->bdaddr.b[3], unit->bdaddr.b[2],
-					unit->bdaddr.b[1], unit->bdaddr.b[0]);
-			} else {
-				devctl_notify("BLUETOOTH", "HCI",
-				    "POWERED_OFF", sbuf_data(sb));
-			}
-
-			sbuf_delete(sb);
-		}
+		ng_hci_notify_devd(NG_HOOK_NODE(hook), unit, "POWERED_OFF");
 	} else
 		return (EINVAL);
 
@@ -413,34 +414,8 @@ ng_hci_default_rcvmsg(node_p node, item_p item, hook_p lasthook)
 			ng_hci_node_is_up(unit->node, unit->acl, NULL, 0);
 			ng_hci_node_is_up(unit->node, unit->sco, NULL, 0);
 
-			 /* Signal init to devd */
-			{
-				struct sbuf *sb;
-				sb = sbuf_new_auto();
-				sbuf_printf(sb, "node=%s bdaddr=",
-				    NG_NODE_NAME(node));
-				ng_hci_append_bdaddr_to_sbuf(sb,
-				    &unit->bdaddr);
-				sbuf_printf(sb, "\n");
-
-				if (sbuf_finish(sb) > 0) {
-					log(LOG_WARNING,
-						"hci: failed to signal bt " \
-						"device init to devd: "
-						"%02x:%02x:%02x:%02x:%02x:%02x\n",
-						unit->bdaddr.b[5],
-						unit->bdaddr.b[4],
-						unit->bdaddr.b[3],
-						unit->bdaddr.b[2],
-						unit->bdaddr.b[1],
-						unit->bdaddr.b[0]);
-				} else {
-					devctl_notify("BLUETOOTH", "HCI",
-					    "INITIALIZED", sbuf_data(sb));
-				}
-
-				sbuf_delete(sb);
-			}
+			/* Signal init to devd */
+			ng_hci_notify_devd(node, unit, "INITIALIZED");
 
 			break;