diff options
Diffstat (limited to 'net/core/sock.c')
-rw-r--r-- | net/core/sock.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/net/core/sock.c b/net/core/sock.c index b66f607fcb96..2b744c2bf466 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -870,7 +870,8 @@ static void sock_copy(struct sock *nsk, const struct sock *osk) | |||
870 | #endif | 870 | #endif |
871 | } | 871 | } |
872 | 872 | ||
873 | static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority) | 873 | static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, |
874 | int family) | ||
874 | { | 875 | { |
875 | struct sock *sk; | 876 | struct sock *sk; |
876 | struct kmem_cache *slab; | 877 | struct kmem_cache *slab; |
@@ -881,18 +882,40 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority) | |||
881 | else | 882 | else |
882 | sk = kmalloc(prot->obj_size, priority); | 883 | sk = kmalloc(prot->obj_size, priority); |
883 | 884 | ||
885 | if (sk != NULL) { | ||
886 | if (security_sk_alloc(sk, family, priority)) | ||
887 | goto out_free; | ||
888 | |||
889 | if (!try_module_get(prot->owner)) | ||
890 | goto out_free_sec; | ||
891 | } | ||
892 | |||
884 | return sk; | 893 | return sk; |
894 | |||
895 | out_free_sec: | ||
896 | security_sk_free(sk); | ||
897 | out_free: | ||
898 | if (slab != NULL) | ||
899 | kmem_cache_free(slab, sk); | ||
900 | else | ||
901 | kfree(sk); | ||
902 | return NULL; | ||
885 | } | 903 | } |
886 | 904 | ||
887 | static void sk_prot_free(struct proto *prot, struct sock *sk) | 905 | static void sk_prot_free(struct proto *prot, struct sock *sk) |
888 | { | 906 | { |
889 | struct kmem_cache *slab; | 907 | struct kmem_cache *slab; |
908 | struct module *owner; | ||
890 | 909 | ||
910 | owner = prot->owner; | ||
891 | slab = prot->slab; | 911 | slab = prot->slab; |
912 | |||
913 | security_sk_free(sk); | ||
892 | if (slab != NULL) | 914 | if (slab != NULL) |
893 | kmem_cache_free(slab, sk); | 915 | kmem_cache_free(slab, sk); |
894 | else | 916 | else |
895 | kfree(sk); | 917 | kfree(sk); |
918 | module_put(owner); | ||
896 | } | 919 | } |
897 | 920 | ||
898 | /** | 921 | /** |
@@ -911,7 +934,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
911 | if (zero_it) | 934 | if (zero_it) |
912 | priority |= __GFP_ZERO; | 935 | priority |= __GFP_ZERO; |
913 | 936 | ||
914 | sk = sk_prot_alloc(prot, priority); | 937 | sk = sk_prot_alloc(prot, priority, family); |
915 | if (sk) { | 938 | if (sk) { |
916 | if (zero_it) { | 939 | if (zero_it) { |
917 | sk->sk_family = family; | 940 | sk->sk_family = family; |
@@ -923,24 +946,14 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority, | |||
923 | sock_lock_init(sk); | 946 | sock_lock_init(sk); |
924 | sk->sk_net = get_net(net); | 947 | sk->sk_net = get_net(net); |
925 | } | 948 | } |
926 | |||
927 | if (security_sk_alloc(sk, family, priority)) | ||
928 | goto out_free; | ||
929 | |||
930 | if (!try_module_get(prot->owner)) | ||
931 | goto out_free; | ||
932 | } | 949 | } |
933 | return sk; | ||
934 | 950 | ||
935 | out_free: | 951 | return sk; |
936 | sk_prot_free(prot, sk); | ||
937 | return NULL; | ||
938 | } | 952 | } |
939 | 953 | ||
940 | void sk_free(struct sock *sk) | 954 | void sk_free(struct sock *sk) |
941 | { | 955 | { |
942 | struct sk_filter *filter; | 956 | struct sk_filter *filter; |
943 | struct module *owner = sk->sk_prot_creator->owner; | ||
944 | 957 | ||
945 | if (sk->sk_destruct) | 958 | if (sk->sk_destruct) |
946 | sk->sk_destruct(sk); | 959 | sk->sk_destruct(sk); |
@@ -957,10 +970,8 @@ void sk_free(struct sock *sk) | |||
957 | printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", | 970 | printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", |
958 | __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); | 971 | __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); |
959 | 972 | ||
960 | security_sk_free(sk); | ||
961 | put_net(sk->sk_net); | 973 | put_net(sk->sk_net); |
962 | sk_prot_free(sk->sk_prot_creator, sk); | 974 | sk_prot_free(sk->sk_prot_creator, sk); |
963 | module_put(owner); | ||
964 | } | 975 | } |
965 | 976 | ||
966 | struct sock *sk_clone(const struct sock *sk, const gfp_t priority) | 977 | struct sock *sk_clone(const struct sock *sk, const gfp_t priority) |