* [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: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
* 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).