Merge branch 'stable-3.17' of git://git.infradead.org/users/pcmoore/selinux
[cascardo/linux.git] / net / bluetooth / l2cap_sock.c
index e137869..1884f72 100644 (file)
@@ -279,7 +279,7 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
                        break;
                /* fall through */
        default:
-               err = -ENOTSUPP;
+               err = -EOPNOTSUPP;
                goto done;
        }
 
@@ -361,7 +361,8 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
        BT_DBG("sock %p, sk %p", sock, sk);
 
        if (peer && sk->sk_state != BT_CONNECTED &&
-           sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2)
+           sk->sk_state != BT_CONNECT && sk->sk_state != BT_CONNECT2 &&
+           sk->sk_state != BT_CONFIG)
                return -ENOTCONN;
 
        memset(la, 0, sizeof(struct sockaddr_l2));
@@ -796,7 +797,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
                } else if ((sk->sk_state == BT_CONNECT2 &&
                            test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) ||
                           sk->sk_state == BT_CONNECTED) {
-                       if (!l2cap_chan_check_security(chan))
+                       if (!l2cap_chan_check_security(chan, true))
                                set_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
                        else
                                sk->sk_state_change(sk);
@@ -964,7 +965,7 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                return err;
 
        l2cap_chan_lock(chan);
-       err = l2cap_chan_send(chan, msg, len, sk->sk_priority);
+       err = l2cap_chan_send(chan, msg, len);
        l2cap_chan_unlock(chan);
 
        return err;
@@ -1111,7 +1112,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how)
                l2cap_chan_close(chan, 0);
                lock_sock(sk);
 
-               if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime)
+               if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
+                   !(current->flags & PF_EXITING))
                        err = bt_sock_wait_state(sk, BT_CLOSED,
                                                 sk->sk_lingertime);
        }
@@ -1292,6 +1294,7 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state,
 }
 
 static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
+                                              unsigned long hdr_len,
                                               unsigned long len, int nb)
 {
        struct sock *sk = chan->data;
@@ -1299,17 +1302,26 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
        int err;
 
        l2cap_chan_unlock(chan);
-       skb = bt_skb_send_alloc(sk, len, nb, &err);
+       skb = bt_skb_send_alloc(sk, hdr_len + len, nb, &err);
        l2cap_chan_lock(chan);
 
        if (!skb)
                return ERR_PTR(err);
 
+       skb->priority = sk->sk_priority;
+
        bt_cb(skb)->chan = chan;
 
        return skb;
 }
 
+static int l2cap_sock_memcpy_fromiovec_cb(struct l2cap_chan *chan,
+                                         unsigned char *kdata,
+                                         struct iovec *iov, int len)
+{
+       return memcpy_fromiovec(kdata, iov, len);
+}
+
 static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
 {
        struct sock *sk = chan->data;
@@ -1375,20 +1387,21 @@ static void l2cap_sock_suspend_cb(struct l2cap_chan *chan)
        sk->sk_state_change(sk);
 }
 
-static struct l2cap_ops l2cap_chan_ops = {
-       .name           = "L2CAP Socket Interface",
-       .new_connection = l2cap_sock_new_connection_cb,
-       .recv           = l2cap_sock_recv_cb,
-       .close          = l2cap_sock_close_cb,
-       .teardown       = l2cap_sock_teardown_cb,
-       .state_change   = l2cap_sock_state_change_cb,
-       .ready          = l2cap_sock_ready_cb,
-       .defer          = l2cap_sock_defer_cb,
-       .resume         = l2cap_sock_resume_cb,
-       .suspend        = l2cap_sock_suspend_cb,
-       .set_shutdown   = l2cap_sock_set_shutdown_cb,
-       .get_sndtimeo   = l2cap_sock_get_sndtimeo_cb,
-       .alloc_skb      = l2cap_sock_alloc_skb_cb,
+static const struct l2cap_ops l2cap_chan_ops = {
+       .name                   = "L2CAP Socket Interface",
+       .new_connection         = l2cap_sock_new_connection_cb,
+       .recv                   = l2cap_sock_recv_cb,
+       .close                  = l2cap_sock_close_cb,
+       .teardown               = l2cap_sock_teardown_cb,
+       .state_change           = l2cap_sock_state_change_cb,
+       .ready                  = l2cap_sock_ready_cb,
+       .defer                  = l2cap_sock_defer_cb,
+       .resume                 = l2cap_sock_resume_cb,
+       .suspend                = l2cap_sock_suspend_cb,
+       .set_shutdown           = l2cap_sock_set_shutdown_cb,
+       .get_sndtimeo           = l2cap_sock_get_sndtimeo_cb,
+       .alloc_skb              = l2cap_sock_alloc_skb_cb,
+       .memcpy_fromiovec       = l2cap_sock_memcpy_fromiovec_cb,
 };
 
 static void l2cap_sock_destruct(struct sock *sk)