Subject: [PATCH] nethost: Cleanup sk_host handling. From: Eric W. Biederman Date: 1133775584 -0700 Move freeing of sk_host into sk_free which is as late as possible. af_inet6 - Bump the ref count on sk_host af_inet, af_unix - Allow sk_free to reduce the refcount. All of this is good but this allows sk_host to be freed in process, BH and IRQ contexts and unfortunately __put_host only seems safe to run in process context because we down the loopback interface, remove the host routes, and clear the route cache. Which means there is work left to do. --- net/core/sock.c | 3 +++ net/ipv4/af_inet.c | 1 - net/ipv6/af_inet6.c | 1 + net/unix/af_unix.c | 2 -- 4 files changed, 4 insertions(+), 3 deletions(-) a7458eeea8945a004899c9c7ba4542203bf6b8c5 diff --git a/net/core/sock.c b/net/core/sock.c index 1c52fe8..b0f8918 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -111,6 +111,7 @@ #include #include #include +#include #include #include @@ -696,6 +697,8 @@ void sk_free(struct sock *sk) printk(KERN_DEBUG "%s: optmem leakage (%d bytes) detected.\n", __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); + if (sk->sk_host) + put_host(sk->sk_host); security_sk_free(sk); if (sk->sk_prot_creator->slab != NULL) kmem_cache_free(sk->sk_prot_creator->slab, sk); diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index fb25c5c..c6e0361 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -393,7 +393,6 @@ int inet_release(struct socket *sock) timeout = sk->sk_lingertime; sock->sk = NULL; sk->sk_prot->close(sk, timeout); - put_host(sk->sk_host); } return 0; } diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c565cd6..26b8726 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -148,6 +148,7 @@ static int inet6_create(struct socket *s rc = 0; sk->sk_host = current->host; + get_host(sk->sk_host); sk->sk_no_check = answer_no_check; if (INET_PROTOSW_REUSE & answer_flags) sk->sk_reuse = 1; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 08f4dce..9ca3ca2 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -401,8 +401,6 @@ static int unix_release_sock (struct soc mntput(mnt); } - put_host(sk->sk_host); - sk->sk_host = NULL; sock_put(sk); /* ---- Socket is dead now and most probably destroyed ---- */ -- 1.0.GIT