aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-05-22 20:29:00 +0000
committerEric Andersen <andersen@codepoet.org>2001-05-22 20:29:00 +0000
commitaeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc (patch)
tree34880ad3a23ca05ec02f5a53d00067d6270f703a
parent816867858b90485df6c304673cbd01d9664007b4 (diff)
downloadbusybox-w32-aeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc.tar.gz
busybox-w32-aeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc.tar.bz2
busybox-w32-aeb44c4da620cd4ec1c4f1e4f15fb227ec4dc8dc.zip
Fix a race. Sometimes by the time we got to checkjobs(), the
pipe struct had already been freed. Return immediately if the pipe is NULL.
-rw-r--r--hush.c39
-rw-r--r--shell/hush.c39
2 files changed, 54 insertions, 24 deletions
diff --git a/hush.c b/hush.c
index 46f1a77bd..a26e2f6e3 100644
--- a/hush.c
+++ b/hush.c
@@ -1243,6 +1243,9 @@ static void checkjobs()
1243 break; 1243 break;
1244 } 1244 }
1245 1245
1246 if(pi==NULL)
1247 return;
1248
1246 if (WIFEXITED(status) || WIFSIGNALED(status)) { 1249 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1247 /* child exited */ 1250 /* child exited */
1248 pi->running_progs--; 1251 pi->running_progs--;
@@ -1253,8 +1256,6 @@ static void checkjobs()
1253 remove_bg_job(pi); 1256 remove_bg_job(pi);
1254 } 1257 }
1255 } else { 1258 } else {
1256 if(pi==NULL)
1257 break;
1258 /* child stopped */ 1259 /* child stopped */
1259 pi->stopped_progs++; 1260 pi->stopped_progs++;
1260 pi->progs[prognum].is_stopped = 1; 1261 pi->progs[prognum].is_stopped = 1;
@@ -1727,31 +1728,33 @@ static int set_local_var(const char *s, int flg_export)
1727 cur->flg_export=flg_export; 1728 cur->flg_export=flg_export;
1728 else 1729 else
1729 result++; 1730 result++;
1731 free(newval);
1730 } else { 1732 } else {
1731 if(cur->flg_read_only) { 1733 if(cur->flg_read_only) {
1732 result = -1;
1733 error_msg("%s: readonly variable", name); 1734 error_msg("%s: readonly variable", name);
1735 free(newval);
1736 result = -1;
1734 } else { 1737 } else {
1735 if(flg_export>0 || cur->flg_export>1) 1738 if(flg_export>0 || cur->flg_export>1)
1736 cur->flg_export=1; 1739 cur->flg_export=1;
1737 free(cur->value); 1740 free(cur->value);
1738 cur->value = newval; 1741 cur->value = newval;
1739 newval = 0; /* protect free */
1740 } 1742 }
1741 } 1743 }
1742 } else { 1744 } else {
1743 cur = malloc(sizeof(struct variables)); 1745 cur = malloc(sizeof(struct variables));
1744 if(cur==0) { 1746 if(cur==0) {
1747 free(newval);
1745 result = -1; 1748 result = -1;
1746 } else { 1749 } else {
1747 cur->name = strdup(name); 1750 cur->name = strdup(name);
1748 if(cur->name == 0) { 1751 if(cur->name == 0) {
1749 free(cur); 1752 free(cur);
1753 free(newval);
1750 result = -1; 1754 result = -1;
1751 } else { 1755 } else {
1752 struct variables *bottom = top_vars; 1756 struct variables *bottom = top_vars;
1753 cur->value = newval; 1757 cur->value = newval;
1754 newval = 0; /* protect free */
1755 cur->next = 0; 1758 cur->next = 0;
1756 cur->flg_export = flg_export; 1759 cur->flg_export = flg_export;
1757 cur->flg_read_only = 0; 1760 cur->flg_read_only = 0;
@@ -1770,7 +1773,6 @@ static int set_local_var(const char *s, int flg_export)
1770 if(result>0) /* equivalent to previous set */ 1773 if(result>0) /* equivalent to previous set */
1771 result = 0; 1774 result = 0;
1772 } 1775 }
1773 free(newval);
1774 return result; 1776 return result;
1775} 1777}
1776 1778
@@ -2473,10 +2475,10 @@ void update_ifs_map(void)
2473 * The map[] array only really needs two bits each, and on most machines 2475 * The map[] array only really needs two bits each, and on most machines
2474 * that would be faster because of the reduced L1 cache footprint. 2476 * that would be faster because of the reduced L1 cache footprint.
2475 */ 2477 */
2476 memset(map,0,sizeof(map)); /* most characters flow through always */ 2478 memset(map,0,sizeof(map)); /* most characters flow through always */
2477 mapset("\\$'\"`", 3); /* never flow through */ 2479 mapset("\\$'\"`", 3); /* never flow through */
2478 mapset("<>;&|(){}#", 1); /* flow through if quoted */ 2480 mapset("<>;&|(){}#", 1); /* flow through if quoted */
2479 mapset(ifs, 2); /* also flow through if quoted */ 2481 mapset(ifs, 2); /* also flow through if quoted */
2480} 2482}
2481 2483
2482/* most recursion does not come through here, the exeception is 2484/* most recursion does not come through here, the exeception is
@@ -2549,7 +2551,7 @@ int shell_main(int argc, char **argv)
2549 * shell_main(), therefore we cannot rely on the BSS to zero out this 2551 * shell_main(), therefore we cannot rely on the BSS to zero out this
2550 * stuff. Reset these to 0 every time. */ 2552 * stuff. Reset these to 0 every time. */
2551 ifs = NULL; 2553 ifs = NULL;
2552 memset(map,0,sizeof(map)); 2554 /* map[] is taken care of with call to update_ifs_map() */
2553 fake_mode = 0; 2555 fake_mode = 0;
2554 interactive = 0; 2556 interactive = 0;
2555 close_me_head = NULL; 2557 close_me_head = NULL;
@@ -2650,7 +2652,20 @@ int shell_main(int argc, char **argv)
2650 opt = parse_file_outer(input); 2652 opt = parse_file_outer(input);
2651 2653
2652#ifdef BB_FEATURE_CLEAN_UP 2654#ifdef BB_FEATURE_CLEAN_UP
2653 fclose(input.file); 2655 fclose(input);
2656 if (cwd && cwd != unknown)
2657 free((char*)cwd);
2658 {
2659 struct variables *cur, *tmp;
2660 for(cur = top_vars; cur; cur = tmp) {
2661 tmp = cur->next;
2662 if (!cur->flg_read_only) {
2663 free(cur->name);
2664 free(cur->value);
2665 free(cur);
2666 }
2667 }
2668 }
2654#endif 2669#endif
2655 2670
2656final_return: 2671final_return:
diff --git a/shell/hush.c b/shell/hush.c
index 46f1a77bd..a26e2f6e3 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1243,6 +1243,9 @@ static void checkjobs()
1243 break; 1243 break;
1244 } 1244 }
1245 1245
1246 if(pi==NULL)
1247 return;
1248
1246 if (WIFEXITED(status) || WIFSIGNALED(status)) { 1249 if (WIFEXITED(status) || WIFSIGNALED(status)) {
1247 /* child exited */ 1250 /* child exited */
1248 pi->running_progs--; 1251 pi->running_progs--;
@@ -1253,8 +1256,6 @@ static void checkjobs()
1253 remove_bg_job(pi); 1256 remove_bg_job(pi);
1254 } 1257 }
1255 } else { 1258 } else {
1256 if(pi==NULL)
1257 break;
1258 /* child stopped */ 1259 /* child stopped */
1259 pi->stopped_progs++; 1260 pi->stopped_progs++;
1260 pi->progs[prognum].is_stopped = 1; 1261 pi->progs[prognum].is_stopped = 1;
@@ -1727,31 +1728,33 @@ static int set_local_var(const char *s, int flg_export)
1727 cur->flg_export=flg_export; 1728 cur->flg_export=flg_export;
1728 else 1729 else
1729 result++; 1730 result++;
1731 free(newval);
1730 } else { 1732 } else {
1731 if(cur->flg_read_only) { 1733 if(cur->flg_read_only) {
1732 result = -1;
1733 error_msg("%s: readonly variable", name); 1734 error_msg("%s: readonly variable", name);
1735 free(newval);
1736 result = -1;
1734 } else { 1737 } else {
1735 if(flg_export>0 || cur->flg_export>1) 1738 if(flg_export>0 || cur->flg_export>1)
1736 cur->flg_export=1; 1739 cur->flg_export=1;
1737 free(cur->value); 1740 free(cur->value);
1738 cur->value = newval; 1741 cur->value = newval;
1739 newval = 0; /* protect free */
1740 } 1742 }
1741 } 1743 }
1742 } else { 1744 } else {
1743 cur = malloc(sizeof(struct variables)); 1745 cur = malloc(sizeof(struct variables));
1744 if(cur==0) { 1746 if(cur==0) {
1747 free(newval);
1745 result = -1; 1748 result = -1;
1746 } else { 1749 } else {
1747 cur->name = strdup(name); 1750 cur->name = strdup(name);
1748 if(cur->name == 0) { 1751 if(cur->name == 0) {
1749 free(cur); 1752 free(cur);
1753 free(newval);
1750 result = -1; 1754 result = -1;
1751 } else { 1755 } else {
1752 struct variables *bottom = top_vars; 1756 struct variables *bottom = top_vars;
1753 cur->value = newval; 1757 cur->value = newval;
1754 newval = 0; /* protect free */
1755 cur->next = 0; 1758 cur->next = 0;
1756 cur->flg_export = flg_export; 1759 cur->flg_export = flg_export;
1757 cur->flg_read_only = 0; 1760 cur->flg_read_only = 0;
@@ -1770,7 +1773,6 @@ static int set_local_var(const char *s, int flg_export)
1770 if(result>0) /* equivalent to previous set */ 1773 if(result>0) /* equivalent to previous set */
1771 result = 0; 1774 result = 0;
1772 } 1775 }
1773 free(newval);
1774 return result; 1776 return result;
1775} 1777}
1776 1778
@@ -2473,10 +2475,10 @@ void update_ifs_map(void)
2473 * The map[] array only really needs two bits each, and on most machines 2475 * The map[] array only really needs two bits each, and on most machines
2474 * that would be faster because of the reduced L1 cache footprint. 2476 * that would be faster because of the reduced L1 cache footprint.
2475 */ 2477 */
2476 memset(map,0,sizeof(map)); /* most characters flow through always */ 2478 memset(map,0,sizeof(map)); /* most characters flow through always */
2477 mapset("\\$'\"`", 3); /* never flow through */ 2479 mapset("\\$'\"`", 3); /* never flow through */
2478 mapset("<>;&|(){}#", 1); /* flow through if quoted */ 2480 mapset("<>;&|(){}#", 1); /* flow through if quoted */
2479 mapset(ifs, 2); /* also flow through if quoted */ 2481 mapset(ifs, 2); /* also flow through if quoted */
2480} 2482}
2481 2483
2482/* most recursion does not come through here, the exeception is 2484/* most recursion does not come through here, the exeception is
@@ -2549,7 +2551,7 @@ int shell_main(int argc, char **argv)
2549 * shell_main(), therefore we cannot rely on the BSS to zero out this 2551 * shell_main(), therefore we cannot rely on the BSS to zero out this
2550 * stuff. Reset these to 0 every time. */ 2552 * stuff. Reset these to 0 every time. */
2551 ifs = NULL; 2553 ifs = NULL;
2552 memset(map,0,sizeof(map)); 2554 /* map[] is taken care of with call to update_ifs_map() */
2553 fake_mode = 0; 2555 fake_mode = 0;
2554 interactive = 0; 2556 interactive = 0;
2555 close_me_head = NULL; 2557 close_me_head = NULL;
@@ -2650,7 +2652,20 @@ int shell_main(int argc, char **argv)
2650 opt = parse_file_outer(input); 2652 opt = parse_file_outer(input);
2651 2653
2652#ifdef BB_FEATURE_CLEAN_UP 2654#ifdef BB_FEATURE_CLEAN_UP
2653 fclose(input.file); 2655 fclose(input);
2656 if (cwd && cwd != unknown)
2657 free((char*)cwd);
2658 {
2659 struct variables *cur, *tmp;
2660 for(cur = top_vars; cur; cur = tmp) {
2661 tmp = cur->next;
2662 if (!cur->flg_read_only) {
2663 free(cur->name);
2664 free(cur->value);
2665 free(cur);
2666 }
2667 }
2668 }
2654#endif 2669#endif
2655 2670
2656final_return: 2671final_return: