提交 319050d4 编写于 作者: C Chuck Lever

SUNRPC: Fix error handling in svc_setup_socket()

Dan points out that sock_alloc_file() releases @sock on error, but
so do all of svc_setup_socket's callers, resulting in a double-
release if sock_alloc_file() returns an error.

Rather than allocating a struct file for all new sockets, allocate
one only for sockets created during a TCP accept. For the moment,
those are the only ones that will ever be used with RPC-with-TLS.
Reported-by: NDan Carpenter <dan.carpenter@linaro.org>
Fixes: ae0d7770 ("SUNRPC: Ensure server-side sockets have a sock->file")
Signed-off-by: NChuck Lever <chuck.lever@oracle.com>
上级 29cd2927
...@@ -895,6 +895,9 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt) ...@@ -895,6 +895,9 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
trace_svcsock_accept_err(xprt, serv->sv_name, err); trace_svcsock_accept_err(xprt, serv->sv_name, err);
return NULL; return NULL;
} }
if (IS_ERR(sock_alloc_file(newsock, O_NONBLOCK, NULL)))
return NULL;
set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);
err = kernel_getpeername(newsock, sin); err = kernel_getpeername(newsock, sin);
...@@ -935,7 +938,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt) ...@@ -935,7 +938,7 @@ static struct svc_xprt *svc_tcp_accept(struct svc_xprt *xprt)
return &newsvsk->sk_xprt; return &newsvsk->sk_xprt;
failed: failed:
sock_release(newsock); sockfd_put(newsock);
return NULL; return NULL;
} }
...@@ -1430,7 +1433,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, ...@@ -1430,7 +1433,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
struct socket *sock, struct socket *sock,
int flags) int flags)
{ {
struct file *filp = NULL;
struct svc_sock *svsk; struct svc_sock *svsk;
struct sock *inet; struct sock *inet;
int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); int pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
...@@ -1439,14 +1441,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, ...@@ -1439,14 +1441,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
if (!svsk) if (!svsk)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (!sock->file) {
filp = sock_alloc_file(sock, O_NONBLOCK, NULL);
if (IS_ERR(filp)) {
kfree(svsk);
return ERR_CAST(filp);
}
}
inet = sock->sk; inet = sock->sk;
if (pmap_register) { if (pmap_register) {
...@@ -1456,8 +1450,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, ...@@ -1456,8 +1450,6 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
inet->sk_protocol, inet->sk_protocol,
ntohs(inet_sk(inet)->inet_sport)); ntohs(inet_sk(inet)->inet_sport));
if (err < 0) { if (err < 0) {
if (filp)
fput(filp);
kfree(svsk); kfree(svsk);
return ERR_PTR(err); return ERR_PTR(err);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册