vhostuser: Fix vhostuser file descriptor leak 32/10432/2
authorHaiyang Tan <haiyang.tan.dev@gmail.com>
Tue, 6 Feb 2018 16:16:48 +0000 (11:16 -0500)
committerDamjan Marion <dmarion.lists@gmail.com>
Thu, 8 Feb 2018 20:33:17 +0000 (20:33 +0000)
In the case that vhostuser server accepted more than one client connection,
'vui->clib_file_index' will be overwritten directly without release the possible
existed resource, so file descriptor leak occurs

Change-Id: I89d08133dae31a12a815df2631334dbf0aefeb1e
Signed-off-by: Haiyang Tan <haiyang.tan.dev@gmail.com>
src/vnet/devices/virtio/vhost-user.c

index be34054..5460f10 100644 (file)
  */
 #define VHOST_USER_TX_COPY_THRESHOLD (VHOST_USER_COPY_ARRAY_N - 40)
 
-#define UNIX_GET_FD(unixfd_idx) \
-    (unixfd_idx != ~0) ? \
+#define UNIX_GET_FD(unixfd_idx) ({ \
+    typeof(unixfd_idx) __unixfd_idx = (unixfd_idx); \
+    (__unixfd_idx != ~0) ? \
        pool_elt_at_index (file_main.file_pool, \
-                          unixfd_idx)->file_descriptor : -1;
+                          __unixfd_idx)->file_descriptor : -1; })
 
 #define foreach_virtio_trace_flags \
   _ (SIMPLE_CHAINED, 0, "Simple descriptor chaining") \
@@ -1282,7 +1283,15 @@ vhost_user_socksvr_accept_ready (clib_file_t * uf)
   if (client_fd < 0)
     return clib_error_return_unix (0, "accept");
 
-  DBG_SOCK ("New client socket for vhost interface %d", vui->sw_if_index);
+  if (vui->clib_file_index != ~0)
+    {
+      DBG_SOCK ("Close client socket for vhost interface %d, fd %d",
+               vui->sw_if_index, UNIX_GET_FD (vui->clib_file_index));
+      clib_file_del (&file_main, file_main.file_pool + vui->clib_file_index);
+    }
+
+  DBG_SOCK ("New client socket for vhost interface %d, fd %d",
+           vui->sw_if_index, client_fd);
   template.read_function = vhost_user_socket_read;
   template.error_function = vhost_user_socket_error;
   template.file_descriptor = client_fd;