[Devel] [PATCH RHEL7 COMMIT] fuse kio: Fix rpc socket leak on rpc_abort()

Konstantin Khorenko khorenko at virtuozzo.com
Tue Oct 16 18:09:44 MSK 2018


The commit is pushed to "branch-rh7-3.10.0-862.14.4.vz7.72.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-862.14.4.vz7.72.9
------>
commit f76c48f2552666a564ab4ae72b6673040b14c7e4
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Tue Oct 16 18:09:43 2018 +0300

    fuse kio: Fix rpc socket leak on rpc_abort()
    
    There is no a place we have paired fput() for fget()
    from process_pcs_csconn_reply(), and it looks like
    it is leaked. Also, there is no a place, we free sio.
    Fix that.
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    Reviewed-by: Pavel Butsykin <pbutsykin at virtuozzo.com>
    
    =====================
    Patchset description:
    
    Order pcs_rpc and pcs_sockio destruction and close leaked socket
    
    https://pmc.acronis.com/browse/VSTOR-15305
    
    Ploop can asynchronously unmap regions by sending IOCB_CMD_UNMAP_ITER, but this
    command isn't quite correctly interpreted in Fuse. Moreover, in Fast-path mode,
    fallocate(FALLOC_FL_PUNCH_HOLE|FALLOC_FL_ZERO_RANGE) falls to fuse user daemon
    and it can lead to data corruption.
    
    Let's fix it.
    
    Kirill Tkhai (9):
          fuse kio: Use __maybe_unused
          fuse kio: Use sio eof instead of parent to determ abort
          fuse kio: Reorder callback assignment
          fuse kio: Add pcs_cleanup_wq
          fuse kio: Destroy rpc in work func
          fuse kio: Introduce pcs_sk_kick_queue()
          fuse kio: Dereference sk_user_data under rcu
          fuse kio: Fix rpc socket leak on rpc_abort()
          fuse kio: Hold pcs_rpc counter till sio may be freed
---
 fs/fuse/kio/pcs/pcs_rpc.c     |  2 ++
 fs/fuse/kio/pcs/pcs_sock_io.c | 12 +++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/fs/fuse/kio/pcs/pcs_rpc.c b/fs/fuse/kio/pcs/pcs_rpc.c
index 9035b504121b..7571523fe271 100644
--- a/fs/fuse/kio/pcs/pcs_rpc.c
+++ b/fs/fuse/kio/pcs/pcs_rpc.c
@@ -208,6 +208,8 @@ void rpc_abort(struct pcs_rpc * ep, int fatal, int error)
 
 		sio->eof = NULL;
 		pcs_sock_error(sio, error);
+		if (ioconn->destruct)
+			ioconn->destruct(ioconn);
 	}
 
 	if (ep->state == PCS_RPC_UNCONN) {
diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c
index bcf4bf6745a8..68829daaa00e 100644
--- a/fs/fuse/kio/pcs/pcs_sock_io.c
+++ b/fs/fuse/kio/pcs/pcs_sock_io.c
@@ -4,6 +4,7 @@
 #include <linux/kthread.h>
 #include <linux/types.h>
 #include <linux/highmem.h>
+#include <linux/file.h>
 
 #include "pcs_types.h"
 #include "pcs_sock_io.h"
@@ -43,11 +44,8 @@ void sio_push(struct pcs_sockio * sio)
 static void pcs_restore_sockets(struct pcs_ioconn *ioconn);
 void pcs_ioconn_unregister(struct pcs_ioconn *ioconn)
 {
-	if (!test_bit(PCS_IOCONN_BF_DEAD, &ioconn->flags)) {
+	if (!test_bit(PCS_IOCONN_BF_DEAD, &ioconn->flags))
 		set_bit(PCS_IOCONN_BF_DEAD, &ioconn->flags);
-		pcs_restore_sockets(ioconn);
-	}
-
 }
 
 void pcs_ioconn_close(struct pcs_ioconn *ioconn)
@@ -500,7 +498,11 @@ void pcs_sock_ioconn_destruct(struct pcs_ioconn *ioconn)
 	BUG_ON(!list_empty(&sio->write_queue));
 	BUG_ON(sio->write_queue_len);
 
-	pcs_ioconn_close(ioconn);
+	if (ioconn->socket) {
+		pcs_restore_sockets(ioconn);
+		fput(ioconn->socket->file);
+		ioconn->socket = NULL;
+	}
 
 	/* Wait pending socket callbacks, e.g., sk_data_ready() */
 	call_rcu(&sio->rcu, sio_destroy_rcu);



More information about the Devel mailing list