diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2023-05-26 01:46:42 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2023-08-11 20:37:22 +0200 |
commit | 464c702fb9374ff8f3f816f24fb7ac719dd20e1e (patch) | |
tree | b6ec1705f2eb9febf74345421afdbd68be82490f /net/bluetooth/af_bluetooth.c | |
parent | Bluetooth: Consolidate code around sk_alloc into a helper function (diff) | |
download | linux-464c702fb9374ff8f3f816f24fb7ac719dd20e1e.tar.xz linux-464c702fb9374ff8f3f816f24fb7ac719dd20e1e.zip |
Bluetooth: Init sk_peer_* on bt_sock_alloc
This makes sure peer information is always available via sock when using
bt_sock_alloc.
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'net/bluetooth/af_bluetooth.c')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 6035422e13da..647afb187147 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -157,6 +157,14 @@ struct sock *bt_sock_alloc(struct net *net, struct socket *sock, sk->sk_protocol = proto; sk->sk_state = BT_OPEN; + /* Init peer information so it can be properly monitored */ + if (!kern) { + spin_lock(&sk->sk_peer_lock); + sk->sk_peer_pid = get_pid(task_tgid(current)); + sk->sk_peer_cred = get_current_cred(); + spin_unlock(&sk->sk_peer_lock); + } + return sk; } EXPORT_SYMBOL(bt_sock_alloc); @@ -179,6 +187,9 @@ EXPORT_SYMBOL(bt_sock_unlink); void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh) { + const struct cred *old_cred; + struct pid *old_pid; + BT_DBG("parent %p, sk %p", parent, sk); sock_hold(sk); @@ -191,6 +202,19 @@ void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh) list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q); bt_sk(sk)->parent = parent; + /* Copy credentials from parent since for incoming connections the + * socket is allocated by the kernel. + */ + spin_lock(&sk->sk_peer_lock); + old_pid = sk->sk_peer_pid; + old_cred = sk->sk_peer_cred; + sk->sk_peer_pid = get_pid(parent->sk_peer_pid); + sk->sk_peer_cred = get_cred(parent->sk_peer_cred); + spin_unlock(&sk->sk_peer_lock); + + put_pid(old_pid); + put_cred(old_cred); + if (bh) bh_unlock_sock(sk); else |