0003-Prevent-hang-in-SIGCHLD-handler.patch 2.9 KB

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