summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorWillem de Bruijn <willemb@google.com>2016-07-12 18:18:56 -0400
committerBen Hutchings <ben@decadent.org.uk>2017-02-23 03:54:46 +0000
commitd0fb92f2ca9b8c3ba10047b5e134cd7d1459cc1c (patch)
treec604ee27806ef2a3ad809d5f80658b460f7ad9b0 /include
parentbed7167a188ec74018825232eeee67e2032275f8 (diff)
rose: limit sk_filter trim to payload
commit f4979fcea7fd36d8e2f556abef86f80e0d5af1ba upstream. Sockets can have a filter program attached that drops or trims incoming packets based on the filter program return value. Rose requires data packets to have at least ROSE_MIN_LEN bytes. It verifies this on arrival in rose_route_frame and unconditionally pulls the bytes in rose_recvmsg. The filter can trim packets to below this value in-between, causing pull to fail, leaving the partial header at the time of skb_copy_datagram_msg. Place a lower bound on the size to which sk_filter may trim packets by introducing sk_filter_trim_cap and call this for rose packets. Signed-off-by: Willem de Bruijn <willemb@google.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'include')
-rw-r--r--include/linux/filter.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 96509e579d21..bdc6f86e7897 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -346,7 +346,11 @@ static inline unsigned int sk_filter_size(unsigned int proglen)
#define sk_filter_proglen(fprog) \
(fprog->len * sizeof(fprog->filter[0]))
-int sk_filter(struct sock *sk, struct sk_buff *skb);
+int sk_filter_trim_cap(struct sock *sk, struct sk_buff *skb, unsigned int cap);
+static inline int sk_filter(struct sock *sk, struct sk_buff *skb)
+{
+ return sk_filter_trim_cap(sk, skb, 1);
+}
void sk_filter_select_runtime(struct sk_filter *fp);
void sk_filter_free(struct sk_filter *fp);