]> git.ipfire.org Git - thirdparty/bash.git/commitdiff
fix issue with invalidating pointer to last procsub; fix boundary issues with small...
authorChet Ramey <chet.ramey@case.edu>
Fri, 26 Jul 2024 13:30:30 +0000 (09:30 -0400)
committerChet Ramey <chet.ramey@case.edu>
Fri, 26 Jul 2024 13:30:30 +0000 (09:30 -0400)
CWRU/CWRU.chlog
builtins/evalfile.c
jobs.c
jobs.h
lib/malloc/malloc.c
shell.c
variables.c
variables.h

index 66d523106c7bda7b6b8d3647601ff1c2a1b6f268..bfe8444be6c8cec41e5a6561d7cfd165a21caf50 100644 (file)
@@ -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>
index 9521934e59197eaa0f7dd2edbe1a9ba49e9a6b37..b9b325ff3ed156b6d5fcd51f982e098fec7dc5f2 100644 (file)
@@ -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 7c32e6bcae261e73ed561b1f4c99564961475892..26e907857940fc23b13bdaee50758db91e8b1f22 100644 (file)
--- 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 33afdb59beb04ec6bff07263143e3eed543485c1..d8fb2f9a268824457efbff95ae581a201fe3fac9 100644 (file)
--- 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;
 
index 7b2c3f257269d63fa266e3ffdbdf267343818222..4ad9a22393cb16c3bff2ab0524ace8bb0a2244b0 100644 (file)
@@ -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 15e005d6cd7b99d98199919000c3d133bc542c27..c89a3da2db28be67189769b5e772d4785167188e 100644 (file)
--- 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 ());
index e069ae5e5fc5020eaaaeaf43e9a998e08145121a..cd336c85b0be0035be300ba25391845baa459ace 100644 (file)
@@ -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    *
index fe8c3c23bca095126bff8ff2c4fec9e03270d3cc..8b33ea6f2c2169c6459c2a879f6953f32c25e52b 100644 (file)
@@ -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 *);