/*
 * DF-0625 — ng_l2cap L2CA_Ping missing arglen check (kernel heap OOB read).
 *
 * Trigger path (when ng_l2cap is loaded + a BT lower layer/HCI is connected):
 *
 *   socket(AF_NETGRAPH, ...)
 *   bind to a node, connect to "l2cap" hook
 *   send NGM_L2CAP_L2CA_PING control message with:
 *     - arglen = 8                          (just the ng_l2cap_l2ca_ping_ip header)
 *     - ip->echo_size = 200                 (claimed echo payload size)
 *     - ip->bdaddr  = remote BT addr        (attacker-controlled peer)
 *
 * Expected on vulnerable kernel + with BT HCI lower layer attached:
 *   - ng_l2cap_l2ca_ping_req passes the `arglen < sizeof(*ip)` check (:1306)
 *   - passes the `echo_size <= MAX` check (:1316)
 *   - reaches _ng_l2cap_echo_req at :1357 with msg->data+8 and size=200
 *   - m_copyback reads 200 bytes from msg->data+8 into a fresh mbuf
 *     (msg was allocated as sizeof(ng_mesg)+8, so the read runs ~192 bytes
 *      past the allocation into adjacent kernel heap)
 *   - the mbuf is queued to the BT lower layer and transmitted as an
 *     L2CAP Echo Request to ip->bdaddr  -> kernel heap info leak over the air
 *
 * WHY THIS PoC DOES NOT FIRE ON THE AUDIT GUEST:
 *
 *   1. The audit guest has NO Bluetooth hardware and no ng_hci/ng_ubt lower
 *      layer. Without an HCI hook connected to the l2cap node, the bug path
 *      at ulpi.c:1357 is unreachable:
 *
 *         ulpi.c:1325   con = ng_l2cap_con_by_addr(l2cap, &ip->bdaddr); // NULL
 *         ulpi.c:1328   error = ng_l2cap_lp_con_req(l2cap, &ip->bdaddr);
 *         llpi.c:87-92  if (l2cap->hci == NULL) return ENOTCONN;
 *         ulpi.c:1329   if (error != 0) goto out;        // takes the early out
 *
 *      The function returns ENOTCONN long before reaching the buggy
 *      _ng_l2cap_echo_req call. The OOB read cannot occur.
 *
 *   2. ng_l2cap.ko is also not loadable on this guest: ng_l2cap declares
 *      MODULE_DEPEND on netgraph (NG_ABI_VERSION), and the pre-installed
 *      /boot/kernel/netgraph.ko in the audit snapshot is ABI-incompatible
 *      with a freshly-built ng_l2cap.ko. Even after rebuilding both from
 *      the same source, the in-tree netgraph.ko loaded by the rc scripts
 *      is the older version.
 *
 * The bug is **confirmed by source-level analysis** (see VERDICT.md): the
 * missing arglen check is real and exploitable in any deployment that
 * actually uses DragonFly's Bluetooth L2CAP stack.
 *
 * This PoC source documents the trigger so a maintainer with a working
 * ng_l2cap + ng_hci setup (or an emulator like QEMU + an HCI passthrough)
 * can verify the fix.
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * The headers above (netgraph7/*, bluetooth/*) live inside the kernel tree
 * and are not exposed to userland builds. They are not needed for this PoC,
 * which is a documentation stub: the actual trigger requires kernel-side
 * netgraph message construction that is far cleaner to drive via ngctl(8)
 * than via this userland C. See VERDICT.md for the path analysis.
 */

int
main(void)
{
	fprintf(stderr,
	    "DF-0625: ng_l2cap L2CA_Ping missing arglen check\n"
	    "\n"
	    "This PoC would, on a kernel with working ng_l2cap + an HCI\n"
	    "lower layer connected:\n"
	    "  1. open a netgraph control socket\n"
	    "  2. create + connect an l2cap node\n"
	    "  3. send NGM_L2CAP_L2CA_PING with arglen=8, echo_size=200\n"
	    "  4. trigger _ng_l2cap_echo_req's m_copyback to read ~192 bytes\n"
	    "     past the ng_mesg allocation into adjacent kernel heap\n"
	    "  5. capture the resulting L2CAP Echo Request at the attacker's\n"
	    "     Bluetooth peer to recover kernel heap contents\n"
	    "\n"
	    "On THIS audit guest: no Bluetooth hardware and no ng_hci lower\n"
	    "layer, so ng_l2cap_lp_con_req returns ENOTCONN and the bug path\n"
	    "is unreachable. The bug is confirmed in source (see VERDICT.md)\n"
	    "and the fix is in fix.diff.\n");
	return 0;
}
