Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.2:Staging:A
bash
bash-4.4-bgpoverflow.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bash-4.4-bgpoverflow.patch of Package bash
--- 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)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor