diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2023-03-07 15:14:46 +0100 |
---|---|---|
committer | Chuck Lever <chuck.lever@oracle.com> | 2023-04-26 15:05:01 +0200 |
commit | ae0d77708aae219a9264a74188d5c1b1a5754da6 (patch) | |
tree | 573da9a2412590a6906d9785434823a7a373f339 /net | |
parent | NFSD: Watch for rq_pages bounds checking errors in nfsd_splice_actor() (diff) | |
download | linux-ae0d77708aae219a9264a74188d5c1b1a5754da6.tar.xz linux-ae0d77708aae219a9264a74188d5c1b1a5754da6.zip |
SUNRPC: Ensure server-side sockets have a sock->file
The TLS handshake upcall mechanism requires a non-NULL sock->file on
the socket it hands to user space. svc_sock_free() already releases
sock->file properly if one exists.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/sunrpc/svcsock.c | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 03a4f5615086..302a14dd7882 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1293,26 +1293,37 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, struct socket *sock, int flags) { + struct file *filp = NULL; struct svc_sock *svsk; struct sock *inet; int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); - int err = 0; svsk = kzalloc(sizeof(*svsk), GFP_KERNEL); if (!svsk) 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; - /* Register socket with portmapper */ - if (pmap_register) + if (pmap_register) { + int err; + err = svc_register(serv, sock_net(sock->sk), inet->sk_family, inet->sk_protocol, ntohs(inet_sk(inet)->inet_sport)); - - if (err < 0) { - kfree(svsk); - return ERR_PTR(err); + if (err < 0) { + if (filp) + fput(filp); + kfree(svsk); + return ERR_PTR(err); + } } svsk->sk_sock = sock; |