123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- BASH PATCH REPORT
- =================
- Bash-Release: 4.4
- Patch-ID: bash44-020
- Bug-Reported-by: Graham Northup <northug@clarkson.edu>
- Bug-Reference-ID: <537530c3-61f0-349b-9de6-fa4e2487f428@clarkson.edu>
- Bug-Reference-URL: http://lists.gnu.org/archive/html/bug-bash/2017-02/msg00025.html
- Bug-Description:
- In circumstances involving long-running scripts that create and reap many
- processes, it is possible for the hash table bash uses to store exit
- statuses from asynchronous processes to develop loops. This patch fixes
- the loop causes and adds code to detect any future loops.
- Patch (apply with `patch -p0'):
- *** ../bash-4.4-patched/jobs.c 2016-11-11 13:42:55.000000000 -0500
- --- jobs.c 2017-02-22 15:16:28.000000000 -0500
- ***************
- *** 813,818 ****
- struct pidstat *ps;
-
- ! bucket = pshash_getbucket (pid);
- ! psi = bgp_getindex ();
- ps = &bgpids.storage[psi];
-
- --- 796,815 ----
- struct pidstat *ps;
-
- ! /* bucket == existing chain of pids hashing to same value
- ! psi = where were going to put this pid/status */
- !
- ! bucket = pshash_getbucket (pid); /* index into pidstat_table */
- ! psi = bgp_getindex (); /* bgpids.head, index into storage */
- !
- ! /* XXX - what if psi == *bucket? */
- ! if (psi == *bucket)
- ! {
- ! #ifdef DEBUG
- ! internal_warning ("hashed pid %d (pid %d) collides with bgpids.head, skipping", psi, pid);
- ! #endif
- ! bgpids.storage[psi].pid = NO_PID; /* make sure */
- ! psi = bgp_getindex (); /* skip to next one */
- ! }
- !
- ps = &bgpids.storage[psi];
-
- ***************
- *** 842,845 ****
- --- 839,843 ----
- {
- struct pidstat *ps;
- + ps_index_t *bucket;
-
- ps = &bgpids.storage[psi];
- ***************
- *** 847,856 ****
- return;
-
- ! if (ps->bucket_next != NO_PID)
- bgpids.storage[ps->bucket_next].bucket_prev = ps->bucket_prev;
- ! if (ps->bucket_prev != NO_PID)
- bgpids.storage[ps->bucket_prev].bucket_next = ps->bucket_next;
- else
- ! *(pshash_getbucket (ps->pid)) = ps->bucket_next;
- }
-
- --- 845,861 ----
- return;
-
- ! if (ps->bucket_next != NO_PIDSTAT)
- bgpids.storage[ps->bucket_next].bucket_prev = ps->bucket_prev;
- ! if (ps->bucket_prev != NO_PIDSTAT)
- bgpids.storage[ps->bucket_prev].bucket_next = ps->bucket_next;
- else
- ! {
- ! bucket = pshash_getbucket (ps->pid);
- ! *bucket = ps->bucket_next; /* deleting chain head in hash table */
- ! }
- !
- ! /* clear out this cell, just in case */
- ! ps->pid = NO_PID;
- ! ps->bucket_next = ps->bucket_prev = NO_PIDSTAT;
- }
-
- ***************
- *** 859,863 ****
- pid_t pid;
- {
- ! ps_index_t psi;
-
- if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
- --- 864,868 ----
- pid_t pid;
- {
- ! ps_index_t psi, orig_psi;
-
- if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
- ***************
- *** 865,871 ****
-
- /* Search chain using hash to find bucket in pidstat_table */
- ! for (psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
- ! if (bgpids.storage[psi].pid == pid)
- ! break;
-
- if (psi == NO_PIDSTAT)
- --- 870,883 ----
-
- /* Search chain using hash to find bucket in pidstat_table */
- ! for (orig_psi = psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
- ! {
- ! if (bgpids.storage[psi].pid == pid)
- ! break;
- ! if (orig_psi == bgpids.storage[psi].bucket_next) /* catch reported bug */
- ! {
- ! internal_warning ("bgp_delete: LOOP: psi (%d) == storage[psi].bucket_next", psi);
- ! return 0;
- ! }
- ! }
-
- if (psi == NO_PIDSTAT)
- ***************
- *** 905,909 ****
- pid_t pid;
- {
- ! ps_index_t psi;
-
- if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
- --- 917,921 ----
- pid_t pid;
- {
- ! ps_index_t psi, orig_psi;
-
- if (bgpids.storage == 0 || bgpids.nalloc == 0 || bgpids.npid == 0)
- ***************
- *** 911,917 ****
-
- /* Search chain using hash to find bucket in pidstat_table */
- ! for (psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
- ! if (bgpids.storage[psi].pid == pid)
- ! return (bgpids.storage[psi].status);
-
- return -1;
- --- 923,936 ----
-
- /* Search chain using hash to find bucket in pidstat_table */
- ! for (orig_psi = psi = *(pshash_getbucket (pid)); psi != NO_PIDSTAT; psi = bgpids.storage[psi].bucket_next)
- ! {
- ! if (bgpids.storage[psi].pid == pid)
- ! return (bgpids.storage[psi].status);
- ! if (orig_psi == bgpids.storage[psi].bucket_next) /* catch reported bug */
- ! {
- ! internal_warning ("bgp_search: LOOP: psi (%d) == storage[psi].bucket_next", psi);
- ! return -1;
- ! }
- ! }
-
- return -1;
- *** ../bash-4.4/patchlevel.h 2016-06-22 14:51:03.000000000 -0400
- --- patchlevel.h 2016-10-01 11:01:28.000000000 -0400
- ***************
- *** 26,30 ****
- looks for to find the patch level (for the sccs version string). */
-
- ! #define PATCHLEVEL 19
-
- #endif /* _PATCHLEVEL_H_ */
- --- 26,30 ----
- looks for to find the patch level (for the sccs version string). */
-
- ! #define PATCHLEVEL 20
-
- #endif /* _PATCHLEVEL_H_ */
|