mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-23 05:47:59 +02:00
fix issue with invalidating pointer to last procsub; fix boundary issues with small reallocs
This commit is contained in:
@@ -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 <collin.funk1@gmail.com>
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+2
-2
@@ -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;
|
||||
|
||||
@@ -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 ());
|
||||
|
||||
+10
@@ -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 *
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
Reference in New Issue
Block a user