Skip to content

Commit 817efd3

Browse files
committed
Bluetooth: hci_sock: Forward credentials to monitor
This stores scm_creds into hci_skb_cb so they can be properly forwarded to the likes of btmon which is then able to print information about the process who is originating the traffic: bluetoothd[35]: @ MGMT Command: Rea.. (0x0001) plen 0 {0x0001} @ MGMT Event: Command Complete (0x0001) plen 6 {0x0001} Read Management Version Information (0x0001) plen 3 bluetoothd[35]: < ACL Data T.. flags 0x00 dlen 41 ATT: Write Command (0x52) len 36 Handle: 0x0043 Type: ASE Control Point (0x2bc6) Data: 020203000110270000022800020a00409c0001000110270000022800020a00409c00 Opcode: QoS Configuration (0x02) Number of ASE(s): 2 ASE: #0 ASE ID: 0x03 CIG ID: 0x00 CIS ID: 0x01 SDU Interval: 10000 usec Framing: Unframed (0x00) PHY: 0x02 LE 2M PHY (0x02) Max SDU: 40 RTN: 2 Max Transport Latency: 10 Presentation Delay: 40000 us ASE: #1 ASE ID: 0x01 CIG ID: 0x00 CIS ID: 0x01 SDU Interval: 10000 usec Framing: Unframed (0x00) PHY: 0x02 LE 2M PHY (0x02) Max SDU: 40 RTN: 2 Max Transport Latency: 10 Presentation Delay: 40000 us Signed-off-by: Luiz Augusto von Dentz <[email protected]>
1 parent 777e1d7 commit 817efd3

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

include/net/bluetooth/bluetooth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ struct bt_skb_cb {
471471
struct sco_ctrl sco;
472472
struct hci_ctrl hci;
473473
struct mgmt_ctrl mgmt;
474+
struct scm_creds creds;
474475
};
475476
};
476477
#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb))

net/bluetooth/hci_sock.c

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,53 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
264264
kfree_skb(skb_copy);
265265
}
266266

267+
static void hci_sock_copy_creds(struct sock *sk, struct sk_buff *skb)
268+
{
269+
struct scm_creds *creds;
270+
271+
if (!sk || WARN_ON(!skb))
272+
return;
273+
274+
creds = &bt_cb(skb)->creds;
275+
276+
/* Check if peer credentials is set */
277+
if (!sk->sk_peer_pid) {
278+
/* Check if parent peer credentials is set */
279+
if (bt_sk(sk)->parent && bt_sk(sk)->parent->sk_peer_pid)
280+
sk = bt_sk(sk)->parent;
281+
else
282+
return;
283+
}
284+
285+
/* Check if scm_creds already set */
286+
if (creds->pid == pid_vnr(sk->sk_peer_pid))
287+
return;
288+
289+
memset(creds, 0, sizeof(*creds));
290+
291+
creds->pid = pid_vnr(sk->sk_peer_pid);
292+
if (sk->sk_peer_cred) {
293+
creds->uid = sk->sk_peer_cred->uid;
294+
creds->gid = sk->sk_peer_cred->gid;
295+
}
296+
}
297+
298+
static struct sk_buff *hci_skb_clone(struct sk_buff *skb)
299+
{
300+
struct sk_buff *nskb;
301+
302+
if (!skb)
303+
return NULL;
304+
305+
nskb = skb_clone(skb, GFP_ATOMIC);
306+
if (!nskb)
307+
return NULL;
308+
309+
hci_sock_copy_creds(skb->sk, nskb);
310+
311+
return nskb;
312+
}
313+
267314
/* Send frame to sockets with specific channel */
268315
static void __hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
269316
int flag, struct sock *skip_sk)
@@ -289,7 +336,7 @@ static void __hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
289336
if (hci_pi(sk)->channel != channel)
290337
continue;
291338

292-
nskb = skb_clone(skb, GFP_ATOMIC);
339+
nskb = hci_skb_clone(skb);
293340
if (!nskb)
294341
continue;
295342

@@ -356,6 +403,8 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
356403
if (!skb_copy)
357404
return;
358405

406+
hci_sock_copy_creds(skb->sk, skb_copy);
407+
359408
/* Put header before the data */
360409
hdr = skb_push(skb_copy, HCI_MON_HDR_SIZE);
361410
hdr->opcode = opcode;
@@ -531,10 +580,12 @@ static struct sk_buff *create_monitor_ctrl_open(struct sock *sk)
531580
return NULL;
532581
}
533582

534-
skb = bt_skb_alloc(14 + TASK_COMM_LEN , GFP_ATOMIC);
583+
skb = bt_skb_alloc(14 + TASK_COMM_LEN, GFP_ATOMIC);
535584
if (!skb)
536585
return NULL;
537586

587+
hci_sock_copy_creds(sk, skb);
588+
538589
flags = hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) ? 0x1 : 0x0;
539590

540591
put_unaligned_le32(hci_pi(sk)->cookie, skb_put(skb, 4));
@@ -580,6 +631,8 @@ static struct sk_buff *create_monitor_ctrl_close(struct sock *sk)
580631
if (!skb)
581632
return NULL;
582633

634+
hci_sock_copy_creds(sk, skb);
635+
583636
put_unaligned_le32(hci_pi(sk)->cookie, skb_put(skb, 4));
584637

585638
__net_timestamp(skb);
@@ -606,6 +659,8 @@ static struct sk_buff *create_monitor_ctrl_command(struct sock *sk, u16 index,
606659
if (!skb)
607660
return NULL;
608661

662+
hci_sock_copy_creds(sk, skb);
663+
609664
put_unaligned_le32(hci_pi(sk)->cookie, skb_put(skb, 4));
610665
put_unaligned_le16(opcode, skb_put(skb, 2));
611666

@@ -638,6 +693,8 @@ send_monitor_note(struct sock *sk, const char *fmt, ...)
638693
if (!skb)
639694
return;
640695

696+
hci_sock_copy_creds(sk, skb);
697+
641698
va_start(args, fmt);
642699
vsprintf(skb_put(skb, len), fmt, args);
643700
*(u8 *)skb_put(skb, 1) = 0;
@@ -1494,6 +1551,7 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
14941551
static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg,
14951552
size_t len, int flags)
14961553
{
1554+
struct scm_cookie scm;
14971555
struct sock *sk = sock->sk;
14981556
struct sk_buff *skb;
14991557
int copied, err;
@@ -1538,11 +1596,16 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg,
15381596
break;
15391597
}
15401598

1599+
memset(&scm, 0, sizeof(scm));
1600+
scm.creds = bt_cb(skb)->creds;
1601+
15411602
skb_free_datagram(sk, skb);
15421603

15431604
if (flags & MSG_TRUNC)
15441605
copied = skblen;
15451606

1607+
scm_recv(sock, msg, &scm, flags);
1608+
15461609
return err ? : copied;
15471610
}
15481611

0 commit comments

Comments
 (0)