aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/sock.c41
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
873static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority) 873static 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
895out_free_sec:
896 security_sk_free(sk);
897out_free:
898 if (slab != NULL)
899 kmem_cache_free(slab, sk);
900 else
901 kfree(sk);
902 return NULL;
885} 903}
886 904
887static void sk_prot_free(struct proto *prot, struct sock *sk) 905static 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
935out_free: 951 return sk;
936 sk_prot_free(prot, sk);
937 return NULL;
938} 952}
939 953
940void sk_free(struct sock *sk) 954void 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
966struct sock *sk_clone(const struct sock *sk, const gfp_t priority) 977struct sock *sk_clone(const struct sock *sk, const gfp_t priority)