From: Chet Ramey Date: Fri, 26 Jul 2024 13:30:30 +0000 (-0400) Subject: fix issue with invalidating pointer to last procsub; fix boundary issues with small... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d5ef283cbdd08217efdc55974a6a8a2c52a7562f;p=thirdparty%2Fbash.git fix issue with invalidating pointer to last procsub; fix boundary issues with small reallocs --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 66d52310..bfe8444b 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -9858,3 +9858,17 @@ builtins/wait.def PROC_WAITING if we have one - unset_waitlist: unset PROC_WAITING in all procsubs + 7/18 + ---- +jobs.c + - procsub_prune: set last_procsub_child to NULL if we are cleaning up + that process because it's terminated, since that will invalidate the + pointer + + 7/22 + ---- +lib/malloc/malloc.c + - RIGHT_BUCKET: don't check binsizes[nu-1] unless nu >= 1; clamp at 0 + otherwise + - internal_realloc: don't check bucket at nunits-1 unless nunits >= 1 + Report and fix from Collin Funk diff --git a/builtins/evalfile.c b/builtins/evalfile.c index 9521934e..b9b325ff 100644 --- a/builtins/evalfile.c +++ b/builtins/evalfile.c @@ -245,7 +245,7 @@ file_error_and_exit: GET_ARRAY_FROM_VAR ("BASH_ARGC", bash_argc_v, bash_argc_a); # endif - array_push (bash_source_a, (char *)filename); + push_source (bash_source_a, (char *)filename); t = itos (executing_line_number ()); array_push (bash_lineno_a, t); free (t); diff --git a/jobs.c b/jobs.c index 7c32e6bc..26e90785 100644 --- a/jobs.c +++ b/jobs.c @@ -233,6 +233,7 @@ int already_making_children = 0; int check_window_size = CHECKWINSIZE_DEFAULT; PROCESS *last_procsub_child = (PROCESS *)NULL; +pid_t last_procsub_pid = NO_PID; /* Set to non-zero if you want to force job notifications even in contexts where the shell would defer them. */ @@ -1067,6 +1068,8 @@ procsub_search (pid_t pid, int block) return p; } +/* Take the PROCESS * corresponding to PID out of the procsubs list and + return it. */ PROCESS * procsub_delete (pid_t pid, int block) { @@ -1151,7 +1154,9 @@ procsub_clear (void) procsub_free (p); } procsubs.head = procsubs.end = 0; - procsubs.nproc = 0; + procsubs.nproc = 0; + + last_procsub_child = NULL; UNBLOCK_CHILD (oset); } @@ -1179,6 +1184,8 @@ procsub_prune (void) if (p->running == PS_DONE) { bgp_add (p->pid, process_exit_status (p->status)); + if (p == last_procsub_child) + last_procsub_child = NULL; procsub_free (p); } else @@ -1194,7 +1201,6 @@ procsub_reap (void) QUEUE_SIGCHLD(os); procsub_prune (); - last_procsub_child = (PROCESS *)NULL; UNQUEUE_SIGCHLD (os); } @@ -1314,7 +1320,6 @@ cleanup_dead_jobs (void) #if defined (PROCESS_SUBSTITUTION) /* Don't need to call procsub_reap() since SIGCHLD is already blocked. */ procsub_prune (); - last_procsub_child = (PROCESS *)NULL; #endif #if defined (COPROCESS_SUPPORT) @@ -3469,9 +3474,17 @@ return_job: /* If we're waiting for specific pids, skip over ones we're not interested in. */ if ((flags & JWAIT_WAITING) && (p->flags & PROC_WAITING) == 0) continue; +#if 0 + /* If we want to restrict wait -n without pid arguments to only wait + for last_procsub_child->pid, uncomment this. */ + if ((flags & JWAIT_WAITING) == 0 && p != last_procsub_child) + continue; +#endif if (p->running == PS_DONE) { return_procsub: + if (p == last_procsub_child) + last_procsub_child = (PROCESS *)NULL; r = process_exit_status (p->status); pid = p->pid; if (ps) @@ -3479,7 +3492,10 @@ return_procsub: ps->pid = pid; ps->status = r; } - procsub_delete (pid, 0); /* XXX - procsub_reap? */ + child = procsub_delete (pid, 0); /* XXX - procsub_reap? */ + if (child == last_procsub_child) + last_procsub_child = NULL; + procsub_free (child); if (posixly_correct) bgp_delete (pid); UNBLOCK_CHILD (oset); @@ -3515,6 +3531,12 @@ return_procsub: { if ((flags & JWAIT_WAITING) && (p->flags & PROC_WAITING) == 0) continue; +#if 0 + /* If we want to restrict wait -n without pid arguments to only wait + for last_procsub_child->pid, uncomment this. */ + if ((flags & JWAIT_WAITING) == 0 && p != last_procsub_child && p->running == PS_DONE) + continue; +#endif else if (p->running == PS_DONE) goto return_procsub; else if (p->running == PS_RUNNING) /* still got one */ diff --git a/jobs.h b/jobs.h index 33afdb59..d8fb2f9a 100644 --- a/jobs.h +++ b/jobs.h @@ -237,6 +237,7 @@ extern int already_making_children; extern int running_in_background; extern PROCESS *last_procsub_child; +extern pid_t last_procsub_pid; extern JOB **jobs; diff --git a/lib/malloc/malloc.c b/lib/malloc/malloc.c index 7b2c3f25..4ad9a223 100644 --- a/lib/malloc/malloc.c +++ b/lib/malloc/malloc.c @@ -274,7 +274,7 @@ typedef union _malloc_guard { /* Use this when we want to be sure that NB is in bucket NU. */ #define RIGHT_BUCKET(nb, nu) \ - (((nb) > binsizes[(nu)-1]) && ((nb) <= binsizes[(nu)])) + (((nb) > (((nu) >= 1) ? binsizes[(nu)-1] : 0UL)) && ((nb) <= binsizes[(nu)])) /* nextf[i] is free list of blocks of size 2**(i + 5) */ @@ -1202,7 +1202,7 @@ internal_realloc (PTR_T mem, size_t n, const char *file, int line, int flags) nbytes = ALLOCATED_BYTES(n); /* If ok, use the same block, just marking its size as changed. */ - if (RIGHT_BUCKET(nbytes, nunits) || RIGHT_BUCKET(nbytes, nunits-1)) + if (RIGHT_BUCKET(nbytes, nunits) || (nunits >= 1 && RIGHT_BUCKET(nbytes, nunits-1))) { /* Compensate for increment above. */ m -= 4; diff --git a/shell.c b/shell.c index 15e005d6..c89a3da2 100644 --- a/shell.c +++ b/shell.c @@ -1638,7 +1638,7 @@ open_shell_script (char *script_name) GET_ARRAY_FROM_VAR ("BASH_SOURCE", bash_source_v, bash_source_a); GET_ARRAY_FROM_VAR ("BASH_LINENO", bash_lineno_v, bash_lineno_a); - array_push (bash_source_a, filename); + push_source (bash_source_a, filename); if (bash_lineno_a) { t = itos (executing_line_number ()); diff --git a/variables.c b/variables.c index e069ae5e..cd336c85 100644 --- a/variables.c +++ b/variables.c @@ -5688,6 +5688,16 @@ uw_pop_args (void *ignore) pop_args (); } +#if defined (ARRAY_VARS) +/* Push the current input filename onto BASH_SOURCE. This is where we can + apply any policy. */ +void +push_source (ARRAY *a, char *filename) +{ + array_push (a, filename); +} +#endif + /************************************************* * * * Functions to manage special variables * diff --git a/variables.h b/variables.h index fe8c3c23..8b33ea6f 100644 --- a/variables.h +++ b/variables.h @@ -375,6 +375,10 @@ extern void push_args (WORD_LIST *); extern void pop_args (void); extern void uw_pop_args (void *); +#if defined (ARRAY_VARS) +extern void push_source (ARRAY *, char *); +#endif + extern void adjust_shell_level (int); extern void non_unsettable (char *); extern void dispose_variable (SHELL_VAR *);