bash/bash-4.4-bgpoverflow.patch
2024-02-05 15:40:59 +08:00

301 lines
7.2 KiB
Diff

---
execute_cmd.c | 4 ++
jobs.c | 45 +++++++++++++++++++------
nojobs.c | 5 ++
subst.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
subst.h | 8 ++++
5 files changed, 154 insertions(+), 10 deletions(-)
--- execute_cmd.c
+++ execute_cmd.c 2019-06-05 09:19:06.362106086 +0000
@@ -722,6 +722,10 @@ execute_command_internal (command, async
stdin_redir = stdin_redirects (command->redirects);
#if defined (PROCESS_SUBSTITUTION)
+# if !defined (HAVE_DEV_FD)
+ reap_procsubs ();
+# endif
+
if (variable_context != 0)
{
ofifo = num_fifos ();
--- jobs.c
+++ jobs.c 2019-06-05 09:42:13.056119389 +0000
@@ -72,6 +72,8 @@
#include "execute_cmd.h"
#include "flags.h"
+#include "typemax.h"
+
#include "builtins/builtext.h"
#include "builtins/common.h"
@@ -92,7 +94,7 @@ extern int killpg __P((pid_t, int));
#endif
#if !MAX_CHILD_MAX
-# define MAX_CHILD_MAX 8192
+# define MAX_CHILD_MAX 32768
#endif
#if !defined (DEBUG)
@@ -751,7 +753,7 @@ stop_pipeline (async, deferred)
static void
bgp_resize ()
{
- ps_index_t nsize;
+ ps_index_t nsize, nsize_cur, nsize_max;
ps_index_t psi;
if (bgpids.nalloc == 0)
@@ -765,10 +767,19 @@ bgp_resize ()
else
nsize = bgpids.nalloc;
- while (nsize < js.c_childmax)
- nsize *= 2;
+ nsize_max = TYPE_MAXIMUM (ps_index_t);
+ nsize_cur = (ps_index_t)js.c_childmax;
+ if (nsize_cur < 0) /* overflow */
+ nsize_cur = MAX_CHILD_MAX;
+
+ while (nsize > 0 && nsize < nsize_cur) /* > 0 should catch overflow */
+ nsize <<= 1;
+ if (nsize > nsize_max || nsize <= 0) /* overflow? */
+ nsize = nsize_max;
+ if (nsize > MAX_CHILD_MAX)
+ nsize = nsize_max = MAX_CHILD_MAX; /* hard cap */
- if (bgpids.nalloc < js.c_childmax)
+ if (bgpids.nalloc < nsize_cur && bgpids.nalloc < nsize_max)
{
bgpids.storage = (struct pidstat *)xrealloc (bgpids.storage, nsize * sizeof (struct pidstat));
@@ -785,9 +796,7 @@ bgp_resize ()
static ps_index_t
bgp_getindex ()
{
- ps_index_t psi;
-
- if (bgpids.nalloc < js.c_childmax || bgpids.head >= bgpids.nalloc)
+ if (bgpids.nalloc < (ps_index_t)js.c_childmax || bgpids.head >= bgpids.nalloc)
bgp_resize ();
pshash_delindex (bgpids.head); /* XXX - clear before reusing */
@@ -1010,6 +1019,7 @@ cleanup_dead_jobs ()
{
register int i;
int os;
+ PROCESS *discard;
if (js.j_jobslots == 0 || jobs_list_frozen)
return;
@@ -1034,8 +1044,9 @@ cleanup_dead_jobs ()
if (last_procsub_child && last_procsub_child->running == PS_DONE)
{
bgp_add (last_procsub_child->pid, process_exit_status (last_procsub_child->status)); /* XXX */
- discard_pipeline (last_procsub_child);
+ discard = last_procsub_child;
last_procsub_child = (PROCESS *)NULL;
+ discard_pipeline (discard);
}
#endif
@@ -2475,6 +2486,13 @@ wait_for_background_pids ()
waited_for++;
}
+#if defined (PROCESS_SUBSTITUTION)
+ if (last_procsub_child && last_procsub_child->pid != NO_PID)
+ r = wait_for (last_procsub_child->pid);
+ wait_procsubs ();
+ reap_procsubs ();
+#endif
+
/* POSIX.2 says the shell can discard the statuses of all completed jobs if
`wait' is called with no arguments. */
mark_dead_jobs_as_notified (1);
@@ -3498,6 +3516,7 @@ waitchld (wpid, block)
WAIT status;
PROCESS *child;
pid_t pid;
+ int ind;
int call_set_current, last_stopped_job, job, children_exited, waitpid_flags;
static int wcontinued = WCONTINUED; /* run-time fix for glibc problem */
@@ -3604,6 +3623,13 @@ itrace("waitchld: waitpid returns %d blo
coproc_pidchk (pid, WSTATUS(status));
#endif
+#if defined (PROCESS_SUBSTITUTION)
+ /* Only manipulate the list of process substitutions while SIGCHLD
+ is blocked. */
+ if ((ind = find_procsub_child (pid)) >= 0)
+ set_procsub_status (ind, pid, WSTATUS (status));
+#endif
+
/* It is not an error to have a child terminate that we did
not have a record of. This child could have been part of
a pipeline in backquote substitution. Even so, I'm not
@@ -4838,5 +4864,4 @@ restore_pgrp_pipe (p)
pgrp_pipe[0] = p[0];
pgrp_pipe[1] = p[1];
}
-
#endif /* PGRP_PIPE */
--- nojobs.c
+++ nojobs.c 2019-06-05 09:28:29.891549557 +0000
@@ -273,6 +273,11 @@ set_pid_status (pid, status)
coproc_pidchk (pid, status);
#endif
+#if defined (PROCESS_SUBSTITUTION)
+ if ((slot = find_procsub_child (pid)) >= 0)
+ set_procsub_status (slot, pid, WSTATUS (status));
+#endif
+
slot = find_index_by_pid (pid);
if (slot == NO_PID)
return;
--- subst.c
+++ subst.c 2019-06-05 09:34:35.696693909 +0000
@@ -5506,6 +5506,55 @@ close_new_fifos (list, lsize)
}
int
+find_procsub_child (pid)
+ pid_t pid;
+{
+ int i;
+
+ for (i = 0; i < nfifo; i++)
+ if (fifo_list[i].proc == pid)
+ return i;
+ return -1;
+}
+
+void
+set_procsub_status (ind, pid, status)
+ int ind;
+ pid_t pid;
+ int status;
+{
+ if (ind >= 0 && ind < nfifo)
+ fifo_list[ind].proc = (pid_t)-1; /* sentinel */
+}
+
+/* If we've marked the process for this procsub as dead, close the
+ associated file descriptor and delete the FIFO. */
+void
+reap_procsubs ()
+{
+ int i;
+
+ for (i = 0; i < nfifo; i++)
+ if (fifo_list[i].proc == (pid_t)-1) /* reaped */
+ unlink_fifo (i);
+}
+
+void
+wait_procsubs ()
+{
+ int i, r;
+
+ for (i = 0; i < nfifo; i++)
+ {
+ if (fifo_list[i].proc != (pid_t)-1 && fifo_list[i].proc > 0)
+ {
+ r = wait_for (fifo_list[i].proc);
+ fifo_list[i].proc = (pid_t)-1;
+ }
+ }
+}
+
+int
fifos_pending ()
{
return nfifo;
@@ -5674,6 +5723,59 @@ close_new_fifos (list, lsize)
unlink_fifo (i);
}
+int
+find_procsub_child (pid)
+ pid_t pid;
+{
+ int i;
+
+ if (nfds == 0)
+ return -1;
+
+ for (i = 0; i < totfds; i++)
+ if (dev_fd_list[i] == pid)
+ return i;
+
+ return -1;
+}
+
+void
+set_procsub_status (ind, pid, status)
+ int ind;
+ pid_t pid;
+ int status;
+{
+ if (ind >= 0 && ind < totfds)
+ dev_fd_list[ind] = (pid_t)-1; /* sentinel */
+}
+
+/* If we've marked the process for this procsub as dead, close the
+ associated file descriptor. */
+void
+reap_procsubs ()
+{
+ int i;
+
+ for (i = 0; nfds > 0 && i < totfds; i++)
+ if (dev_fd_list[i] == (pid_t)-1)
+ unlink_fifo (i);
+}
+
+void
+wait_procsubs ()
+{
+ int i, r;
+
+ for (i = 0; nfds > 0 && i < totfds; i++)
+ {
+ if (dev_fd_list[i] != (pid_t)-1 && dev_fd_list[i] > 0)
+ {
+ r = wait_for (dev_fd_list[i]);
+ dev_fd_list[i] = (pid_t)-1;
+ }
+ }
+}
+
#if defined (NOTDEF)
print_dev_fd_list ()
{
--- subst.h
+++ subst.h 2019-06-05 09:15:36.846029324 +0000
@@ -261,6 +261,7 @@ extern WORD_LIST *expand_words_shellexp
extern WORD_DESC *command_substitute __P((char *, int));
extern char *pat_subst __P((char *, char *, char *, int));
+#if defined (PROCESS_SUBSTITUTION)
extern int fifos_pending __P((void));
extern int num_fifos __P((void));
extern void unlink_fifo_list __P((void));
@@ -272,6 +273,13 @@ extern void close_new_fifos __P((char *,
extern void clear_fifo_list __P((void));
+extern int find_procsub_child __P((pid_t));
+extern void set_procsub_status __P((int, pid_t, int));
+
+extern void wait_procsubs __P((void));
+extern void reap_procsubs __P((void));
+#endif
+
extern WORD_LIST *list_string_with_quotes __P((char *));
#if defined (ARRAY_VARS)