OSDN Git Service

Bluetooth: Init sk_peer_* on bt_sock_alloc
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 25 May 2023 23:46:42 +0000 (16:46 -0700)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 11 Aug 2023 18:37:22 +0000 (11:37 -0700)
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>
net/bluetooth/af_bluetooth.c
net/bluetooth/hidp/sock.c
net/bluetooth/l2cap_sock.c

index 6035422..647afb1 100644 (file)
@@ -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
index 369ed92..c93aaeb 100644 (file)
@@ -256,21 +256,13 @@ static int hidp_sock_create(struct net *net, struct socket *sock, int protocol,
        if (sock->type != SOCK_RAW)
                return -ESOCKTNOSUPPORT;
 
-       sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, kern);
+       sk = bt_sock_alloc(net, sock, &hidp_proto, protocol, GFP_ATOMIC, kern);
        if (!sk)
                return -ENOMEM;
 
-       sock_init_data(sock, sk);
-
        sock->ops = &hidp_sock_ops;
-
        sock->state = SS_UNCONNECTED;
 
-       sock_reset_flag(sk, SOCK_ZAPPED);
-
-       sk->sk_protocol = protocol;
-       sk->sk_state    = BT_OPEN;
-
        bt_sock_link(&hidp_sk_list, sk);
 
        return 0;
index 9ef936f..3bdfc3f 100644 (file)
@@ -178,21 +178,6 @@ done:
        return err;
 }
 
-static void l2cap_sock_init_pid(struct sock *sk)
-{
-       struct l2cap_chan *chan = l2cap_pi(sk)->chan;
-
-       /* Only L2CAP_MODE_EXT_FLOWCTL ever need to access the PID in order to
-        * group the channels being requested.
-        */
-       if (chan->mode != L2CAP_MODE_EXT_FLOWCTL)
-               return;
-
-       spin_lock(&sk->sk_peer_lock);
-       sk->sk_peer_pid = get_pid(task_tgid(current));
-       spin_unlock(&sk->sk_peer_lock);
-}
-
 static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
                              int alen, int flags)
 {
@@ -268,8 +253,6 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
            chan->mode != L2CAP_MODE_EXT_FLOWCTL)
                chan->mode = L2CAP_MODE_LE_FLOWCTL;
 
-       l2cap_sock_init_pid(sk);
-
        err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
                                 &la.l2_bdaddr, la.l2_bdaddr_type);
        if (err)
@@ -325,8 +308,6 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
                goto done;
        }
 
-       l2cap_sock_init_pid(sk);
-
        sk->sk_max_ack_backlog = backlog;
        sk->sk_ack_backlog = 0;