diff options
| author | Arnaldo Carvalho de Melo <acme@ghostprotocols.net> | 2005-05-05 16:35:15 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2005-05-05 16:35:15 -0400 |
| commit | 476e19cfa131e2b6eedc4017b627cdc4ca419ffb (patch) | |
| tree | 8c6881affa0d20a3ce2dd8d4f9a5b0ba588916c5 /net | |
| parent | 25ae3f59b10dbd5e2b9b192ecc90ea935cc23e68 (diff) | |
[IPV6]: Fix OOPS when using IPV6_ADDRFORM
This causes sk->sk_prot to change, which makes the socket
release free the sock into the wrong SLAB cache. Fix this
by introducing sk_prot_creator so that we always remember
where the sock came from.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/sock.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index 98171ddd7e7d..92c0676e4708 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -635,7 +635,11 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) | |||
| 635 | if (zero_it) { | 635 | if (zero_it) { |
| 636 | memset(sk, 0, prot->obj_size); | 636 | memset(sk, 0, prot->obj_size); |
| 637 | sk->sk_family = family; | 637 | sk->sk_family = family; |
| 638 | sk->sk_prot = prot; | 638 | /* |
| 639 | * See comment in struct sock definition to understand | ||
| 640 | * why we need sk_prot_creator -acme | ||
| 641 | */ | ||
| 642 | sk->sk_prot = sk->sk_prot_creator = prot; | ||
| 639 | sock_lock_init(sk); | 643 | sock_lock_init(sk); |
| 640 | } | 644 | } |
| 641 | 645 | ||
| @@ -654,7 +658,7 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) | |||
| 654 | void sk_free(struct sock *sk) | 658 | void sk_free(struct sock *sk) |
| 655 | { | 659 | { |
| 656 | struct sk_filter *filter; | 660 | struct sk_filter *filter; |
| 657 | struct module *owner = sk->sk_prot->owner; | 661 | struct module *owner = sk->sk_prot_creator->owner; |
| 658 | 662 | ||
| 659 | if (sk->sk_destruct) | 663 | if (sk->sk_destruct) |
| 660 | sk->sk_destruct(sk); | 664 | sk->sk_destruct(sk); |
| @@ -672,8 +676,8 @@ void sk_free(struct sock *sk) | |||
| 672 | __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); | 676 | __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); |
| 673 | 677 | ||
| 674 | security_sk_free(sk); | 678 | security_sk_free(sk); |
| 675 | if (sk->sk_prot->slab != NULL) | 679 | if (sk->sk_prot_creator->slab != NULL) |
| 676 | kmem_cache_free(sk->sk_prot->slab, sk); | 680 | kmem_cache_free(sk->sk_prot_creator->slab, sk); |
| 677 | else | 681 | else |
| 678 | kfree(sk); | 682 | kfree(sk); |
| 679 | module_put(owner); | 683 | module_put(owner); |
