You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							177 lines
						
					
					
						
							5.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							177 lines
						
					
					
						
							5.0 KiB
						
					
					
				| 			     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_ */
 | |
| 
 |