diff options
Diffstat (limited to 'net/bluetooth/af_bluetooth.c')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 72 |
1 files changed, 28 insertions, 44 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 9047512..0938f6b 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -40,15 +40,6 @@ #include <net/bluetooth/bluetooth.h> -#ifdef CONFIG_ANDROID_PARANOID_NETWORK -#include <linux/android_aid.h> -#endif - -#ifndef CONFIG_BT_SOCK_DEBUG -#undef BT_DBG -#define BT_DBG(D...) -#endif - #define VERSION "2.16" /* Bluetooth sockets */ @@ -134,40 +125,11 @@ int bt_sock_unregister(int proto) } EXPORT_SYMBOL(bt_sock_unregister); -#ifdef CONFIG_ANDROID_PARANOID_NETWORK -static inline int current_has_bt_admin(void) -{ - return (!current_euid() || in_egroup_p(AID_NET_BT_ADMIN)); -} - -static inline int current_has_bt(void) -{ - return (current_has_bt_admin() || in_egroup_p(AID_NET_BT)); -} -# else -static inline int current_has_bt_admin(void) -{ - return 1; -} - -static inline int current_has_bt(void) -{ - return 1; -} -#endif - static int bt_sock_create(struct net *net, struct socket *sock, int proto, int kern) { int err; - if (proto == BTPROTO_RFCOMM || proto == BTPROTO_SCO || - proto == BTPROTO_L2CAP) { - if (!current_has_bt()) - return -EPERM; - } else if (!current_has_bt_admin()) - return -EPERM; - if (net != &init_net) return -EAFNOSUPPORT; @@ -283,8 +245,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & (MSG_OOB)) return -EOPNOTSUPP; - msg->msg_namelen = 0; - skb = skb_recv_datagram(sk, flags, noblock, &err); if (!skb) { if (sk->sk_shutdown & RCV_SHUTDOWN) @@ -349,8 +309,6 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & MSG_OOB) return -EOPNOTSUPP; - msg->msg_namelen = 0; - BT_DBG("sk %p size %zu", sk, size); lock_sock(sk); @@ -387,7 +345,7 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, } chunk = min_t(unsigned int, skb->len, size); - if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + if (skb_copy_datagram_iovec(skb, 0, msg->msg_iov, chunk)) { skb_queue_head(&sk->sk_receive_queue, skb); if (!copied) copied = -EFAULT; @@ -399,7 +357,33 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, sock_recv_ts_and_drops(msg, sk, skb); if (!(flags & MSG_PEEK)) { - skb_pull(skb, chunk); + int skb_len = skb_headlen(skb); + + if (chunk <= skb_len) { + __skb_pull(skb, chunk); + } else { + struct sk_buff *frag; + + __skb_pull(skb, skb_len); + chunk -= skb_len; + + skb_walk_frags(skb, frag) { + if (chunk <= frag->len) { + /* Pulling partial data */ + skb->len -= chunk; + skb->data_len -= chunk; + __skb_pull(frag, chunk); + break; + } else if (frag->len) { + /* Pulling all frag data */ + chunk -= frag->len; + skb->len -= frag->len; + skb->data_len -= frag->len; + __skb_pull(frag, frag->len); + } + } + } + if (skb->len) { skb_queue_head(&sk->sk_receive_queue, skb); break; |