From 198e79f0e8f0b24c1e36ab6032d348f40de20262 Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Fri, 22 Dec 2017 12:07:34 +0000 Subject: backports: bluetooth: Support 4.9 kernels Signed-off-by: Dominik Sliwa --- net/bluetooth/l2cap_core.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'net/bluetooth/l2cap_core.c') diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9800324..a1a9b4c 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -33,7 +33,7 @@ #include #include #include - +#include #include #include #include @@ -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) -- cgit v1.2.3