aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h2
-rw-r--r--net/core/filter.c5
-rw-r--r--net/ipv4/ipcomp.c7
-rw-r--r--net/ipv4/tcp_output.c4
-rw-r--r--net/ipv6/exthdrs.c16
-rw-r--r--net/ipv6/ip6_input.c3
-rw-r--r--net/ipv6/xfrm6_policy.c8
-rw-r--r--net/tipc/name_distr.c3
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
233extern int ipv6_parse_hopopts(struct sk_buff *skb, int); 233extern int ipv6_parse_hopopts(struct sk_buff *skb);
234 234
235extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); 235extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
236extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, 236extern 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
177load_w: 178load_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:
186load_h: 187load_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
488int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) 488int 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:
191static inline void 191static 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/**