[BUG] kernel BUG in lowpan_header_compress

Farhad Alemi posted 1 patch 2 weeks, 1 day ago
[BUG] kernel BUG in lowpan_header_compress
Posted by Farhad Alemi 2 weeks, 1 day ago
Hello,

We are reporting the following crash (reproducer and a proposed patch attached):
Linux version 7.3.0-rc2 50d05c7c76c96b90462f24debacca971d2e86713
Build Config: UpstreamAppArmorKASAN (KASAN + UBSAN, panic_on_warn=1)

[   50.238797][   T56] Bluetooth: hci0: unexpected cc 0x0c03 length: 249 > 1
[   50.241338][   T56] Bluetooth: hci0: unexpected cc 0x1003 length: 249 > 9
[   50.241848][   T56] Bluetooth: hci0: unexpected cc 0x1001 length: 249 > 9
[   50.245626][   T56] Bluetooth: hci0: unexpected cc 0x0c23 length: 249 > 4
[   50.245912][   T56] Bluetooth: hci0: unexpected cc 0x0c38 length: 249 > 2
[   50.754952][ T9494] skbuff: skb_under_panic: text:ffffffff8b7fa50d
len:64 put:28 head:ffff888111738000 data:ffff888111737ff4 tail:0x34
end:0x180 dev:bt0
[   50.755855][ T9494] ------------[ cut here ]------------
[   50.755867][ T9494] kernel BUG at net/core/skbuff.c:214!
[   50.755943][ T9494] Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
[   50.768411][ T9494] CPU: 1 UID: 0 PID: 9494 Comm: repro Not tainted
7.3.0-rc2-00099-g50d05c7c76c9 #1 PREEMPT(full)
[   50.770445][ T9494] Hardware name: QEMU Standard PC (Q35 + ICH9,
2009), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
[   50.772451][ T9494] RIP: 0010:skb_panic+0x157/0x160
[   50.773445][ T9494] Code: c7 c0 a8 01 8d 48 8b 74 24 08 48 8b 54 24
10 8b 0c 24 44 8b 44 24 04 4d 89 e9 50 55 41 57 41 56 e8 4e 84 f5 ff
48 83 c4 20 90 <0f> 0b cc cc cc cc cc cc cc 90 90 90 90 90 90 90 90 90
90 90 90 90
[   50.777065][ T9494] RSP: 0018:ffffc900071b6ea0 EFLAGS: 00010286
[   50.777983][ T9494] RAX: 0000000000000084 RBX: dffffc0000000000
RCX: 4ccd4c5bba686000
[   50.778782][ T9494] RDX: 0000000000000000 RSI: 8000000000000201
RDI: 0000000000000000
[   50.779550][ T9494] RBP: 0000000000000180 R08: ffffc900071b6c07
R09: 1ffff92000e36d80
[   50.780352][ T9494] R10: dffffc0000000000 R11: fffff52000e36d81
R12: ffff88810804e290
[   50.781105][ T9494] R13: ffff888111738000 R14: ffff888111737ff4
R15: 0000000000000034
[   50.781865][ T9494] FS:  000000002fb9b400(0000)
GS:ffff8881da588000(0000) knlGS:0000000000000000
[   50.782727][ T9494] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   50.783410][ T9494] CR2: 000055f09acf9258 CR3: 0000000022ecb000
CR4: 0000000000752ef0
[   50.784188][ T9494] PKRU: 55555554
[   50.784546][ T9494] Call Trace:
[   50.784881][ T9494]  <TASK>
[   50.785181][ T9494]  ? lowpan_header_compress+0x11dd/0x1ee0
[   50.785759][ T9494]  ? lowpan_header_compress+0x11dd/0x1ee0
[   50.786308][ T9494]  skb_push+0xc3/0xe0
[   50.786705][ T9494]  lowpan_header_compress+0x11dd/0x1ee0
[   50.787246][ T9494]  ? __pfx_lowpan_header_compress+0x10/0x10
[   50.787822][ T9494]  ? lock_acquire+0x115/0x350
[   50.788284][ T9494]  ? skb_copy_bits+0x8a/0x8f0
[   50.788745][ T9494]  ? bt_xmit+0x283/0x2280
[   50.789179][ T9494]  bt_xmit+0x12c8/0x2280
[   50.789603][ T9494]  ? __pfx_bt_xmit+0x10/0x10
[   50.790100][ T9494]  ? skb_network_protocol+0x23d/0x400
[   50.790623][ T9494]  ? netif_skb_features+0xdf0/0x1480
[   50.791135][ T9494]  ? lockdep_unlock+0x5c/0xd0
[   50.791595][ T9494]  ? __lock_acquire+0x25db/0x2db0
[   50.792082][ T9494]  ? __pfx_netif_skb_features+0x10/0x10
[   50.792620][ T9494]  ? packet_sendmsg+0x3039/0x4d00
[   50.793108][ T9494]  ? sock_sendmsg_nosec+0x13a/0x180
[   50.793635][ T9494]  ? __sys_sendto+0x408/0x5a0
[   50.794103][ T9494]  ? __x64_sys_sendto+0xde/0x100
[   50.794599][ T9494]  ? do_syscall_64+0x155/0x510
[   50.795065][ T9494]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   50.795654][ T9494]  dev_hard_start_xmit+0x2cd/0x830
[   50.796153][ T9494]  sch_direct_xmit+0x251/0x4c0
[   50.796624][ T9494]  ? __pfx_sch_direct_xmit+0x10/0x10
[   50.797135][ T9494]  ? qdisc_bstats_update+0x110/0x1d0
[   50.797652][ T9494]  __dev_queue_xmit+0x19ef/0x3980
[   50.798140][ T9494]  ? __dev_queue_xmit+0x2b6/0x3980
[   50.798637][ T9494]  ? _copy_from_iter+0x21b/0x1670
[   50.799132][ T9494]  ? __pfx___dev_queue_xmit+0x10/0x10
[   50.799653][ T9494]  ? sock_alloc_send_pskb+0x896/0x990
[   50.800221][ T9494]  ? __pfx__copy_from_iter+0x10/0x10
[   50.800733][ T9494]  ? packet_parse_headers+0x2e6/0x790
[   50.801250][ T9494]  ? packet_parse_headers+0x5dd/0x790
[   50.801772][ T9494]  ? __pfx_sock_alloc_send_pskb+0x10/0x10
[   50.802340][ T9494]  ? __pfx_packet_parse_headers+0x10/0x10
[   50.802906][ T9494]  ? packet_xmit+0x68/0x320
[   50.803358][ T9494]  packet_sendmsg+0x3b14/0x4d00
[   50.803852][ T9494]  ? aa_inet_bind_perm+0x6b6/0xca0
[   50.804360][ T9494]  ? kasan_save_track+0x4f/0x80
[   50.804838][ T9494]  ? kasan_save_track+0x3e/0x80
[   50.805310][ T9494]  ? __kasan_slab_alloc+0x6c/0x80
[   50.805811][ T9494]  ? kmem_cache_alloc_noprof+0x2bd/0x610
[   50.806355][ T9494]  ? __lock_acquire+0x74c/0x2db0
[   50.806847][ T9494]  ? __pfx_packet_sendmsg+0x10/0x10
[   50.807352][ T9494]  ? aa_sk_perm+0x713/0x900
[   50.807801][ T9494]  ? update_triggers+0x320/0x4d0
[   50.808282][ T9494]  ? __pfx_aa_sk_perm+0x10/0x10
[   50.808760][ T9494]  ? aa_sock_msg_perm+0x144/0x210
[   50.809251][ T9494]  ? apparmor_socket_sendmsg+0x95/0x390
[   50.809793][ T9494]  ? __pfx_packet_sendmsg+0x10/0x10
[   50.810343][ T9494]  sock_sendmsg_nosec+0x13a/0x180
[   50.810833][ T9494]  __sys_sendto+0x408/0x5a0
[   50.811275][ T9494]  ? __pfx___sys_sendto+0x10/0x10
[   50.811769][ T9494]  ? fd_install+0x94/0x3d0
[   50.812202][ T9494]  ? fd_install+0x309/0x3d0
[   50.812647][ T9494]  __x64_sys_sendto+0xde/0x100
[   50.813112][ T9494]  do_syscall_64+0x155/0x510
[   50.813567][ T9494]  ? trace_irq_disable+0x3b/0x140
[   50.814057][ T9494]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   50.814644][ T9494]  ? clear_bhb_loop+0x30/0x80
[   50.815101][ T9494]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[   50.815675][ T9494] RIP: 0033:0x4527b2
[   50.816062][ T9494] Code: 08 0f 85 e1 df ff ff 49 89 fb 48 89 f0 48
89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89
5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa
55 48 89 e5
[   50.817904][ T9494] RSP: 002b:00007ffc7bf0a438 EFLAGS: 00000246
ORIG_RAX: 000000000000002c
[   50.818725][ T9494] RAX: ffffffffffffffda RBX: 0000000000000001
RCX: 00000000004527b2
[   50.819496][ T9494] RDX: 0000000000000024 RSI: 00007ffc7bf0a4c0
RDI: 0000000000000003
[   50.820334][ T9494] RBP: 00007ffc7bf0a460 R08: 00007ffc7bf0a4a0
R09: 0000000000000014
[   50.821106][ T9494] R10: 0000000000000000 R11: 0000000000000246
R12: 00007ffc7bf0a618
[   50.821873][ T9494] R13: 00007ffc7bf0a628 R14: 0000000000000002
R15: 00000000004cba40
[   50.822631][ T9494]  </TASK>
[   50.822957][ T9494] Modules linked in:
[   50.823408][ T9494] ---[ end trace 0000000000000000 ]---
[   50.823952][ T9494] RIP: 0010:skb_panic+0x157/0x160
[   50.823964][ T9494] Code: c7 c0 a8 01 8d 48 8b 74 24 08 48 8b 54 24
10 8b 0c 24 44 8b 44 24 04 4d 89 e9 50 55 41 57 41 56 e8 4e 84 f5 ff
48 83 c4 20 90 <0f> 0b cc cc cc cc cc cc cc 90 90 90 90 90 90 90 90 90
90 90 90 90
[   50.823970][ T9494] RSP: 0018:ffffc900071b6ea0 EFLAGS: 00010286
[   50.823976][ T9494] RAX: 0000000000000084 RBX: dffffc0000000000
RCX: 4ccd4c5bba686000
[   50.823981][ T9494] RDX: 0000000000000000 RSI: 8000000000000201
RDI: 0000000000000000
[   50.823986][ T9494] RBP: 0000000000000180 R08: ffffc900071b6c07
R09: 1ffff92000e36d80
[   50.823991][ T9494] R10: dffffc0000000000 R11: fffff52000e36d81
R12: ffff88810804e290
[   50.823996][ T9494] R13: ffff888111738000 R14: ffff888111737ff4
R15: 0000000000000034
[   50.824001][ T9494] FS:  000000002fb9b400(0000)
GS:ffff8881da588000(0000) knlGS:0000000000000000
[   50.824006][ T9494] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   50.824011][ T9494] CR2: 000055f09acf9258 CR3: 0000000022ecb000
CR4: 0000000000752ef0
[   50.824017][ T9494] PKRU: 55555554
[   50.824024][ T9494] Kernel panic - not syncing: Fatal exception in interrupt
[   50.834454][ T9494] Kernel Offset: disabled
[   50.835002][ T9494] Rebooting in 86400 seconds..

Regards,
SEFCOM Lab @ ASU
--- a/net/6lowpan/iphc.c	2026-09-09 17:39:32.246999220 -0700
+++ b/net/6lowpan/iphc.c	2026-09-09 17:39:32.269520956 -0700
@@ -1140,6 +1140,10 @@
 	if (skb->protocol != htons(ETH_P_IPV6))
 		return -EINVAL;
 
+	/* Every field compressed below is read out of the IPv6 header. */
+	if (skb->len < sizeof(struct ipv6hdr))
+		return -EINVAL;
+
 	hdr = ipv6_hdr(skb);
 	hc_ptr = head + 2;
 
@@ -1299,7 +1303,11 @@
 	head[0] = iphc0;
 	head[1] = iphc1;
 
-	skb_pull(skb, sizeof(struct ipv6hdr));
+	/* NHC compression has already pulled the transport header, so the
+	 * IPv6 header may no longer be there to pull.
+	 */
+	if (!skb_pull(skb, sizeof(struct ipv6hdr)))
+		return -EINVAL;
 	skb_reset_transport_header(skb);
 	memcpy(skb_push(skb, hc_ptr - head), head, hc_ptr - head);
 	skb_reset_network_header(skb);
/*
 * 207-kernel-bug-in-lowpan-header-compress
 */

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>

typedef uint8_t u8;
typedef uint16_t u16;

#define BTPROTO_HCI 1

#define HCI_COMMAND_PKT 0x01
#define HCI_ACLDATA_PKT 0x02
#define HCI_EVENT_PKT 0x04
#define HCI_VENDOR_PKT 0xff

#define HCI_EV_CMD_COMPLETE 0x0e
#define HCI_EV_LE_META 0x3e
#define HCI_EV_LE_CONN_COMPLETE 0x01

#define HCI_OP_RESET 0x0c03
#define HCI_OP_READ_BUFFER_SIZE 0x1005
#define HCI_OP_READ_BD_ADDR 0x1009
#define HCIDEVUP _IOW('H', 201, int)

/* Connection handle the faked LE link is given; reused as the ACL TX handle. */
#define FAKE_LE_CONN_HANDLE 201

typedef struct { u8 b[6]; } __attribute__((packed)) bdaddr_t;

struct hci_command_hdr { u16 opcode; u8 plen; } __attribute__((packed));
struct hci_event_hdr { u8 evt; u8 plen; } __attribute__((packed));
struct hci_ev_cmd_complete { u8 ncmd; u16 opcode; } __attribute__((packed));

struct hci_ev_le_conn_complete {
	u8 status; u16 handle; u8 role; u8 bdaddr_type; bdaddr_t bdaddr;
	u16 interval; u16 latency; u16 supervision_timeout; u8 clk_accurancy;
} __attribute__((packed));

struct hci_rp_read_buffer_size {
	u8 status; u16 acl_mtu; u8 sco_mtu; u16 acl_max_pkt; u16 sco_max_pkt;
} __attribute__((packed));
struct hci_rp_read_bd_addr { u8 status; bdaddr_t bdaddr; } __attribute__((packed));

struct vhci_vendor_pkt_request { u8 type; u8 opcode; } __attribute__((packed));
struct vhci_pkt {
	u8 type;
	union {
		struct { u8 opcode; u16 id; } __attribute__((packed)) vendor_pkt;
		struct hci_command_hdr command_hdr;
	};
} __attribute__((packed));

static int vhci_fd = -1;

static void die(const char *what)
{
	fprintf(stderr, "FAIL: %s (%s)\n", what, strerror(errno));
	exit(1);
}

static void hci_send_event_packet(u8 event_code, void *payload, size_t payload_len)
{
	struct hci_event_hdr hdr = { .evt = event_code, .plen = (u8)payload_len };
	u8 packet_type = HCI_EVENT_PKT;
	struct iovec iov[3] = {
		{ &packet_type, 1 },
		{ &hdr, sizeof(hdr) },
		{ payload, payload_len },
	};
	if (writev(vhci_fd, iov, 3) < 0)
		die("writev HCI event");
}

static void hci_send_command_complete(u16 opcode, void *return_params, size_t return_len)
{
	struct hci_event_hdr hdr = {
		.evt = HCI_EV_CMD_COMPLETE,
		.plen = (u8)(sizeof(struct hci_ev_cmd_complete) + return_len),
	};
	struct hci_ev_cmd_complete complete = { .ncmd = 1, .opcode = opcode };
	u8 packet_type = HCI_EVENT_PKT;
	struct iovec iov[4] = {
		{ &packet_type, 1 },
		{ &hdr, sizeof(hdr) },
		{ &complete, sizeof(complete) },
		{ return_params, return_len },
	};
	if (writev(vhci_fd, iov, 4) < 0)
		die("writev HCI command complete");
}

/*
 * Answer every HCI command the kernel's controller-init sends with a success
 * Command Complete.  Two commands need real values or HCIDEVUP fails with
 * EINVAL: an all-zero BD_ADDR is rejected as invalid, and a zero ACL MTU
 * leaves the controller with no usable TX buffer.  Everything else gets the
 * largest all-zero return-parameter block an HCI event can carry (0xf9 after
 * the 3-byte Command Complete preamble), so no parser sees a short reply.
 */
static void *hci_command_responder_thread(void *unused)
{
	for (;;) {
		char buf[1024];
		ssize_t nbytes = read(vhci_fd, buf, sizeof(buf));
		if (nbytes <= 0) {
			if (errno == EINTR)
				continue;
			return NULL;
		}
		if (buf[0] != HCI_COMMAND_PKT ||
		    nbytes < 1 + (ssize_t)sizeof(struct hci_command_hdr))
			continue;
		struct hci_command_hdr *cmd = (struct hci_command_hdr *)(buf + 1);
		if (cmd->opcode == HCI_OP_READ_BD_ADDR) {
			struct hci_rp_read_bd_addr bd_addr = {0};
			memset(&bd_addr.bdaddr, 0xaa, 6);
			hci_send_command_complete(cmd->opcode, &bd_addr, sizeof(bd_addr));
		} else if (cmd->opcode == HCI_OP_READ_BUFFER_SIZE) {
			struct hci_rp_read_buffer_size buffer_size = {0};
			buffer_size.acl_mtu = 1021;
			buffer_size.sco_mtu = 96;
			buffer_size.acl_max_pkt = 4;
			buffer_size.sco_max_pkt = 6;
			hci_send_command_complete(cmd->opcode, &buffer_size,
						  sizeof(buffer_size));
		} else {
			char zero_return_params[0xf9] = {0};
			hci_send_command_complete(cmd->opcode, zero_return_params,
						  sizeof(zero_return_params));
		}
	}
}

static void create_vhci_controller_with_fake_le_connection(void)
{
	pthread_t hci_command_responder;
	int hci_sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
	if (hci_sock < 0)
		die("socket(AF_BLUETOOTH, BTPROTO_HCI)");

	vhci_fd = open("/dev/vhci", O_RDWR);
	if (vhci_fd < 0)
		die("open /dev/vhci");

	/* Vendor packet requesting HCI_PRIMARY; the reply carries the dev id. */
	struct vhci_vendor_pkt_request request = { HCI_VENDOR_PKT, 0 };
	if (write(vhci_fd, &request, sizeof(request)) != sizeof(request))
		die("write vhci vendor packet");

	struct vhci_pkt reply;
	if (read(vhci_fd, &reply, sizeof(reply)) != sizeof(reply))
		die("read vhci reply");
	/* Some kernels emit HCI_OP_RESET before the vendor reply. */
	if (reply.type == HCI_COMMAND_PKT && reply.command_hdr.opcode == HCI_OP_RESET) {
		char status_ok = 0;
		hci_send_command_complete(HCI_OP_RESET, &status_ok, 1);
		if (read(vhci_fd, &reply, sizeof(reply)) != sizeof(reply))
			die("read vhci reply after reset");
	}
	if (reply.type != HCI_VENDOR_PKT)
		die("unexpected vhci packet type");
	int hci_dev_id = reply.vendor_pkt.id;

	if (pthread_create(&hci_command_responder, NULL,
			   hci_command_responder_thread, NULL))
		die("pthread_create");

	if (ioctl(hci_sock, HCIDEVUP, hci_dev_id) && errno != EALREADY)
		die("HCIDEVUP");
	close(hci_sock);

	/* Fake an LE Connection Complete so an ACL link exists to speak L2CAP on. */
	struct {
		u8 subevent;
		struct hci_ev_le_conn_complete conn;
	} __attribute__((packed)) le_meta;
	memset(&le_meta, 0, sizeof(le_meta));
	le_meta.subevent = HCI_EV_LE_CONN_COMPLETE;
	le_meta.conn.handle = FAKE_LE_CONN_HANDLE;
	le_meta.conn.role = 1;
	memset(&le_meta.conn.bdaddr, 0xaa, 6);
	le_meta.conn.bdaddr.b[5] = 0x11;
	hci_send_event_packet(HCI_EV_LE_META, &le_meta, sizeof(le_meta));

	usleep(200000);
}

/*
 * Inject an L2CAP LE credit-based connection request for PSM 0x0023 (IPSP).
 * The 6lowpan listener accepts it, and chan_ready_cb() then registers bt0
 * and brings it up, so no explicit SIOCSIFFLAGS is needed.
 */
static void open_l2cap_ipsp_channel(void)
{
	u8 l2cap_le_conn_req[14];
	u8 acl_packet[64];
	int offset = 0;

	l2cap_le_conn_req[0] = 0x14;			/* L2CAP_LE_CONN_REQ */
	l2cap_le_conn_req[1] = 0x01;			/* identifier */
	*(u16 *)&l2cap_le_conn_req[2] = 10;		/* command length */
	*(u16 *)&l2cap_le_conn_req[4] = 0x0023;		/* PSM: IPSP */
	*(u16 *)&l2cap_le_conn_req[6] = 0x0040;		/* source CID */
	*(u16 *)&l2cap_le_conn_req[8] = 1280;		/* MTU */
	*(u16 *)&l2cap_le_conn_req[10] = 1280;		/* MPS */
	*(u16 *)&l2cap_le_conn_req[12] = 10;		/* initial credits */

	acl_packet[offset++] = HCI_ACLDATA_PKT;
	/* Packet-boundary flag 2 = first non-flushable, point-to-point. */
	*(u16 *)&acl_packet[offset] = FAKE_LE_CONN_HANDLE | (2 << 12);
	offset += 2;
	*(u16 *)&acl_packet[offset] = 4 + sizeof(l2cap_le_conn_req);
	offset += 2;					/* ACL data length */
	*(u16 *)&acl_packet[offset] = sizeof(l2cap_le_conn_req);
	offset += 2;					/* L2CAP PDU length */
	*(u16 *)&acl_packet[offset] = 0x0005;
	offset += 2;					/* LE signaling CID */
	memcpy(&acl_packet[offset], l2cap_le_conn_req, sizeof(l2cap_le_conn_req));
	offset += sizeof(l2cap_le_conn_req);

	if (write(vhci_fd, acl_packet, offset) != offset)
		die("write L2CAP LE connection request");
	usleep(300000);
}

int main(void)
{
	int lowpan_enable_fd;
	unsigned bt0_ifindex = 0;
	int attempt;

	mkdir("/sys/kernel/debug", 0755);
	mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL);

	lowpan_enable_fd = open("/sys/kernel/debug/bluetooth/6lowpan_enable", O_WRONLY);
	if (lowpan_enable_fd < 0)
		die("open 6lowpan_enable");
	if (write(lowpan_enable_fd, "1\n", 2) < 0)
		die("write 6lowpan_enable");
	close(lowpan_enable_fd);

	create_vhci_controller_with_fake_le_connection();
	open_l2cap_ipsp_channel();

	for (attempt = 0; attempt < 100 && !bt0_ifindex; attempt++) {
		bt0_ifindex = if_nametoindex("bt0");
		if (!bt0_ifindex)
			usleep(100000);
	}
	if (!bt0_ifindex)
		die("bt0 never appeared");

	int packet_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IPV6));
	if (packet_socket < 0)
		die("socket(AF_PACKET)");

	struct sockaddr_ll bt0_link_address;
	memset(&bt0_link_address, 0, sizeof(bt0_link_address));
	bt0_link_address.sll_family = AF_PACKET;
	bt0_link_address.sll_protocol = htons(ETH_P_IPV6);
	bt0_link_address.sll_ifindex = bt0_ifindex;
	bt0_link_address.sll_halen = 0;

	/*
	 * 36 bytes: shorter than sizeof(struct ipv6hdr) == 40.  net/6lowpan/iphc.c
	 * does skb_pull(skb, sizeof(struct ipv6hdr)) before the compressed header
	 * is pushed, and skb_pull() is a no-op when len > skb->len, so skb->data
	 * is never advanced.  Every compressible field below is chosen to be
	 * incompressible, so the IPHC header is 28 bytes -- more than the 16
	 * bytes of headroom AF_PACKET reserved for bt0 (hard_header_len 0,
	 * needed_headroom 0).  The skb_push() therefore underflows the buffer.
	 */
	u8 truncated_ipv6_frame[36];
	memset(truncated_ipv6_frame, 0, sizeof(truncated_ipv6_frame));
	truncated_ipv6_frame[0] = 0x61;		/* version 6, traffic class != 0 */
	truncated_ipv6_frame[1] = 0x12;		/* traffic class / flow label */
	truncated_ipv6_frame[2] = 0x34;
	truncated_ipv6_frame[3] = 0x56;		/* flow label != 0 -> TF=00, 4 bytes inline */
	truncated_ipv6_frame[6] = 0x06;		/* next header TCP: no NHC -> 1 byte inline */
	truncated_ipv6_frame[7] = 0x07;		/* hop limit not 1/64/255 -> 1 byte inline */
	/* source 2001:db8::1 -- global unicast, so all 16 bytes go inline */
	truncated_ipv6_frame[8] = 0x20;
	truncated_ipv6_frame[9] = 0x01;
	truncated_ipv6_frame[10] = 0x0d;
	truncated_ipv6_frame[11] = 0xb8;
	truncated_ipv6_frame[23] = 0x01;
	/* destination ff05::... , truncated by the 36-byte frame length */
	truncated_ipv6_frame[24] = 0xff;
	truncated_ipv6_frame[25] = 0x05;

	sendto(packet_socket, truncated_ipv6_frame, sizeof(truncated_ipv6_frame), 0,
	       (struct sockaddr *)&bt0_link_address, sizeof(bt0_link_address));
	return 0;
}