Blame SOURCES/0059-Fix-SEGFAULT-when-running-in-a-container-as-PID-1.patch

bd689f
From 970711fde95bee3de1e4a5e0b557c3132d0c3e3f Mon Sep 17 00:00:00 2001
bd689f
From: =?UTF-8?q?Ond=C5=99ej=20Lyson=C4=9Bk?= <olysonek@redhat.com>
bd689f
Date: Tue, 6 Feb 2018 11:39:01 +0100
bd689f
Subject: [PATCH 59/59] Fix SEGFAULT when running in a container as PID 1
bd689f
bd689f
When vsftpd is running in a container as PID 1, it is possible
bd689f
that it will get SIGCHILD for processes, which were not directly
bd689f
created by it, but by some of its children. These processes will
bd689f
not be in the s_p_pid_ip_hash hash table, and thus trying to
bd689f
delete the entry from the hash table in standalone.c:handle_sigchld()
bd689f
will result in segmentation fault.
bd689f
bd689f
I can quite easily reproduce it with the upstream vsftpd and default
bd689f
configuration, except for isolate=NO and isolate_network=NO being set
bd689f
(it seems to me that network namespaces take a long time to create
bd689f
and destroy, which hides the race condition), on a quad-core machine.
bd689f
When connecting to vsftpd in a loop like this:
bd689f
$ while true; do echo -en '' | nc localhost 21; done
bd689f
bd689f
vsftpd crashes after a couple of seconds.
bd689f
---
bd689f
 standalone.c | 18 +++++++++++++-----
bd689f
 1 file changed, 13 insertions(+), 5 deletions(-)
bd689f
bd689f
diff --git a/standalone.c b/standalone.c
bd689f
index 3b65ea2..3f35e9e 100644
bd689f
--- a/standalone.c
bd689f
+++ b/standalone.c
bd689f
@@ -270,13 +270,21 @@ handle_sigchld(void* duff)
bd689f
     if (reap_one)
bd689f
     {
bd689f
       struct vsf_sysutil_ipaddr* p_ip;
bd689f
-      /* Account total number of instances */
bd689f
-      --s_children;
bd689f
-      /* Account per-IP limit */
bd689f
       p_ip = (struct vsf_sysutil_ipaddr*)
bd689f
         hash_lookup_entry(s_p_pid_ip_hash, (void*)&reap_one);
bd689f
-      drop_ip_count(p_ip);      
bd689f
-      hash_free_entry(s_p_pid_ip_hash, (void*)&reap_one);
bd689f
+      /* If we are running in a container as PID 1, it is possible
bd689f
+       * that we will get SIGCHILD for processes, which were not
bd689f
+       * created directly by our process and which are not in the
bd689f
+       * s_p_pid_ip_hash hash table.
bd689f
+       */
bd689f
+      if (p_ip)
bd689f
+      {
bd689f
+        /* Account total number of instances */
bd689f
+        --s_children;
bd689f
+        /* Account per-IP limit */
bd689f
+        drop_ip_count(p_ip);
bd689f
+        hash_free_entry(s_p_pid_ip_hash, (void*)&reap_one);
bd689f
+      }
bd689f
     }
bd689f
   }
bd689f
 }
bd689f
-- 
bd689f
2.14.4
bd689f