diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-18 21:03:22 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-04-18 21:03:22 -0400 |
| commit | 5c723d26fa223bdb17b9230c77e4e1156884475a (patch) | |
| tree | 03487f55b11cdfa5d3f0edf655fa2351f7d4ed53 | |
| parent | a196e7880905313773be97dbca5aa7b0a0aed71c (diff) | |
| parent | 63903ca6af3d9424a0c2b176f927fa7e7ab2ae8e (diff) | |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
[NET]: Remove redundant NULL checks before [kv]free
unaligned access in sk_run_filter()
[IPV6]: Clean up hop-by-hop options handler.
[IPV6] XFRM: Fix decoding session with preceding extension header(s).
[IPV6] XFRM: Don't use old copy of pointer after pskb_may_pull().
[IPV6]: Ensure to have hop-by-hop options in our header of &sk_buff.
[TCP]: Fix truesize underflow
| -rw-r--r-- | include/net/ipv6.h | 2 | ||||
| -rw-r--r-- | net/core/filter.c | 5 | ||||
| -rw-r--r-- | net/ipv4/ipcomp.c | 7 | ||||
| -rw-r--r-- | net/ipv4/tcp_output.c | 4 | ||||
| -rw-r--r-- | net/ipv6/exthdrs.c | 16 | ||||
| -rw-r--r-- | net/ipv6/ip6_input.c | 3 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_policy.c | 8 | ||||
| -rw-r--r-- | net/tipc/name_distr.c | 3 |
8 files changed, 30 insertions, 18 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 6d6f0634ae41..4abedb8eaece 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
| @@ -230,7 +230,7 @@ extern int ip6_ra_control(struct sock *sk, int sel, | |||
| 230 | void (*destructor)(struct sock *)); | 230 | void (*destructor)(struct sock *)); |
| 231 | 231 | ||
| 232 | 232 | ||
| 233 | extern int ipv6_parse_hopopts(struct sk_buff *skb, int); | 233 | extern int ipv6_parse_hopopts(struct sk_buff *skb); |
| 234 | 234 | ||
| 235 | extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); | 235 | extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); |
| 236 | extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, | 236 | extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, |
diff --git a/net/core/filter.c b/net/core/filter.c index 93fbd01d2259..5b4486a60cf6 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
| 35 | #include <asm/system.h> | 35 | #include <asm/system.h> |
| 36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 37 | #include <asm/unaligned.h> | ||
| 37 | #include <linux/filter.h> | 38 | #include <linux/filter.h> |
| 38 | 39 | ||
| 39 | /* No hurry in this branch */ | 40 | /* No hurry in this branch */ |
| @@ -177,7 +178,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int | |||
| 177 | load_w: | 178 | load_w: |
| 178 | ptr = load_pointer(skb, k, 4, &tmp); | 179 | ptr = load_pointer(skb, k, 4, &tmp); |
| 179 | if (ptr != NULL) { | 180 | if (ptr != NULL) { |
| 180 | A = ntohl(*(u32 *)ptr); | 181 | A = ntohl(get_unaligned((u32 *)ptr)); |
| 181 | continue; | 182 | continue; |
| 182 | } | 183 | } |
| 183 | break; | 184 | break; |
| @@ -186,7 +187,7 @@ load_w: | |||
| 186 | load_h: | 187 | load_h: |
| 187 | ptr = load_pointer(skb, k, 2, &tmp); | 188 | ptr = load_pointer(skb, k, 2, &tmp); |
| 188 | if (ptr != NULL) { | 189 | if (ptr != NULL) { |
| 189 | A = ntohs(*(u16 *)ptr); | 190 | A = ntohs(get_unaligned((u16 *)ptr)); |
| 190 | continue; | 191 | continue; |
| 191 | } | 192 | } |
| 192 | break; | 193 | break; |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 04a429465665..cd810f41af1a 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
| @@ -290,11 +290,8 @@ static void ipcomp_free_scratches(void) | |||
| 290 | if (!scratches) | 290 | if (!scratches) |
| 291 | return; | 291 | return; |
| 292 | 292 | ||
| 293 | for_each_possible_cpu(i) { | 293 | for_each_possible_cpu(i) |
| 294 | void *scratch = *per_cpu_ptr(scratches, i); | 294 | vfree(*per_cpu_ptr(scratches, i)); |
| 295 | if (scratch) | ||
| 296 | vfree(scratch); | ||
| 297 | } | ||
| 298 | 295 | ||
| 299 | free_percpu(scratches); | 296 | free_percpu(scratches); |
| 300 | } | 297 | } |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index b871db6adc55..44df1db726a3 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -551,7 +551,9 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss | |||
| 551 | buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); | 551 | buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); |
| 552 | if (buff == NULL) | 552 | if (buff == NULL) |
| 553 | return -ENOMEM; /* We'll just try again later. */ | 553 | return -ENOMEM; /* We'll just try again later. */ |
| 554 | sk_charge_skb(sk, buff); | 554 | |
| 555 | buff->truesize = skb->len - len; | ||
| 556 | skb->truesize -= buff->truesize; | ||
| 555 | 557 | ||
| 556 | /* Correct the sequence numbers. */ | 558 | /* Correct the sequence numbers. */ |
| 557 | TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; | 559 | TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 2a1e7e45b890..a18d4256372c 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
| @@ -485,15 +485,27 @@ static struct tlvtype_proc tlvprochopopt_lst[] = { | |||
| 485 | { -1, } | 485 | { -1, } |
| 486 | }; | 486 | }; |
| 487 | 487 | ||
| 488 | int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) | 488 | int ipv6_parse_hopopts(struct sk_buff *skb) |
| 489 | { | 489 | { |
| 490 | struct inet6_skb_parm *opt = IP6CB(skb); | 490 | struct inet6_skb_parm *opt = IP6CB(skb); |
| 491 | 491 | ||
| 492 | /* | ||
| 493 | * skb->nh.raw is equal to skb->data, and | ||
| 494 | * skb->h.raw - skb->nh.raw is always equal to | ||
| 495 | * sizeof(struct ipv6hdr) by definition of | ||
| 496 | * hop-by-hop options. | ||
| 497 | */ | ||
| 498 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || | ||
| 499 | !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { | ||
| 500 | kfree_skb(skb); | ||
| 501 | return -1; | ||
| 502 | } | ||
| 503 | |||
| 492 | opt->hop = sizeof(struct ipv6hdr); | 504 | opt->hop = sizeof(struct ipv6hdr); |
| 493 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { | 505 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { |
| 494 | skb->h.raw += (skb->h.raw[1]+1)<<3; | 506 | skb->h.raw += (skb->h.raw[1]+1)<<3; |
| 495 | opt->nhoff = sizeof(struct ipv6hdr); | 507 | opt->nhoff = sizeof(struct ipv6hdr); |
| 496 | return sizeof(struct ipv6hdr); | 508 | return 1; |
| 497 | } | 509 | } |
| 498 | return -1; | 510 | return -1; |
| 499 | } | 511 | } |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 29f73592e68e..aceee252503d 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
| @@ -114,11 +114,10 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | if (hdr->nexthdr == NEXTHDR_HOP) { | 116 | if (hdr->nexthdr == NEXTHDR_HOP) { |
| 117 | if (ipv6_parse_hopopts(skb, IP6CB(skb)->nhoff) < 0) { | 117 | if (ipv6_parse_hopopts(skb) < 0) { |
| 118 | IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | 118 | IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); |
| 119 | return 0; | 119 | return 0; |
| 120 | } | 120 | } |
| 121 | hdr = skb->nh.ipv6h; | ||
| 122 | } | 121 | } |
| 123 | 122 | ||
| 124 | return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); | 123 | return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 91cce8b2d7a5..88c840f1beb6 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -191,16 +191,18 @@ error: | |||
| 191 | static inline void | 191 | static inline void |
| 192 | _decode_session6(struct sk_buff *skb, struct flowi *fl) | 192 | _decode_session6(struct sk_buff *skb, struct flowi *fl) |
| 193 | { | 193 | { |
| 194 | u16 offset = sizeof(struct ipv6hdr); | 194 | u16 offset = skb->h.raw - skb->nh.raw; |
| 195 | struct ipv6hdr *hdr = skb->nh.ipv6h; | 195 | struct ipv6hdr *hdr = skb->nh.ipv6h; |
| 196 | struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); | 196 | struct ipv6_opt_hdr *exthdr; |
| 197 | u8 nexthdr = skb->nh.ipv6h->nexthdr; | 197 | u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff]; |
| 198 | 198 | ||
| 199 | memset(fl, 0, sizeof(struct flowi)); | 199 | memset(fl, 0, sizeof(struct flowi)); |
| 200 | ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); | 200 | ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); |
| 201 | ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); | 201 | ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); |
| 202 | 202 | ||
| 203 | while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { | 203 | while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { |
| 204 | exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); | ||
| 205 | |||
| 204 | switch (nexthdr) { | 206 | switch (nexthdr) { |
| 205 | case NEXTHDR_ROUTING: | 207 | case NEXTHDR_ROUTING: |
| 206 | case NEXTHDR_HOP: | 208 | case NEXTHDR_HOP: |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 953307a9df1d..a3bbc891f959 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
| @@ -229,8 +229,7 @@ static void node_is_down(struct publication *publ) | |||
| 229 | publ->node, publ->ref, publ->key); | 229 | publ->node, publ->ref, publ->key); |
| 230 | assert(p == publ); | 230 | assert(p == publ); |
| 231 | write_unlock_bh(&tipc_nametbl_lock); | 231 | write_unlock_bh(&tipc_nametbl_lock); |
| 232 | if (publ) | 232 | kfree(publ); |
| 233 | kfree(publ); | ||
| 234 | } | 233 | } |
| 235 | 234 | ||
| 236 | /** | 235 | /** |
