aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package/vsftpd/0004-Prevent-hang-in-SIGCHLD-handler.patch87
1 files changed, 87 insertions, 0 deletions
diff --git a/package/vsftpd/0004-Prevent-hang-in-SIGCHLD-handler.patch b/package/vsftpd/0004-Prevent-hang-in-SIGCHLD-handler.patch
new file mode 100644
index 0000000000..0732c5f632
--- /dev/null
+++ b/package/vsftpd/0004-Prevent-hang-in-SIGCHLD-handler.patch
@@ -0,0 +1,87 @@
+From 1e65a0a15f819b8bf1b551bd84f71d0da1f5a00c Mon Sep 17 00:00:00 2001
+From: Martin Sehnoutka <msehnout@redhat.com>
+Date: Thu, 17 Nov 2016 13:02:27 +0100
+Subject: [PATCH] Prevent hanging in SIGCHLD handler.
+
+vsftpd can now handle pam_exec.so in pam.d config without hanging
+in SIGCHLD handler.
+
+[Abdelmalek:
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1198259
+Fetched from:
+https://src.fedoraproject.org/cgit/rpms/vsftpd.git/plain/0026-Prevent-hanging-in-SIGCHLD-handler.patch]
+Signed-off-by: Abdelmalek Benelouezzane <abdelmalek.benelouezzane@savoirfairelinux.com>
+---
+ sysutil.c | 4 ++--
+ sysutil.h | 2 +-
+ twoprocess.c | 13 +++++++++++--
+ 3 files changed, 14 insertions(+), 5 deletions(-)
+
+diff --git a/sysutil.c b/sysutil.c
+index 6d7cb3f..099748f 100644
+--- a/sysutil.c
++++ b/sysutil.c
+@@ -608,13 +608,13 @@ vsf_sysutil_exit(int exit_code)
+ }
+
+ struct vsf_sysutil_wait_retval
+-vsf_sysutil_wait(void)
++vsf_sysutil_wait(int hang)
+ {
+ struct vsf_sysutil_wait_retval retval;
+ vsf_sysutil_memclr(&retval, sizeof(retval));
+ while (1)
+ {
+- int sys_ret = wait(&retval.exit_status);
++ int sys_ret = waitpid(-1, &retval.exit_status, hang ? 0 : WNOHANG);
+ if (sys_ret < 0 && errno == EINTR)
+ {
+ vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0);
+diff --git a/sysutil.h b/sysutil.h
+index c145bdf..13153cd 100644
+--- a/sysutil.h
++++ b/sysutil.h
+@@ -177,7 +177,7 @@ struct vsf_sysutil_wait_retval
+ int PRIVATE_HANDS_OFF_syscall_retval;
+ int PRIVATE_HANDS_OFF_exit_status;
+ };
+-struct vsf_sysutil_wait_retval vsf_sysutil_wait(void);
++struct vsf_sysutil_wait_retval vsf_sysutil_wait(int hang);
+ int vsf_sysutil_wait_reap_one(void);
+ int vsf_sysutil_wait_get_retval(
+ const struct vsf_sysutil_wait_retval* p_waitret);
+diff --git a/twoprocess.c b/twoprocess.c
+index 33d84dc..b1891e7 100644
+--- a/twoprocess.c
++++ b/twoprocess.c
+@@ -47,8 +47,17 @@ static void
+ handle_sigchld(void* duff)
+ {
+
+- struct vsf_sysutil_wait_retval wait_retval = vsf_sysutil_wait();
++ struct vsf_sysutil_wait_retval wait_retval = vsf_sysutil_wait(0);
+ (void) duff;
++ if (!vsf_sysutil_wait_get_exitcode(&wait_retval) &&
++ !vsf_sysutil_wait_get_retval(&wait_retval))
++ /* There was nobody to wait for, possibly caused by underlying library
++ * which created a new process through fork()/vfork() and already picked
++ * it up, e.g. by pam_exec.so or integrity check routines for libraries
++ * when FIPS mode is on (nss freebl), which can lead to calling prelink
++ * if the prelink package is installed.
++ */
++ return;
+ /* Child died, so we'll do the same! Report it as an error unless the child
+ * exited normally with zero exit code
+ */
+@@ -390,7 +399,7 @@ common_do_login(struct vsf_session* p_sess, const struct mystr* p_user_str,
+ priv_sock_send_result(p_sess->parent_fd, PRIV_SOCK_RESULT_OK);
+ if (!p_sess->control_use_ssl)
+ {
+- (void) vsf_sysutil_wait();
++ (void) vsf_sysutil_wait(1);
+ }
+ else
+ {
+--
+2.14.4
+