summaryrefslogtreecommitdiff
path: root/net/bluetooth/af_bluetooth.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-05-25 16:46:42 -0700
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-08-11 11:37:22 -0700
commit464c702fb9374ff8f3f816f24fb7ac719dd20e1e (patch)
treeb6ec1705f2eb9febf74345421afdbd68be82490f /net/bluetooth/af_bluetooth.c
parent6bfa273e533d7b25eee3d74e28a7fe8e6a8e7a93 (diff)
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.c24
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