| From 105f5528b9bbaa08b526d3405a5bcd2ff0c953c8 Mon Sep 17 00:00:00 2001 |
| From: Jamie Bainbridge <jbainbri@redhat.com> |
| Date: Wed, 26 Apr 2017 10:43:27 +1000 |
| Subject: [PATCH] ipv6: check raw payload size correctly in ioctl |
| |
| commit 105f5528b9bbaa08b526d3405a5bcd2ff0c953c8 upstream. |
| |
| In situations where an skb is paged, the transport header pointer and |
| tail pointer can be the same because the skb contents are in frags. |
| |
| This results in ioctl(SIOCINQ/FIONREAD) incorrectly returning a |
| length of 0 when the length to receive is actually greater than zero. |
| |
| skb->len is already correctly set in ip6_input_finish() with |
| pskb_pull(), so use skb->len as it always returns the correct result |
| for both linear and paged data. |
| |
| Signed-off-by: Jamie Bainbridge <jbainbri@redhat.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| |
| diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c |
| index f174e76e6505..0da6a12b5472 100644 |
| --- a/net/ipv6/raw.c |
| +++ b/net/ipv6/raw.c |
| @@ -1178,8 +1178,7 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) |
| spin_lock_bh(&sk->sk_receive_queue.lock); |
| skb = skb_peek(&sk->sk_receive_queue); |
| if (skb) |
| - amount = skb_tail_pointer(skb) - |
| - skb_transport_header(skb); |
| + amount = skb->len; |
| spin_unlock_bh(&sk->sk_receive_queue.lock); |
| return put_user(amount, (int __user *)arg); |
| } |
| -- |
| 2.12.0 |
| |