SUNRPC: Ensure server-side sockets have a sock->file
authorChuck Lever <chuck.lever@oracle.com>
Tue, 7 Mar 2023 14:14:46 +0000 (09:14 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Wed, 26 Apr 2023 13:05:01 +0000 (09:05 -0400)
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>
net/sunrpc/svcsock.c

index 03a4f56150865e706f2419149567220ee555af6d..302a14dd7882fc395a3e3c443cf1932dfa7884f5 100644 (file)
@@ -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;