diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-12-07 16:35:17 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-12-07 16:35:17 -0500 |
commit | 21b4e736922f546e0f1aa7b9d6c442f309a2444a (patch) | |
tree | e1be8645297f8ebe87445251743ebcc52081a20d /net/ipv4 | |
parent | 34161db6b14d984fb9b06c735b7b42f8803f6851 (diff) | |
parent | 68380b581383c028830f79ec2670f4a193854aa6 (diff) |
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/ into merge_linus
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/fib_hash.c | 8 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 6 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 6 | ||||
-rw-r--r-- | net/ipv4/inet_timewait_sock.c | 3 | ||||
-rw-r--r-- | net/ipv4/inetpeer.c | 2 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 2 | ||||
-rw-r--r-- | net/ipv4/ipvs/ip_vs_conn.c | 2 | ||||
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 48 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 144 | ||||
-rw-r--r-- | net/ipv4/route.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 4 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 2 |
13 files changed, 120 insertions, 113 deletions
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 107bb6cbb0b3..648f47c1c399 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c | |||
@@ -45,8 +45,8 @@ | |||
45 | 45 | ||
46 | #include "fib_lookup.h" | 46 | #include "fib_lookup.h" |
47 | 47 | ||
48 | static kmem_cache_t *fn_hash_kmem __read_mostly; | 48 | static struct kmem_cache *fn_hash_kmem __read_mostly; |
49 | static kmem_cache_t *fn_alias_kmem __read_mostly; | 49 | static struct kmem_cache *fn_alias_kmem __read_mostly; |
50 | 50 | ||
51 | struct fib_node { | 51 | struct fib_node { |
52 | struct hlist_node fn_hash; | 52 | struct hlist_node fn_hash; |
@@ -485,13 +485,13 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg) | |||
485 | goto out; | 485 | goto out; |
486 | 486 | ||
487 | err = -ENOBUFS; | 487 | err = -ENOBUFS; |
488 | new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); | 488 | new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); |
489 | if (new_fa == NULL) | 489 | if (new_fa == NULL) |
490 | goto out; | 490 | goto out; |
491 | 491 | ||
492 | new_f = NULL; | 492 | new_f = NULL; |
493 | if (!f) { | 493 | if (!f) { |
494 | new_f = kmem_cache_alloc(fn_hash_kmem, SLAB_KERNEL); | 494 | new_f = kmem_cache_alloc(fn_hash_kmem, GFP_KERNEL); |
495 | if (new_f == NULL) | 495 | if (new_f == NULL) |
496 | goto out_free_new_fa; | 496 | goto out_free_new_fa; |
497 | 497 | ||
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index d17990ec724f..cfb249cc0a58 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -172,7 +172,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn); | |||
172 | static struct tnode *halve(struct trie *t, struct tnode *tn); | 172 | static struct tnode *halve(struct trie *t, struct tnode *tn); |
173 | static void tnode_free(struct tnode *tn); | 173 | static void tnode_free(struct tnode *tn); |
174 | 174 | ||
175 | static kmem_cache_t *fn_alias_kmem __read_mostly; | 175 | static struct kmem_cache *fn_alias_kmem __read_mostly; |
176 | static struct trie *trie_local = NULL, *trie_main = NULL; | 176 | static struct trie *trie_local = NULL, *trie_main = NULL; |
177 | 177 | ||
178 | 178 | ||
@@ -1187,7 +1187,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1187 | u8 state; | 1187 | u8 state; |
1188 | 1188 | ||
1189 | err = -ENOBUFS; | 1189 | err = -ENOBUFS; |
1190 | new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); | 1190 | new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); |
1191 | if (new_fa == NULL) | 1191 | if (new_fa == NULL) |
1192 | goto out; | 1192 | goto out; |
1193 | 1193 | ||
@@ -1232,7 +1232,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) | |||
1232 | goto out; | 1232 | goto out; |
1233 | 1233 | ||
1234 | err = -ENOBUFS; | 1234 | err = -ENOBUFS; |
1235 | new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); | 1235 | new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); |
1236 | if (new_fa == NULL) | 1236 | if (new_fa == NULL) |
1237 | goto out; | 1237 | goto out; |
1238 | 1238 | ||
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 244c4f445c7d..8c79c8a4ea5c 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -27,11 +27,11 @@ | |||
27 | * Allocate and initialize a new local port bind bucket. | 27 | * Allocate and initialize a new local port bind bucket. |
28 | * The bindhash mutex for snum's hash chain must be held here. | 28 | * The bindhash mutex for snum's hash chain must be held here. |
29 | */ | 29 | */ |
30 | struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep, | 30 | struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep, |
31 | struct inet_bind_hashbucket *head, | 31 | struct inet_bind_hashbucket *head, |
32 | const unsigned short snum) | 32 | const unsigned short snum) |
33 | { | 33 | { |
34 | struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, SLAB_ATOMIC); | 34 | struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC); |
35 | 35 | ||
36 | if (tb != NULL) { | 36 | if (tb != NULL) { |
37 | tb->port = snum; | 37 | tb->port = snum; |
@@ -45,7 +45,7 @@ struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep, | |||
45 | /* | 45 | /* |
46 | * Caller must hold hashbucket lock for this tb with local BH disabled | 46 | * Caller must hold hashbucket lock for this tb with local BH disabled |
47 | */ | 47 | */ |
48 | void inet_bind_bucket_destroy(kmem_cache_t *cachep, struct inet_bind_bucket *tb) | 48 | void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket *tb) |
49 | { | 49 | { |
50 | if (hlist_empty(&tb->owners)) { | 50 | if (hlist_empty(&tb->owners)) { |
51 | __hlist_del(&tb->node); | 51 | __hlist_del(&tb->node); |
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 8c74f9168b7d..9f414e35c488 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c | |||
@@ -91,7 +91,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat | |||
91 | { | 91 | { |
92 | struct inet_timewait_sock *tw = | 92 | struct inet_timewait_sock *tw = |
93 | kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab, | 93 | kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab, |
94 | SLAB_ATOMIC); | 94 | GFP_ATOMIC); |
95 | if (tw != NULL) { | 95 | if (tw != NULL) { |
96 | const struct inet_sock *inet = inet_sk(sk); | 96 | const struct inet_sock *inet = inet_sk(sk); |
97 | 97 | ||
@@ -178,7 +178,6 @@ void inet_twdr_hangman(unsigned long data) | |||
178 | need_timer = 0; | 178 | need_timer = 0; |
179 | if (inet_twdr_do_twkill_work(twdr, twdr->slot)) { | 179 | if (inet_twdr_do_twkill_work(twdr, twdr->slot)) { |
180 | twdr->thread_slots |= (1 << twdr->slot); | 180 | twdr->thread_slots |= (1 << twdr->slot); |
181 | mb(); | ||
182 | schedule_work(&twdr->twkill_work); | 181 | schedule_work(&twdr->twkill_work); |
183 | need_timer = 1; | 182 | need_timer = 1; |
184 | } else { | 183 | } else { |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index f072f3875af8..711eb6d0285a 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -73,7 +73,7 @@ | |||
73 | /* Exported for inet_getid inline function. */ | 73 | /* Exported for inet_getid inline function. */ |
74 | DEFINE_SPINLOCK(inet_peer_idlock); | 74 | DEFINE_SPINLOCK(inet_peer_idlock); |
75 | 75 | ||
76 | static kmem_cache_t *peer_cachep __read_mostly; | 76 | static struct kmem_cache *peer_cachep __read_mostly; |
77 | 77 | ||
78 | #define node_height(x) x->avl_height | 78 | #define node_height(x) x->avl_height |
79 | static struct inet_peer peer_fake_node = { | 79 | static struct inet_peer peer_fake_node = { |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index efcf45ecc818..ecb5422ea237 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -105,7 +105,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock); | |||
105 | In this case data path is free of exclusive locks at all. | 105 | In this case data path is free of exclusive locks at all. |
106 | */ | 106 | */ |
107 | 107 | ||
108 | static kmem_cache_t *mrt_cachep __read_mostly; | 108 | static struct kmem_cache *mrt_cachep __read_mostly; |
109 | 109 | ||
110 | static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local); | 110 | static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local); |
111 | static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); | 111 | static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); |
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index 8832eb517d52..8086787a2c51 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c | |||
@@ -44,7 +44,7 @@ | |||
44 | static struct list_head *ip_vs_conn_tab; | 44 | static struct list_head *ip_vs_conn_tab; |
45 | 45 | ||
46 | /* SLAB cache for IPVS connections */ | 46 | /* SLAB cache for IPVS connections */ |
47 | static kmem_cache_t *ip_vs_conn_cachep __read_mostly; | 47 | static struct kmem_cache *ip_vs_conn_cachep __read_mostly; |
48 | 48 | ||
49 | /* counter for current IPVS connections */ | 49 | /* counter for current IPVS connections */ |
50 | static atomic_t ip_vs_conn_count = ATOMIC_INIT(0); | 50 | static atomic_t ip_vs_conn_count = ATOMIC_INIT(0); |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 413c2d0a1f3d..71b76ade00e1 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -375,6 +375,13 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
375 | && unconditional(&e->arp)) { | 375 | && unconditional(&e->arp)) { |
376 | unsigned int oldpos, size; | 376 | unsigned int oldpos, size; |
377 | 377 | ||
378 | if (t->verdict < -NF_MAX_VERDICT - 1) { | ||
379 | duprintf("mark_source_chains: bad " | ||
380 | "negative verdict (%i)\n", | ||
381 | t->verdict); | ||
382 | return 0; | ||
383 | } | ||
384 | |||
378 | /* Return: backtrack through the last | 385 | /* Return: backtrack through the last |
379 | * big jump. | 386 | * big jump. |
380 | */ | 387 | */ |
@@ -404,6 +411,14 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
404 | if (strcmp(t->target.u.user.name, | 411 | if (strcmp(t->target.u.user.name, |
405 | ARPT_STANDARD_TARGET) == 0 | 412 | ARPT_STANDARD_TARGET) == 0 |
406 | && newpos >= 0) { | 413 | && newpos >= 0) { |
414 | if (newpos > newinfo->size - | ||
415 | sizeof(struct arpt_entry)) { | ||
416 | duprintf("mark_source_chains: " | ||
417 | "bad verdict (%i)\n", | ||
418 | newpos); | ||
419 | return 0; | ||
420 | } | ||
421 | |||
407 | /* This a jump; chase it. */ | 422 | /* This a jump; chase it. */ |
408 | duprintf("Jump rule %u -> %u\n", | 423 | duprintf("Jump rule %u -> %u\n", |
409 | pos, newpos); | 424 | pos, newpos); |
@@ -426,8 +441,6 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
426 | static inline int standard_check(const struct arpt_entry_target *t, | 441 | static inline int standard_check(const struct arpt_entry_target *t, |
427 | unsigned int max_offset) | 442 | unsigned int max_offset) |
428 | { | 443 | { |
429 | struct arpt_standard_target *targ = (void *)t; | ||
430 | |||
431 | /* Check standard info. */ | 444 | /* Check standard info. */ |
432 | if (t->u.target_size | 445 | if (t->u.target_size |
433 | != ARPT_ALIGN(sizeof(struct arpt_standard_target))) { | 446 | != ARPT_ALIGN(sizeof(struct arpt_standard_target))) { |
@@ -437,18 +450,6 @@ static inline int standard_check(const struct arpt_entry_target *t, | |||
437 | return 0; | 450 | return 0; |
438 | } | 451 | } |
439 | 452 | ||
440 | if (targ->verdict >= 0 | ||
441 | && targ->verdict > max_offset - sizeof(struct arpt_entry)) { | ||
442 | duprintf("arpt_standard_check: bad verdict (%i)\n", | ||
443 | targ->verdict); | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | if (targ->verdict < -NF_MAX_VERDICT - 1) { | ||
448 | duprintf("arpt_standard_check: bad negative verdict (%i)\n", | ||
449 | targ->verdict); | ||
450 | return 0; | ||
451 | } | ||
452 | return 1; | 453 | return 1; |
453 | } | 454 | } |
454 | 455 | ||
@@ -627,18 +628,20 @@ static int translate_table(const char *name, | |||
627 | } | 628 | } |
628 | } | 629 | } |
629 | 630 | ||
631 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) { | ||
632 | duprintf("Looping hook\n"); | ||
633 | return -ELOOP; | ||
634 | } | ||
635 | |||
630 | /* Finally, each sanity check must pass */ | 636 | /* Finally, each sanity check must pass */ |
631 | i = 0; | 637 | i = 0; |
632 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 638 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
633 | check_entry, name, size, &i); | 639 | check_entry, name, size, &i); |
634 | 640 | ||
635 | if (ret != 0) | 641 | if (ret != 0) { |
636 | goto cleanup; | 642 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
637 | 643 | cleanup_entry, &i); | |
638 | ret = -ELOOP; | 644 | return ret; |
639 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) { | ||
640 | duprintf("Looping hook\n"); | ||
641 | goto cleanup; | ||
642 | } | 645 | } |
643 | 646 | ||
644 | /* And one copy for every other CPU */ | 647 | /* And one copy for every other CPU */ |
@@ -647,9 +650,6 @@ static int translate_table(const char *name, | |||
647 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 650 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
648 | } | 651 | } |
649 | 652 | ||
650 | return 0; | ||
651 | cleanup: | ||
652 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
653 | return ret; | 653 | return ret; |
654 | } | 654 | } |
655 | 655 | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index f4b0e68a16d2..8556a4f4f60a 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -65,8 +65,8 @@ static LIST_HEAD(helpers); | |||
65 | unsigned int ip_conntrack_htable_size __read_mostly = 0; | 65 | unsigned int ip_conntrack_htable_size __read_mostly = 0; |
66 | int ip_conntrack_max __read_mostly; | 66 | int ip_conntrack_max __read_mostly; |
67 | struct list_head *ip_conntrack_hash __read_mostly; | 67 | struct list_head *ip_conntrack_hash __read_mostly; |
68 | static kmem_cache_t *ip_conntrack_cachep __read_mostly; | 68 | static struct kmem_cache *ip_conntrack_cachep __read_mostly; |
69 | static kmem_cache_t *ip_conntrack_expect_cachep __read_mostly; | 69 | static struct kmem_cache *ip_conntrack_expect_cachep __read_mostly; |
70 | struct ip_conntrack ip_conntrack_untracked; | 70 | struct ip_conntrack ip_conntrack_untracked; |
71 | unsigned int ip_ct_log_invalid __read_mostly; | 71 | unsigned int ip_ct_log_invalid __read_mostly; |
72 | static LIST_HEAD(unconfirmed); | 72 | static LIST_HEAD(unconfirmed); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 8a455439b128..0ff2956d35e5 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -401,6 +401,13 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
401 | && unconditional(&e->ip)) { | 401 | && unconditional(&e->ip)) { |
402 | unsigned int oldpos, size; | 402 | unsigned int oldpos, size; |
403 | 403 | ||
404 | if (t->verdict < -NF_MAX_VERDICT - 1) { | ||
405 | duprintf("mark_source_chains: bad " | ||
406 | "negative verdict (%i)\n", | ||
407 | t->verdict); | ||
408 | return 0; | ||
409 | } | ||
410 | |||
404 | /* Return: backtrack through the last | 411 | /* Return: backtrack through the last |
405 | big jump. */ | 412 | big jump. */ |
406 | do { | 413 | do { |
@@ -438,6 +445,13 @@ mark_source_chains(struct xt_table_info *newinfo, | |||
438 | if (strcmp(t->target.u.user.name, | 445 | if (strcmp(t->target.u.user.name, |
439 | IPT_STANDARD_TARGET) == 0 | 446 | IPT_STANDARD_TARGET) == 0 |
440 | && newpos >= 0) { | 447 | && newpos >= 0) { |
448 | if (newpos > newinfo->size - | ||
449 | sizeof(struct ipt_entry)) { | ||
450 | duprintf("mark_source_chains: " | ||
451 | "bad verdict (%i)\n", | ||
452 | newpos); | ||
453 | return 0; | ||
454 | } | ||
441 | /* This a jump; chase it. */ | 455 | /* This a jump; chase it. */ |
442 | duprintf("Jump rule %u -> %u\n", | 456 | duprintf("Jump rule %u -> %u\n", |
443 | pos, newpos); | 457 | pos, newpos); |
@@ -470,27 +484,6 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i) | |||
470 | } | 484 | } |
471 | 485 | ||
472 | static inline int | 486 | static inline int |
473 | standard_check(const struct ipt_entry_target *t, | ||
474 | unsigned int max_offset) | ||
475 | { | ||
476 | struct ipt_standard_target *targ = (void *)t; | ||
477 | |||
478 | /* Check standard info. */ | ||
479 | if (targ->verdict >= 0 | ||
480 | && targ->verdict > max_offset - sizeof(struct ipt_entry)) { | ||
481 | duprintf("ipt_standard_check: bad verdict (%i)\n", | ||
482 | targ->verdict); | ||
483 | return 0; | ||
484 | } | ||
485 | if (targ->verdict < -NF_MAX_VERDICT - 1) { | ||
486 | duprintf("ipt_standard_check: bad negative verdict (%i)\n", | ||
487 | targ->verdict); | ||
488 | return 0; | ||
489 | } | ||
490 | return 1; | ||
491 | } | ||
492 | |||
493 | static inline int | ||
494 | check_match(struct ipt_entry_match *m, | 487 | check_match(struct ipt_entry_match *m, |
495 | const char *name, | 488 | const char *name, |
496 | const struct ipt_ip *ip, | 489 | const struct ipt_ip *ip, |
@@ -576,12 +569,7 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size, | |||
576 | if (ret) | 569 | if (ret) |
577 | goto err; | 570 | goto err; |
578 | 571 | ||
579 | if (t->u.kernel.target == &ipt_standard_target) { | 572 | if (t->u.kernel.target->checkentry |
580 | if (!standard_check(t, size)) { | ||
581 | ret = -EINVAL; | ||
582 | goto err; | ||
583 | } | ||
584 | } else if (t->u.kernel.target->checkentry | ||
585 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | 573 | && !t->u.kernel.target->checkentry(name, e, target, t->data, |
586 | e->comefrom)) { | 574 | e->comefrom)) { |
587 | duprintf("ip_tables: check failed for `%s'.\n", | 575 | duprintf("ip_tables: check failed for `%s'.\n", |
@@ -718,17 +706,19 @@ translate_table(const char *name, | |||
718 | } | 706 | } |
719 | } | 707 | } |
720 | 708 | ||
709 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | ||
710 | return -ELOOP; | ||
711 | |||
721 | /* Finally, each sanity check must pass */ | 712 | /* Finally, each sanity check must pass */ |
722 | i = 0; | 713 | i = 0; |
723 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, | 714 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, |
724 | check_entry, name, size, &i); | 715 | check_entry, name, size, &i); |
725 | 716 | ||
726 | if (ret != 0) | 717 | if (ret != 0) { |
727 | goto cleanup; | 718 | IPT_ENTRY_ITERATE(entry0, newinfo->size, |
728 | 719 | cleanup_entry, &i); | |
729 | ret = -ELOOP; | 720 | return ret; |
730 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | 721 | } |
731 | goto cleanup; | ||
732 | 722 | ||
733 | /* And one copy for every other CPU */ | 723 | /* And one copy for every other CPU */ |
734 | for_each_possible_cpu(i) { | 724 | for_each_possible_cpu(i) { |
@@ -736,9 +726,6 @@ translate_table(const char *name, | |||
736 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 726 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
737 | } | 727 | } |
738 | 728 | ||
739 | return 0; | ||
740 | cleanup: | ||
741 | IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
742 | return ret; | 729 | return ret; |
743 | } | 730 | } |
744 | 731 | ||
@@ -1529,25 +1516,8 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m, | |||
1529 | void **dstptr, compat_uint_t *size, const char *name, | 1516 | void **dstptr, compat_uint_t *size, const char *name, |
1530 | const struct ipt_ip *ip, unsigned int hookmask) | 1517 | const struct ipt_ip *ip, unsigned int hookmask) |
1531 | { | 1518 | { |
1532 | struct ipt_entry_match *dm; | ||
1533 | struct ipt_match *match; | ||
1534 | int ret; | ||
1535 | |||
1536 | dm = (struct ipt_entry_match *)*dstptr; | ||
1537 | match = m->u.kernel.match; | ||
1538 | xt_compat_match_from_user(m, dstptr, size); | 1519 | xt_compat_match_from_user(m, dstptr, size); |
1539 | 1520 | return 0; | |
1540 | ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm), | ||
1541 | name, hookmask, ip->proto, | ||
1542 | ip->invflags & IPT_INV_PROTO); | ||
1543 | if (!ret && m->u.kernel.match->checkentry | ||
1544 | && !m->u.kernel.match->checkentry(name, ip, match, dm->data, | ||
1545 | hookmask)) { | ||
1546 | duprintf("ip_tables: check failed for `%s'.\n", | ||
1547 | m->u.kernel.match->name); | ||
1548 | ret = -EINVAL; | ||
1549 | } | ||
1550 | return ret; | ||
1551 | } | 1521 | } |
1552 | 1522 | ||
1553 | static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | 1523 | static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, |
@@ -1569,7 +1539,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
1569 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, | 1539 | ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, |
1570 | name, &de->ip, de->comefrom); | 1540 | name, &de->ip, de->comefrom); |
1571 | if (ret) | 1541 | if (ret) |
1572 | goto err; | 1542 | return ret; |
1573 | de->target_offset = e->target_offset - (origsize - *size); | 1543 | de->target_offset = e->target_offset - (origsize - *size); |
1574 | t = ipt_get_target(e); | 1544 | t = ipt_get_target(e); |
1575 | target = t->u.kernel.target; | 1545 | target = t->u.kernel.target; |
@@ -1582,31 +1552,62 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, | |||
1582 | if ((unsigned char *)de - base < newinfo->underflow[h]) | 1552 | if ((unsigned char *)de - base < newinfo->underflow[h]) |
1583 | newinfo->underflow[h] -= origsize - *size; | 1553 | newinfo->underflow[h] -= origsize - *size; |
1584 | } | 1554 | } |
1555 | return ret; | ||
1556 | } | ||
1557 | |||
1558 | static inline int compat_check_match(struct ipt_entry_match *m, const char *name, | ||
1559 | const struct ipt_ip *ip, unsigned int hookmask) | ||
1560 | { | ||
1561 | struct ipt_match *match; | ||
1562 | int ret; | ||
1563 | |||
1564 | match = m->u.kernel.match; | ||
1565 | ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), | ||
1566 | name, hookmask, ip->proto, | ||
1567 | ip->invflags & IPT_INV_PROTO); | ||
1568 | if (!ret && m->u.kernel.match->checkentry | ||
1569 | && !m->u.kernel.match->checkentry(name, ip, match, m->data, | ||
1570 | hookmask)) { | ||
1571 | duprintf("ip_tables: compat: check failed for `%s'.\n", | ||
1572 | m->u.kernel.match->name); | ||
1573 | ret = -EINVAL; | ||
1574 | } | ||
1575 | return ret; | ||
1576 | } | ||
1577 | |||
1578 | static inline int compat_check_target(struct ipt_entry *e, const char *name) | ||
1579 | { | ||
1580 | struct ipt_entry_target *t; | ||
1581 | struct ipt_target *target; | ||
1582 | int ret; | ||
1585 | 1583 | ||
1586 | t = ipt_get_target(de); | 1584 | t = ipt_get_target(e); |
1587 | target = t->u.kernel.target; | 1585 | target = t->u.kernel.target; |
1588 | ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), | 1586 | ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), |
1589 | name, e->comefrom, e->ip.proto, | 1587 | name, e->comefrom, e->ip.proto, |
1590 | e->ip.invflags & IPT_INV_PROTO); | 1588 | e->ip.invflags & IPT_INV_PROTO); |
1591 | if (ret) | 1589 | if (!ret && t->u.kernel.target->checkentry |
1592 | goto err; | 1590 | && !t->u.kernel.target->checkentry(name, e, target, |
1593 | 1591 | t->data, e->comefrom)) { | |
1594 | ret = -EINVAL; | ||
1595 | if (t->u.kernel.target == &ipt_standard_target) { | ||
1596 | if (!standard_check(t, *size)) | ||
1597 | goto err; | ||
1598 | } else if (t->u.kernel.target->checkentry | ||
1599 | && !t->u.kernel.target->checkentry(name, de, target, | ||
1600 | t->data, de->comefrom)) { | ||
1601 | duprintf("ip_tables: compat: check failed for `%s'.\n", | 1592 | duprintf("ip_tables: compat: check failed for `%s'.\n", |
1602 | t->u.kernel.target->name); | 1593 | t->u.kernel.target->name); |
1603 | goto err; | 1594 | ret = -EINVAL; |
1604 | } | 1595 | } |
1605 | ret = 0; | ||
1606 | err: | ||
1607 | return ret; | 1596 | return ret; |
1608 | } | 1597 | } |
1609 | 1598 | ||
1599 | static inline int compat_check_entry(struct ipt_entry *e, const char *name) | ||
1600 | { | ||
1601 | int ret; | ||
1602 | |||
1603 | ret = IPT_MATCH_ITERATE(e, compat_check_match, name, &e->ip, | ||
1604 | e->comefrom); | ||
1605 | if (ret) | ||
1606 | return ret; | ||
1607 | |||
1608 | return compat_check_target(e, name); | ||
1609 | } | ||
1610 | |||
1610 | static int | 1611 | static int |
1611 | translate_compat_table(const char *name, | 1612 | translate_compat_table(const char *name, |
1612 | unsigned int valid_hooks, | 1613 | unsigned int valid_hooks, |
@@ -1695,6 +1696,11 @@ translate_compat_table(const char *name, | |||
1695 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) | 1696 | if (!mark_source_chains(newinfo, valid_hooks, entry1)) |
1696 | goto free_newinfo; | 1697 | goto free_newinfo; |
1697 | 1698 | ||
1699 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, | ||
1700 | name); | ||
1701 | if (ret) | ||
1702 | goto free_newinfo; | ||
1703 | |||
1698 | /* And one copy for every other CPU */ | 1704 | /* And one copy for every other CPU */ |
1699 | for_each_possible_cpu(i) | 1705 | for_each_possible_cpu(i) |
1700 | if (newinfo->entries[i] && newinfo->entries[i] != entry1) | 1706 | if (newinfo->entries[i] && newinfo->entries[i] != entry1) |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 9f3924c4905e..11c167118e87 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1780,7 +1780,7 @@ static inline int __mkroute_input(struct sk_buff *skb, | |||
1780 | #endif | 1780 | #endif |
1781 | if (in_dev->cnf.no_policy) | 1781 | if (in_dev->cnf.no_policy) |
1782 | rth->u.dst.flags |= DST_NOPOLICY; | 1782 | rth->u.dst.flags |= DST_NOPOLICY; |
1783 | if (in_dev->cnf.no_xfrm) | 1783 | if (out_dev->cnf.no_xfrm) |
1784 | rth->u.dst.flags |= DST_NOXFRM; | 1784 | rth->u.dst.flags |= DST_NOXFRM; |
1785 | rth->fl.fl4_dst = daddr; | 1785 | rth->fl.fl4_dst = daddr; |
1786 | rth->rt_dst = daddr; | 1786 | rth->rt_dst = daddr; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9304034c0c47..c701f6abbfc1 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -4235,7 +4235,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb, | |||
4235 | * Change state from SYN-SENT only after copied_seq | 4235 | * Change state from SYN-SENT only after copied_seq |
4236 | * is initialized. */ | 4236 | * is initialized. */ |
4237 | tp->copied_seq = tp->rcv_nxt; | 4237 | tp->copied_seq = tp->rcv_nxt; |
4238 | mb(); | 4238 | smp_mb(); |
4239 | tcp_set_state(sk, TCP_ESTABLISHED); | 4239 | tcp_set_state(sk, TCP_ESTABLISHED); |
4240 | 4240 | ||
4241 | security_inet_conn_established(sk, skb); | 4241 | security_inet_conn_established(sk, skb); |
@@ -4483,7 +4483,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
4483 | case TCP_SYN_RECV: | 4483 | case TCP_SYN_RECV: |
4484 | if (acceptable) { | 4484 | if (acceptable) { |
4485 | tp->copied_seq = tp->rcv_nxt; | 4485 | tp->copied_seq = tp->rcv_nxt; |
4486 | mb(); | 4486 | smp_mb(); |
4487 | tcp_set_state(sk, TCP_ESTABLISHED); | 4487 | tcp_set_state(sk, TCP_ESTABLISHED); |
4488 | sk->sk_state_change(sk); | 4488 | sk->sk_state_change(sk); |
4489 | 4489 | ||
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index d4107bb701b5..fb9f69c616f5 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -274,6 +274,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) | |||
274 | 274 | ||
275 | if (likely(xdst->u.rt.idev)) | 275 | if (likely(xdst->u.rt.idev)) |
276 | in_dev_put(xdst->u.rt.idev); | 276 | in_dev_put(xdst->u.rt.idev); |
277 | if (likely(xdst->u.rt.peer)) | ||
278 | inet_putpeer(xdst->u.rt.peer); | ||
277 | xfrm_dst_destroy(xdst); | 279 | xfrm_dst_destroy(xdst); |
278 | } | 280 | } |
279 | 281 | ||