* Re: [RFT] remove skb_linearize from igmp.c
2003-06-23 19:03 [RFT] remove skb_linearize from igmp.c Stephen Hemminger
@ 2003-06-23 19:02 ` David S. Miller
2003-06-23 19:41 ` Stephen Hemminger
0 siblings, 1 reply; 4+ messages in thread
From: David S. Miller @ 2003-06-23 19:02 UTC (permalink / raw)
To: shemminger; +Cc: netdev
From: Stephen Hemminger <shemminger@osdl.org>
Date: Mon, 23 Jun 2003 12:03:42 -0700
Could someone who actually receives IGMP packets test this?
Don't bother, your patch is buggy.
int len = skb->len;
...
+ if (!pskb_may_pull(skb, sizeof(struct igmphdr)))
+ goto drop;
+
+ ih = skb->h.igmph;
+ if (ip_compute_csum((void *)ih, len))
+ goto drop;
You're only verifying that "sizeof(struct igmphdr)" is available at
skb->data, then you dereference "len" bytes via the call to
ip_compute_csum().
^ permalink raw reply [flat|nested] 4+ messages in thread
* [RFT] remove skb_linearize from igmp.c
@ 2003-06-23 19:03 Stephen Hemminger
2003-06-23 19:02 ` David S. Miller
0 siblings, 1 reply; 4+ messages in thread
From: Stephen Hemminger @ 2003-06-23 19:03 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
This patch gets rid of the deprecated skb_linearize call in IGMP by
using pskb_may_pull like ip_input does.
Could someone who actually receives IGMP packets test this?
diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c
--- a/net/ipv4/igmp.c Mon Jun 23 11:59:56 2003
+++ b/net/ipv4/igmp.c Mon Jun 23 11:59:56 2003
@@ -838,28 +838,19 @@
int igmp_rcv(struct sk_buff *skb)
{
/* This basically follows the spec line by line -- see RFC1112 */
- struct igmphdr *ih = skb->h.igmph;
+ struct igmphdr *ih;
struct in_device *in_dev = in_dev_get(skb->dev);
int len = skb->len;
- if (in_dev==NULL) {
- kfree_skb(skb);
- return 0;
- }
-
- if (skb_is_nonlinear(skb)) {
- if (skb_linearize(skb, GFP_ATOMIC) != 0) {
- kfree_skb(skb);
- return -ENOMEM;
- }
- ih = skb->h.igmph;
- }
+ if (in_dev==NULL)
+ goto out;
- if (len < sizeof(struct igmphdr) || ip_compute_csum((void *)ih, len)) {
- in_dev_put(in_dev);
- kfree_skb(skb);
- return 0;
- }
+ if (!pskb_may_pull(skb, sizeof(struct igmphdr)))
+ goto drop;
+
+ ih = skb->h.igmph;
+ if (ip_compute_csum((void *)ih, len))
+ goto drop;
switch (ih->type) {
case IGMP_HOST_MEMBERSHIP_QUERY:
@@ -887,7 +878,9 @@
default:
NETDEBUG(printk(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type));
}
+ drop:
in_dev_put(in_dev);
+ out:
kfree_skb(skb);
return 0;
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFT] remove skb_linearize from igmp.c
2003-06-23 19:02 ` David S. Miller
@ 2003-06-23 19:41 ` Stephen Hemminger
2003-06-23 20:17 ` David S. Miller
0 siblings, 1 reply; 4+ messages in thread
From: Stephen Hemminger @ 2003-06-23 19:41 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev
Try again... this time add pullup logic to the query processing, and
use skb_checksum to handle non-linear buffers.
--- linux-2.5.73/net/ipv4/igmp.c 2003-06-23 11:39:50.000000000 -0700
+++ linux-2.5-sysfs/net/ipv4/igmp.c 2003-06-23 12:37:57.000000000 -0700
@@ -757,17 +757,16 @@ static void igmp_heard_report(struct in_
read_unlock(&in_dev->lock);
}
-static void igmp_heard_query(struct in_device *in_dev, struct igmphdr *ih,
- int len)
+static void igmp_heard_query(struct in_device *in_dev, struct sk_buff *skb)
{
+ struct igmphdr *ih = skb->h.igmph;
struct igmpv3_query *ih3 = (struct igmpv3_query *)ih;
struct ip_mc_list *im;
u32 group = ih->group;
int max_delay;
int mark = 0;
-
- if (len == 8) {
+ if (skb->len == 8) {
if (ih->code == 0) {
/* Alas, old v1 router presents here. */
@@ -787,9 +786,14 @@ static void igmp_heard_query(struct in_d
__in_dev_put(in_dev);
/* clear deleted report items */
igmpv3_clear_delrec(in_dev);
- } else if (len < 12) {
+ } else if (skb->len < 12) {
return; /* ignore bogus packet; freed by caller */
} else { /* v3 */
+ if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
+ return;
+
+ ih3 = (struct igmpv3_query *)(ih = skb->h.igmph);
+
max_delay = IGMPV3_MRC(ih3->code)*(HZ/IGMP_TIMER_SCALE);
if (!max_delay)
max_delay = 1; /* can't mod w/ 0 */
@@ -803,7 +807,13 @@ static void igmp_heard_query(struct in_d
return;
}
/* mark sources to include, if group & source-specific */
- mark = ih3->nsrcs != 0;
+ if ((mark = (ih3->nsrcs != 0))) {
+ if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)
+ + ntohs(ih3->nsrcs) * sizeof(ih3->srcs[0])))
+ return;
+
+ ih3 = (struct igmpv3_query *)(ih = skb->h.igmph);
+ }
}
/*
@@ -838,32 +848,23 @@ static void igmp_heard_query(struct in_d
int igmp_rcv(struct sk_buff *skb)
{
/* This basically follows the spec line by line -- see RFC1112 */
- struct igmphdr *ih = skb->h.igmph;
+ struct igmphdr *ih;
struct in_device *in_dev = in_dev_get(skb->dev);
- int len = skb->len;
- if (in_dev==NULL) {
- kfree_skb(skb);
- return 0;
- }
+ if (in_dev==NULL)
+ goto out;
- if (skb_is_nonlinear(skb)) {
- if (skb_linearize(skb, GFP_ATOMIC) != 0) {
- kfree_skb(skb);
- return -ENOMEM;
- }
- ih = skb->h.igmph;
- }
+ if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
+ goto drop;
- if (len < sizeof(struct igmphdr) || ip_compute_csum((void *)ih, len)) {
- in_dev_put(in_dev);
- kfree_skb(skb);
- return 0;
- }
+ if (!pskb_may_pull(skb, sizeof(struct igmphdr)))
+ goto drop;
+
+ ih = skb->h.igmph;
switch (ih->type) {
case IGMP_HOST_MEMBERSHIP_QUERY:
- igmp_heard_query(in_dev, ih, len);
+ igmp_heard_query(in_dev, skb);
break;
case IGMP_HOST_MEMBERSHIP_REPORT:
case IGMPV2_HOST_MEMBERSHIP_REPORT:
@@ -887,7 +888,9 @@ int igmp_rcv(struct sk_buff *skb)
default:
NETDEBUG(printk(KERN_DEBUG "New IGMP type=%d, why we do not know about it?\n", ih->type));
}
+ drop:
in_dev_put(in_dev);
+ out:
kfree_skb(skb);
return 0;
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFT] remove skb_linearize from igmp.c
2003-06-23 19:41 ` Stephen Hemminger
@ 2003-06-23 20:17 ` David S. Miller
0 siblings, 0 replies; 4+ messages in thread
From: David S. Miller @ 2003-06-23 20:17 UTC (permalink / raw)
To: shemminger; +Cc: netdev
From: Stephen Hemminger <shemminger@osdl.org>
Date: Mon, 23 Jun 2003 12:41:18 -0700
Try again... this time add pullup logic to the query processing, and
use skb_checksum to handle non-linear buffers.
I'll let this one sit for a day or so in order to get some
testing done :-)
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-06-23 20:17 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-06-23 19:03 [RFT] remove skb_linearize from igmp.c Stephen Hemminger
2003-06-23 19:02 ` David S. Miller
2003-06-23 19:41 ` Stephen Hemminger
2003-06-23 20:17 ` David S. Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).