1*4882a593SmuzhiyunFrom 1e65a0a15f819b8bf1b551bd84f71d0da1f5a00c Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Martin Sehnoutka <msehnout@redhat.com> 3*4882a593SmuzhiyunDate: Thu, 17 Nov 2016 13:02:27 +0100 4*4882a593SmuzhiyunSubject: [PATCH] Prevent hanging in SIGCHLD handler. 5*4882a593Smuzhiyun 6*4882a593Smuzhiyunvsftpd can now handle pam_exec.so in pam.d config without hanging 7*4882a593Smuzhiyunin SIGCHLD handler. 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun[Abdelmalek: 10*4882a593SmuzhiyunFixes: https://bugzilla.redhat.com/show_bug.cgi?id=1198259 11*4882a593SmuzhiyunFetched from: 12*4882a593Smuzhiyunhttps://src.fedoraproject.org/cgit/rpms/vsftpd.git/plain/0026-Prevent-hanging-in-SIGCHLD-handler.patch] 13*4882a593SmuzhiyunSigned-off-by: Abdelmalek Benelouezzane <abdelmalek.benelouezzane@savoirfairelinux.com> 14*4882a593Smuzhiyun--- 15*4882a593Smuzhiyun sysutil.c | 4 ++-- 16*4882a593Smuzhiyun sysutil.h | 2 +- 17*4882a593Smuzhiyun twoprocess.c | 13 +++++++++++-- 18*4882a593Smuzhiyun 3 files changed, 14 insertions(+), 5 deletions(-) 19*4882a593Smuzhiyun 20*4882a593Smuzhiyundiff --git a/sysutil.c b/sysutil.c 21*4882a593Smuzhiyunindex 6d7cb3f..099748f 100644 22*4882a593Smuzhiyun--- a/sysutil.c 23*4882a593Smuzhiyun+++ b/sysutil.c 24*4882a593Smuzhiyun@@ -592,13 +592,13 @@ vsf_sysutil_exit(int exit_code) 25*4882a593Smuzhiyun } 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun struct vsf_sysutil_wait_retval 28*4882a593Smuzhiyun-vsf_sysutil_wait(void) 29*4882a593Smuzhiyun+vsf_sysutil_wait(int hang) 30*4882a593Smuzhiyun { 31*4882a593Smuzhiyun struct vsf_sysutil_wait_retval retval; 32*4882a593Smuzhiyun vsf_sysutil_memclr(&retval, sizeof(retval)); 33*4882a593Smuzhiyun while (1) 34*4882a593Smuzhiyun { 35*4882a593Smuzhiyun- int sys_ret = wait(&retval.exit_status); 36*4882a593Smuzhiyun+ int sys_ret = waitpid(-1, &retval.exit_status, hang ? 0 : WNOHANG); 37*4882a593Smuzhiyun if (sys_ret < 0 && errno == EINTR) 38*4882a593Smuzhiyun { 39*4882a593Smuzhiyun vsf_sysutil_check_pending_actions(kVSFSysUtilUnknown, 0, 0); 40*4882a593Smuzhiyundiff --git a/sysutil.h b/sysutil.h 41*4882a593Smuzhiyunindex c145bdf..13153cd 100644 42*4882a593Smuzhiyun--- a/sysutil.h 43*4882a593Smuzhiyun+++ b/sysutil.h 44*4882a593Smuzhiyun@@ -175,7 +175,7 @@ struct vsf_sysutil_wait_retval 45*4882a593Smuzhiyun int PRIVATE_HANDS_OFF_syscall_retval; 46*4882a593Smuzhiyun int PRIVATE_HANDS_OFF_exit_status; 47*4882a593Smuzhiyun }; 48*4882a593Smuzhiyun-struct vsf_sysutil_wait_retval vsf_sysutil_wait(void); 49*4882a593Smuzhiyun+struct vsf_sysutil_wait_retval vsf_sysutil_wait(int hang); 50*4882a593Smuzhiyun int vsf_sysutil_wait_reap_one(void); 51*4882a593Smuzhiyun int vsf_sysutil_wait_get_retval( 52*4882a593Smuzhiyun const struct vsf_sysutil_wait_retval* p_waitret); 53*4882a593Smuzhiyundiff --git a/twoprocess.c b/twoprocess.c 54*4882a593Smuzhiyunindex 33d84dc..b1891e7 100644 55*4882a593Smuzhiyun--- a/twoprocess.c 56*4882a593Smuzhiyun+++ b/twoprocess.c 57*4882a593Smuzhiyun@@ -47,8 +47,17 @@ static void 58*4882a593Smuzhiyun handle_sigchld(void* duff) 59*4882a593Smuzhiyun { 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun- struct vsf_sysutil_wait_retval wait_retval = vsf_sysutil_wait(); 62*4882a593Smuzhiyun+ struct vsf_sysutil_wait_retval wait_retval = vsf_sysutil_wait(0); 63*4882a593Smuzhiyun (void) duff; 64*4882a593Smuzhiyun+ if (!vsf_sysutil_wait_get_exitcode(&wait_retval) && 65*4882a593Smuzhiyun+ !vsf_sysutil_wait_get_retval(&wait_retval)) 66*4882a593Smuzhiyun+ /* There was nobody to wait for, possibly caused by underlying library 67*4882a593Smuzhiyun+ * which created a new process through fork()/vfork() and already picked 68*4882a593Smuzhiyun+ * it up, e.g. by pam_exec.so or integrity check routines for libraries 69*4882a593Smuzhiyun+ * when FIPS mode is on (nss freebl), which can lead to calling prelink 70*4882a593Smuzhiyun+ * if the prelink package is installed. 71*4882a593Smuzhiyun+ */ 72*4882a593Smuzhiyun+ return; 73*4882a593Smuzhiyun /* Child died, so we'll do the same! Report it as an error unless the child 74*4882a593Smuzhiyun * exited normally with zero exit code 75*4882a593Smuzhiyun */ 76*4882a593Smuzhiyun@@ -390,7 +399,7 @@ common_do_login(struct vsf_session* p_sess, const struct mystr* p_user_str, 77*4882a593Smuzhiyun priv_sock_send_result(p_sess->parent_fd, PRIV_SOCK_RESULT_OK); 78*4882a593Smuzhiyun if (!p_sess->control_use_ssl) 79*4882a593Smuzhiyun { 80*4882a593Smuzhiyun- (void) vsf_sysutil_wait(); 81*4882a593Smuzhiyun+ (void) vsf_sysutil_wait(1); 82*4882a593Smuzhiyun } 83*4882a593Smuzhiyun else 84*4882a593Smuzhiyun { 85*4882a593Smuzhiyun-- 86*4882a593Smuzhiyun2.14.4 87*4882a593Smuzhiyun 88