diff options
author | Dominik Sliwa <dominik.sliwa@toradex.com> | 2017-12-22 12:07:34 +0000 |
---|---|---|
committer | Dominik Sliwa <dominik.sliwa@toradex.com> | 2018-09-18 17:15:11 +0200 |
commit | 69ff0b5709d0d06545fcb2d08c7645b56d3687dd (patch) | |
tree | 71f1569cc019e16c1b1be22c1e8d382766daebb3 /net | |
parent | d6a47bfb72f495a72637fbe635220f6af0f4cb6f (diff) |
backports: bluetooth: Support 4.9 kernels
Signed-off-by: Dominik Sliwa <dominik.sliwa@toradex.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/Kconfig | 3 | ||||
-rw-r--r-- | net/bluetooth/a2mp.c | 4 | ||||
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 8 | ||||
-rw-r--r-- | net/bluetooth/ecdh_helper.c | 3 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 6 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 38 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 19 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 4 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 11 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 12 |
10 files changed, 94 insertions, 14 deletions
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 08f5808..0f68a23 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -14,7 +14,8 @@ menuconfig BT depends on CRYPTO_CMAC depends on CRYPTO_ECB depends on CRYPTO_SHA256 - depends on CRYPTO_ECDH + depends on CRYPTO_ECDH + depends on !KERNEL_4_7 help Bluetooth is low-cost, low-power, short-range wireless technology. It was designed as a replacement for cables and other short-range diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 51c2cf2..9346e75 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -239,7 +239,7 @@ static int a2mp_discover_rsp(struct amp_mgr *mgr, struct sk_buff *skb, } len -= sizeof(*cl); - cl = skb_pull(skb, sizeof(*cl)); + cl = (void *)skb_pull(skb, sizeof(*cl)); } /* Fall back to L2CAP init sequence */ @@ -279,7 +279,7 @@ static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, while (skb->len >= sizeof(*cl)) { BT_DBG("Controller id %d type %d status %d", cl->id, cl->type, cl->status); - cl = skb_pull(skb, sizeof(*cl)); + cl = (void *) skb_pull(skb, sizeof(*cl)); } /* TODO send A2MP_CHANGE_RSP */ diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 3264e18..77a68c0 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -28,6 +28,7 @@ #include <linux/debugfs.h> #include <linux/stringify.h> #include <linux/sched/signal.h> +#include <linux/refcount.h> #include <asm/ioctls.h> @@ -649,7 +650,7 @@ static int bt_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "%pK %-6d %-6u %-6u %-6u %-6lu %-6lu", sk, - refcount_read(&sk->sk_refcnt), + refcount_read((const refcount_t *)&sk->sk_refcnt), sk_rmem_alloc_get(sk), sk_wmem_alloc_get(sk), from_kuid(seq_user_ns(seq), sock_i_uid(sk)), @@ -679,8 +680,9 @@ int bt_procfs_init(struct net *net, const char *name, { sk_list->custom_seq_show = seq_show; - if (!proc_create_seq_data(name, 0, net->proc_net, &bt_seq_ops, sk_list)) - return -ENOMEM; + /*TODO: FIXME */ + //if (!proc_create_seq_data(name, 0, net->proc_net, &bt_seq_ops, sk_list)) + // return -ENOMEM; return 0; } diff --git a/net/bluetooth/ecdh_helper.c b/net/bluetooth/ecdh_helper.c index 2155ce8..9c91522 100644 --- a/net/bluetooth/ecdh_helper.c +++ b/net/bluetooth/ecdh_helper.c @@ -23,6 +23,9 @@ #include "ecdh_helper.h" #include <linux/scatterlist.h> +#if LINUX_VERSION_IS_LESS(4,8,0) +#include <crypto/backport-kpp.h> +#endif #include <crypto/ecdh.h> struct ecdh_completion { diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 3d3b23d..d1ed594 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -1338,9 +1338,13 @@ done: release_sock(sk); return err; } - +#if LINUX_VERSION_IS_LESS(4,17,0) +static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, + int *sockaddr_len, int peer) +#else static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int peer) +#endif { struct sockaddr_hci *haddr = (struct sockaddr_hci *)addr; struct sock *sk = sock->sk; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d17a473..3bfa43f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -33,7 +33,7 @@ #include <linux/debugfs.h> #include <linux/crc16.h> #include <linux/filter.h> - +#include <linux/uio.h> #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> #include <net/bluetooth/l2cap.h> @@ -2119,6 +2119,42 @@ static void l2cap_send_ack(struct l2cap_chan *chan) } } +extern void __compiletime_error("copy source size is too small") +__bad_copy_from(void); +extern void __compiletime_error("copy destination size is too small") +__bad_copy_to(void); + +static inline void copy_overflow(int size, unsigned long count) +{ + WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); +} + +static __always_inline bool +check_copy_size(const void *addr, size_t bytes, bool is_source) +{ + int sz = __compiletime_object_size(addr); + if (unlikely(sz >= 0 && sz < bytes)) { + if (!__builtin_constant_p(bytes)) + copy_overflow(sz, bytes); + else if (is_source) + __bad_copy_from(); + else + __bad_copy_to(); + return false; + } + check_object_size(addr, bytes, is_source); + return true; +} + +static __always_inline __must_check +bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i) +{ + if (unlikely(!check_copy_size(addr, bytes, false))) + return false; + else + return _copy_from_iter_full(addr, bytes, i); +} + static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, struct msghdr *msg, int len, int count, struct sk_buff *skb) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 95b7293..f1e8ed6 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -300,9 +300,13 @@ done: release_sock(sk); return err; } - +#if LINUX_VERSION_IS_LESS(4,12,0) +static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, + int flags) +#else static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags, bool kern) +#endif { DEFINE_WAIT_FUNC(wait, woken_wake_function); struct sock *sk = sock->sk, *nsk; @@ -357,8 +361,13 @@ done: return err; } +#if LINUX_VERSION_IS_LESS(4,17,0) +static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, + int *sockaddr_len, int peer) +#else static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int peer) +#endif { struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; struct sock *sk = sock->sk; @@ -1027,7 +1036,11 @@ static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, goto done; if (pi->rx_busy_skb) { +#if LINUX_VERSION_IS_GEQ(4,7,0) if (!__sock_queue_rcv_skb(sk, pi->rx_busy_skb)) +#else + if (!sock_queue_rcv_skb(sk, pi->rx_busy_skb)) +#endif pi->rx_busy_skb = NULL; else goto done; @@ -1296,7 +1309,11 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) goto done; } +#if LINUX_VERSION_IS_GEQ(4,7,0) err = __sock_queue_rcv_skb(sk, skb); +#else + err = sock_queue_rcv_skb(sk, skb); +#endif /* For ERTM, handle one skb that doesn't fit into the recv * buffer. This is important to do because the data frames diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 2289d6c..2e7e16c 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -351,7 +351,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d) { struct rfcomm_session *s = d->session; - BT_DBG("dlc %p refcnt %d session %p", d, refcount_read(&d->refcnt), s); + BT_DBG("dlc %p refcnt %d session %p", d, refcount_read((const refcount_t *)&d->refcnt), s); list_del(&d->list); d->session = NULL; @@ -872,7 +872,7 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) if (!skb) return -ENOMEM; - cmd = __skb_put(skb, sizeof(*cmd)); + cmd = (void *)__skb_put(skb, sizeof(*cmd)); cmd->addr = d->addr; cmd->ctrl = __ctrl(RFCOMM_DISC, 1); cmd->len = __len8(0); diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 90e1c3b..5d0b0a5 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -205,7 +205,7 @@ static void rfcomm_sock_kill(struct sock *sk) if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) return; - BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, refcount_read(&sk->sk_refcnt)); + BT_DBG("sk %p state %d refcnt %d", sk, sk->sk_state, refcount_read((const refcount_t *)&sk->sk_refcnt)); /* Kill poor orphan */ bt_sock_unlink(&rfcomm_sk_list, sk); @@ -481,8 +481,12 @@ done: return err; } +#if LINUX_VERSION_IS_LESS(4,12,0) +static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags) +#else static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags, bool kern) +#endif { DEFINE_WAIT_FUNC(wait, woken_wake_function); struct sock *sk = sock->sk, *nsk; @@ -542,7 +546,12 @@ done: return err; } +#if LINUX_VERSION_IS_LESS(4,17,0) +static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, + int *sockaddr_len, int peer) +#else static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int peer) +#endif { struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; struct sock *sk = sock->sk; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 2ece5af..2ee2bd5 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -623,9 +623,13 @@ done: release_sock(sk); return err; } - +#if LINUX_VERSION_IS_LESS(4,12,0) +static int sco_sock_accept(struct socket *sock, struct socket *newsock, + int flags) +#else static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags, bool kern) +#endif { DEFINE_WAIT_FUNC(wait, woken_wake_function); struct sock *sk = sock->sk, *ch; @@ -678,9 +682,13 @@ done: release_sock(sk); return err; } - +#if LINUX_VERSION_IS_LESS(4,17,0) +static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, + int *sockaddr_len, int peer) +#else static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int peer) +#endif { struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; |