Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1244230 > unrolled thread

[PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

Started byBen Cartwright-Cox <ben@benjojo.co.uk>
First post2015-10-11 23:40 +0200
Last post2015-10-12 01:40 +0200
Articles 8 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP  counter values Ben Cartwright-Cox <ben@benjojo.co.uk> - 2015-10-11 23:40 +0200
    Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP  SNMP counter values Eric Dumazet <eric.dumazet@gmail.com> - 2015-10-12 00:20 +0200
      Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP  SNMP counter values Ben Cox <ben@benjojo.co.uk> - 2015-10-12 00:20 +0200
        Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP  SNMP counter values Eric Dumazet <eric.dumazet@gmail.com> - 2015-10-12 00:50 +0200
          Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP  SNMP counter values Eric Dumazet <eric.dumazet@gmail.com> - 2015-10-12 00:50 +0200
            Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP  SNMP counter values Eric Dumazet <eric.dumazet@gmail.com> - 2015-10-12 01:20 +0200
              Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP  SNMP counter values Ben Cox <ben@benjojo.co.uk> - 2015-10-12 01:20 +0200
                Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP  SNMP counter values Eric Dumazet <eric.dumazet@gmail.com> - 2015-10-12 01:40 +0200

#1244230 — [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromBen Cartwright-Cox <ben@benjojo.co.uk>
Date2015-10-11 23:40 +0200
Subject[PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qiwvw-3Qd-15@gated-at.bofh.it>
Sending ICMP packets with raw sockets ends up in the SNMP counters
logging the type as the first byte of the IPv4 header rather than
the ICMP header (in nearly all cases this is seen as "OutType69".
This is fixed by adding the IP Header Length to the casting into
a icmphdr struct.

Signed-off-by: Ben Cartwright-Cox <ben@benjojo.co.uk>
---
 net/ipv4/raw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 561cd4b..1ad8bae 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -409,7 +409,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
 	}
 	if (iph->protocol == IPPROTO_ICMP)
 		icmp_out_count(net, ((struct icmphdr *)
-			skb_transport_header(skb))->type);
+			skb_transport_header(skb) + iphlen)->type);
 
 	err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb,
 		      NULL, rt->dst.dev, dst_output_sk);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1244239 — Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromEric Dumazet <eric.dumazet@gmail.com>
Date2015-10-12 00:20 +0200
SubjectRe: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qix8d-4PI-1@gated-at.bofh.it>
In reply to#1244230
On Sun, 2015-10-11 at 20:55 +0000, Ben Cartwright-Cox wrote:
> Sending ICMP packets with raw sockets ends up in the SNMP counters
> logging the type as the first byte of the IPv4 header rather than
> the ICMP header (in nearly all cases this is seen as "OutType69".
> This is fixed by adding the IP Header Length to the casting into
> a icmphdr struct.
> 
> Signed-off-by: Ben Cartwright-Cox <ben@benjojo.co.uk>
> ---
>  net/ipv4/raw.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
> index 561cd4b..1ad8bae 100644
> --- a/net/ipv4/raw.c
> +++ b/net/ipv4/raw.c
> @@ -409,7 +409,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
>  	}
>  	if (iph->protocol == IPPROTO_ICMP)
>  		icmp_out_count(net, ((struct icmphdr *)
> -			skb_transport_header(skb))->type);
> +			skb_transport_header(skb) + iphlen)->type);
>  
>  	err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb,
>  		      NULL, rt->dst.dev, dst_output_sk);


Hmm... This seems to lack checks against a malicious user ?

The only guarantee you have here is that iphlen < length.

It is not enough.

Make sure you do not access not initialized memory or even non existent
one.



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1244240 — Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromBen Cox <ben@benjojo.co.uk>
Date2015-10-12 00:20 +0200
SubjectRe: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qix8e-4PI-15@gated-at.bofh.it>
In reply to#1244239
Forgive me for possibly being a little stupid here (This is my first
patch to Linux so I am slightly over my head)

Is this issue not addressed above the file where the following check is done?

if (iphlen > length)
    goto error_free;



On Sun, Oct 11, 2015 at 11:10 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Sun, 2015-10-11 at 20:55 +0000, Ben Cartwright-Cox wrote:
>> Sending ICMP packets with raw sockets ends up in the SNMP counters
>> logging the type as the first byte of the IPv4 header rather than
>> the ICMP header (in nearly all cases this is seen as "OutType69".
>> This is fixed by adding the IP Header Length to the casting into
>> a icmphdr struct.
>>
>> Signed-off-by: Ben Cartwright-Cox <ben@benjojo.co.uk>
>> ---
>>  net/ipv4/raw.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
>> index 561cd4b..1ad8bae 100644
>> --- a/net/ipv4/raw.c
>> +++ b/net/ipv4/raw.c
>> @@ -409,7 +409,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
>>       }
>>       if (iph->protocol == IPPROTO_ICMP)
>>               icmp_out_count(net, ((struct icmphdr *)
>> -                     skb_transport_header(skb))->type);
>> +                     skb_transport_header(skb) + iphlen)->type);
>>
>>       err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb,
>>                     NULL, rt->dst.dev, dst_output_sk);
>
>
> Hmm... This seems to lack checks against a malicious user ?
>
> The only guarantee you have here is that iphlen < length.
>
> It is not enough.
>
> Make sure you do not access not initialized memory or even non existent
> one.
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1244243 — Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromEric Dumazet <eric.dumazet@gmail.com>
Date2015-10-12 00:50 +0200
SubjectRe: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qixBg-5nH-1@gated-at.bofh.it>
In reply to#1244240
On Sun, 2015-10-11 at 23:17 +0100, Ben Cox wrote:
> Forgive me for possibly being a little stupid here (This is my first
> patch to Linux so I am slightly over my head)
> 
> Is this issue not addressed above the file where the following check is done?
> 
> if (iphlen > length)
>     goto error_free;
> 

Imagine someone sends a frame, pretending it is ICMP, but containing
only the IPv4 header. And not a _single_ byte more.

length = 20

iphlen = 20 (if say ihl == 5)

We copied 20 bytes from user land.

But your code reads 21th byte.



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1244244 — Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromEric Dumazet <eric.dumazet@gmail.com>
Date2015-10-12 00:50 +0200
SubjectRe: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qixBg-5nH-5@gated-at.bofh.it>
In reply to#1244243
On Sun, 2015-10-11 at 15:43 -0700, Eric Dumazet wrote:

> But your code reads 21th byte.

BTW, nice catch !

Your patch only need a small addition.

Thanks.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1244287 — Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromEric Dumazet <eric.dumazet@gmail.com>
Date2015-10-12 01:20 +0200
SubjectRe: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qiy4h-6cW-5@gated-at.bofh.it>
In reply to#1244244
On Sun, 2015-10-11 at 15:44 -0700, Eric Dumazet wrote:
> On Sun, 2015-10-11 at 15:43 -0700, Eric Dumazet wrote:
> 
> > But your code reads 21th byte.
> 
> BTW, nice catch !

Maybe the following one.

1) We properly set transport header
2) We use icmp_hdr() helper.

diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 561cd4b8fc6e..ffe25cd1f0e0 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -406,11 +406,11 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
 			ip_select_ident(net, skb, NULL);
 
 		iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+		skb->transport_header += iphlen;
+		if (iph->protocol == IPPROTO_ICMP &&
+		    length >= iphlen + sizeof(struct icmphdr))
+			icmp_out_count(net, icmp_hdr(skb)->type);
 	}
-	if (iph->protocol == IPPROTO_ICMP)
-		icmp_out_count(net, ((struct icmphdr *)
-			skb_transport_header(skb))->type);
-
 	err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb,
 		      NULL, rt->dst.dev, dst_output_sk);
 	if (err > 0)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1244291 — Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromBen Cox <ben@benjojo.co.uk>
Date2015-10-12 01:20 +0200
SubjectRe: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qiy4h-6cW-17@gated-at.bofh.it>
In reply to#1244287
Nice!

That works in my head at least, Sorry about not seeing that fairly
glaring memory issue there.

Are you sure " skb->transport_header += iphlen; " won't have a knock
on affect when it's given to NF_HOOK ( as in, would a potential
userspace program get something it does not expect anymore ) ?

How does submission work at this point if the above is not a issue
(apologies if this is already in a FAQ somewhere I missed)?

On Mon, Oct 12, 2015 at 12:09 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Sun, 2015-10-11 at 15:44 -0700, Eric Dumazet wrote:
>> On Sun, 2015-10-11 at 15:43 -0700, Eric Dumazet wrote:
>>
>> > But your code reads 21th byte.
>>
>> BTW, nice catch !
>
> Maybe the following one.
>
> 1) We properly set transport header
> 2) We use icmp_hdr() helper.
>
> diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
> index 561cd4b8fc6e..ffe25cd1f0e0 100644
> --- a/net/ipv4/raw.c
> +++ b/net/ipv4/raw.c
> @@ -406,11 +406,11 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
>                         ip_select_ident(net, skb, NULL);
>
>                 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
> +               skb->transport_header += iphlen;
> +               if (iph->protocol == IPPROTO_ICMP &&
> +                   length >= iphlen + sizeof(struct icmphdr))
> +                       icmp_out_count(net, icmp_hdr(skb)->type);
>         }
> -       if (iph->protocol == IPPROTO_ICMP)
> -               icmp_out_count(net, ((struct icmphdr *)
> -                       skb_transport_header(skb))->type);
> -
>         err = NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, sk, skb,
>                       NULL, rt->dst.dev, dst_output_sk);
>         if (err > 0)
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1244300 — Re: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values

FromEric Dumazet <eric.dumazet@gmail.com>
Date2015-10-12 01:40 +0200
SubjectRe: [PATCH] icmp: Fixed bug in raw sockets causing incorrect ICMP SNMP counter values
Message-ID<qiynD-6zp-7@gated-at.bofh.it>
In reply to#1244291
Please do not top-post on netdev and/or lkml


On Mon, 2015-10-12 at 00:14 +0100, Ben Cox wrote:
> Nice!
> 
> That works in my head at least, Sorry about not seeing that fairly
> glaring memory issue there.

No problem, this is why we review patches ;)

> 
> Are you sure " skb->transport_header += iphlen; " won't have a knock
> on affect when it's given to NF_HOOK ( as in, would a potential
> userspace program get something it does not expect anymore ) ?


netfilter does not depend on transport_header being set (otherwise as
you can see RAW packets would have problems with netfilter since the
very beginning.


> How does submission work at this point if the above is not a issue
> (apologies if this is already in a FAQ somewhere I missed)?
> 

Just send a V2 of the patch, using following title :

[PATCH v2 net] raw: increment correct SNMP counters for ICMP messages


I'll add my 'Acked-by:' after your 'Signed-off-by:'

Thanks !


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web