bash51-012 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. BASH PATCH REPORT
  2. =================
  3. Bash-Release: 5.1
  4. Patch-ID: bash51-012
  5. Bug-Reported-by: Nikolay Borisov <nborisov@suse.com>
  6. Bug-Reference-ID: <1a715205-06ce-413b-c1c0-2f5639ce06c0@suse.com>
  7. Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2020-11/msg00091.html
  8. Bug-Description:
  9. There is a possible race condition that arises when a child process receives
  10. a signal trapped by the parent before it can reset the signal dispositions.
  11. The child process is not supposed to trap the signal in this circumstance.
  12. Patch (apply with `patch -p0'):
  13. *** ../bash-20201118/command.h 2020-08-14 15:04:39.000000000 -0400
  14. --- command.h 2020-11-27 15:18:02.000000000 -0500
  15. ***************
  16. *** 125,128 ****
  17. --- 125,129 ----
  18. #define SUBSHELL_COPROC 0x40 /* subshell from a coproc pipeline */
  19. #define SUBSHELL_RESETTRAP 0x80 /* subshell needs to reset trap strings on first call to trap */
  20. + #define SUBSHELL_IGNTRAP 0x100 /* subshell should reset trapped signals from trap_handler */
  21. /* A structure which represents a word. */
  22. *** ../bash-20201118/execute_cmd.c 2020-11-23 14:16:48.000000000 -0500
  23. --- execute_cmd.c 2020-11-27 16:43:25.000000000 -0500
  24. ***************
  25. *** 1548,1551 ****
  26. --- 1548,1554 ----
  27. reset_signal_handlers ();
  28. subshell_environment |= SUBSHELL_RESETTRAP;
  29. + /* Note that signal handlers have been reset, so we should no longer
  30. + reset the handler and resend trapped signals to ourselves. */
  31. + subshell_environment &= ~SUBSHELL_IGNTRAP;
  32. /* We are in a subshell, so forget that we are running a trap handler or
  33. ***************
  34. *** 4321,4325 ****
  35. cmdflags |= CMD_NO_FORK;
  36. ! subshell_environment = SUBSHELL_FORK; /* XXX */
  37. if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
  38. subshell_environment |= SUBSHELL_PIPE;
  39. --- 4324,4329 ----
  40. cmdflags |= CMD_NO_FORK;
  41. ! /* We redo some of what make_child() does with SUBSHELL_IGNTRAP */
  42. ! subshell_environment = SUBSHELL_FORK|SUBSHELL_IGNTRAP; /* XXX */
  43. if (pipe_in != NO_PIPE || pipe_out != NO_PIPE)
  44. subshell_environment |= SUBSHELL_PIPE;
  45. ***************
  46. *** 4575,4578 ****
  47. --- 4580,4584 ----
  48. reset_signal_handlers ();
  49. subshell_environment |= SUBSHELL_RESETTRAP;
  50. + subshell_environment &= ~SUBSHELL_IGNTRAP;
  51. if (async)
  52. ***************
  53. *** 5515,5518 ****
  54. --- 5521,5525 ----
  55. /* Cancel traps, in trap.c. */
  56. restore_original_signals ();
  57. + subshell_environment &= ~SUBSHELL_IGNTRAP;
  58. #if defined (JOB_CONTROL)
  59. *** ../bash-20201118/jobs.c 2020-08-04 10:17:39.000000000 -0400
  60. --- jobs.c 2020-11-27 16:39:56.000000000 -0500
  61. ***************
  62. *** 2218,2221 ****
  63. --- 2218,2223 ----
  64. pid_t mypid;
  65. + subshell_environment |= SUBSHELL_IGNTRAP;
  66. +
  67. /* If this ends up being changed to modify or use `command' in the
  68. child process, go back and change callers who free `command' in
  69. diff -rC 2 ../bash-20201118/nojobs.c nojobs.c
  70. *** ../bash-20201118/nojobs.c 2020-07-08 10:11:25.000000000 -0400
  71. --- nojobs.c 2020-11-27 16:38:36.000000000 -0500
  72. ***************
  73. *** 576,579 ****
  74. --- 576,581 ----
  75. #endif
  76. + subshell_environment |= SUBSHELL_IGNTRAP;
  77. +
  78. default_tty_job_signals ();
  79. }
  80. *** ../bash-20201118/sig.c 2020-11-23 13:22:17.000000000 -0500
  81. --- sig.c 2020-11-28 10:21:43.000000000 -0500
  82. ***************
  83. *** 56,60 ****
  84. #endif
  85. ! extern void initialize_siglist ();
  86. #if !defined (JOB_CONTROL)
  87. --- 56,61 ----
  88. #endif
  89. ! extern void initialize_siglist PARAMS((void));
  90. ! extern void set_original_signal PARAMS((int, SigHandler *));
  91. #if !defined (JOB_CONTROL)
  92. ***************
  93. *** 256,259 ****
  94. --- 257,267 ----
  95. XHANDLER(i) = oact.sa_handler;
  96. XSAFLAGS(i) = oact.sa_flags;
  97. +
  98. + #if 0
  99. + set_original_signal (XSIG(i), XHANDLER(i)); /* optimization */
  100. + #else
  101. + set_original_signal (XSIG(i), act.sa_handler); /* optimization */
  102. + #endif
  103. +
  104. /* Don't do anything with signals that are ignored at shell entry
  105. if the shell is not interactive. */
  106. *** ../bash-20201118/subst.c 2020-11-16 10:33:15.000000000 -0500
  107. --- subst.c 2020-11-27 16:07:00.000000000 -0500
  108. ***************
  109. *** 5952,5955 ****
  110. --- 5952,5956 ----
  111. /* Cancel traps, in trap.c. */
  112. restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
  113. + subshell_environment &= ~SUBSHELL_IGNTRAP;
  114. QUIT; /* catch any interrupts we got post-fork */
  115. setup_async_signals ();
  116. ***************
  117. *** 6383,6386 ****
  118. --- 6384,6388 ----
  119. QUIT; /* catch any interrupts we got post-fork */
  120. subshell_environment |= SUBSHELL_RESETTRAP;
  121. + subshell_environment &= ~SUBSHELL_IGNTRAP;
  122. }
  123. diff -rC 2 ../bash-20201118/trap.c trap.c
  124. *** ../bash-20201118/trap.c 2020-11-28 12:04:07.000000000 -0500
  125. --- trap.c 2020-11-28 10:22:10.000000000 -0500
  126. ***************
  127. *** 482,485 ****
  128. --- 482,511 ----
  129. }
  130. + /* This means we're in a subshell, but have not yet reset the handler for
  131. + trapped signals. We're not supposed to execute the trap in this situation;
  132. + we should restore the original signal and resend the signal to ourselves
  133. + to preserve the Posix "signal traps that are not being ignored shall be
  134. + set to the default action" semantics. */
  135. + if ((subshell_environment & SUBSHELL_IGNTRAP) && trap_list[sig] != (char *)IGNORE_SIG)
  136. + {
  137. + sigset_t mask;
  138. +
  139. + /* Paranoia */
  140. + if (original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER)
  141. + original_signals[sig] = SIG_DFL;
  142. +
  143. + restore_signal (sig);
  144. +
  145. + /* Make sure we let the signal we just caught through */
  146. + sigemptyset (&mask);
  147. + sigprocmask (SIG_SETMASK, (sigset_t *)NULL, &mask);
  148. + sigdelset (&mask, sig);
  149. + sigprocmask (SIG_SETMASK, &mask, (sigset_t *)NULL);
  150. +
  151. + kill (getpid (), sig);
  152. +
  153. + SIGRETURN (0);
  154. + }
  155. +
  156. if ((sig >= NSIG) ||
  157. (trap_list[sig] == (char *)DEFAULT_SIG) ||
  158. *** ../bash-5.1/patchlevel.h 2020-06-22 14:51:03.000000000 -0400
  159. --- patchlevel.h 2020-10-01 11:01:28.000000000 -0400
  160. ***************
  161. *** 26,30 ****
  162. looks for to find the patch level (for the sccs version string). */
  163. ! #define PATCHLEVEL 11
  164. #endif /* _PATCHLEVEL_H_ */
  165. --- 26,30 ----
  166. looks for to find the patch level (for the sccs version string). */
  167. ! #define PATCHLEVEL 12
  168. #endif /* _PATCHLEVEL_H_ */