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

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