xref: /OK3568_Linux_fs/buildroot/package/vsftpd/0003-Prevent-hang-in-SIGCHLD-handler.patch (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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