Skip to content
This repository has been archived by the owner on Jul 13, 2022. It is now read-only.

Commit

Permalink
ipv6: raw: fix icmpv6_filter()
Browse files Browse the repository at this point in the history
[ Upstream commit 1b05c4b50edbddbdde715c4a7350629819f6655e ]

icmpv6_filter() should not modify its input, or else its caller
would need to recompute ipv6_hdr() if skb->head is reallocated.

Use skb_header_pointer() instead of pskb_may_pull() and
change the prototype to make clear both sk and skb are const.

Also, if icmpv6 header cannot be found, do not deliver the packet,
as we do in IPv4.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Eric Dumazet authored and gregkh committed Oct 12, 2012
1 parent a1b995a commit 27ab68c
Showing 1 changed file with 10 additions and 11 deletions.
21 changes: 10 additions & 11 deletions net/ipv6/raw.c
Expand Up @@ -106,21 +106,20 @@ static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
* 0 - deliver
* 1 - block
*/
static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb)
static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb)
{
struct icmp6hdr *icmph;
struct raw6_sock *rp = raw6_sk(sk);

if (pskb_may_pull(skb, sizeof(struct icmp6hdr))) {
__u32 *data = &rp->filter.data[0];
int bit_nr;
struct icmp6hdr *_hdr;
const struct icmp6hdr *hdr;

icmph = (struct icmp6hdr *) skb->data;
bit_nr = icmph->icmp6_type;
hdr = skb_header_pointer(skb, skb_transport_offset(skb),
sizeof(_hdr), &_hdr);
if (hdr) {
const __u32 *data = &raw6_sk(sk)->filter.data[0];
unsigned int type = hdr->icmp6_type;

return (data[bit_nr >> 5] & (1 << (bit_nr & 31))) != 0;
return (data[type >> 5] & (1U << (type & 31))) != 0;
}
return 0;
return 1;
}

#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
Expand Down

0 comments on commit 27ab68c

Please sign in to comment.