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.
This commit is contained in:
Eric Andersen 2001-05-22 20:29:00 +00:00
parent 816867858b
commit aeb44c4da6
2 changed files with 54 additions and 24 deletions

31
hush.c
View File

@ -1243,6 +1243,9 @@ static void checkjobs()
break; break;
} }
if(pi==NULL)
return;
if (WIFEXITED(status) || WIFSIGNALED(status)) { if (WIFEXITED(status) || WIFSIGNALED(status)) {
/* child exited */ /* child exited */
pi->running_progs--; pi->running_progs--;
@ -1253,8 +1256,6 @@ static void checkjobs()
remove_bg_job(pi); remove_bg_job(pi);
} }
} else { } else {
if(pi==NULL)
break;
/* child stopped */ /* child stopped */
pi->stopped_progs++; pi->stopped_progs++;
pi->progs[prognum].is_stopped = 1; pi->progs[prognum].is_stopped = 1;
@ -1727,31 +1728,33 @@ static int set_local_var(const char *s, int flg_export)
cur->flg_export=flg_export; cur->flg_export=flg_export;
else else
result++; result++;
free(newval);
} else { } else {
if(cur->flg_read_only) { if(cur->flg_read_only) {
result = -1;
error_msg("%s: readonly variable", name); error_msg("%s: readonly variable", name);
free(newval);
result = -1;
} else { } else {
if(flg_export>0 || cur->flg_export>1) if(flg_export>0 || cur->flg_export>1)
cur->flg_export=1; cur->flg_export=1;
free(cur->value); free(cur->value);
cur->value = newval; cur->value = newval;
newval = 0; /* protect free */
} }
} }
} else { } else {
cur = malloc(sizeof(struct variables)); cur = malloc(sizeof(struct variables));
if(cur==0) { if(cur==0) {
free(newval);
result = -1; result = -1;
} else { } else {
cur->name = strdup(name); cur->name = strdup(name);
if(cur->name == 0) { if(cur->name == 0) {
free(cur); free(cur);
free(newval);
result = -1; result = -1;
} else { } else {
struct variables *bottom = top_vars; struct variables *bottom = top_vars;
cur->value = newval; cur->value = newval;
newval = 0; /* protect free */
cur->next = 0; cur->next = 0;
cur->flg_export = flg_export; cur->flg_export = flg_export;
cur->flg_read_only = 0; cur->flg_read_only = 0;
@ -1770,7 +1773,6 @@ static int set_local_var(const char *s, int flg_export)
if(result>0) /* equivalent to previous set */ if(result>0) /* equivalent to previous set */
result = 0; result = 0;
} }
free(newval);
return result; return result;
} }
@ -2549,7 +2551,7 @@ int shell_main(int argc, char **argv)
* shell_main(), therefore we cannot rely on the BSS to zero out this * shell_main(), therefore we cannot rely on the BSS to zero out this
* stuff. Reset these to 0 every time. */ * stuff. Reset these to 0 every time. */
ifs = NULL; ifs = NULL;
memset(map,0,sizeof(map)); /* map[] is taken care of with call to update_ifs_map() */
fake_mode = 0; fake_mode = 0;
interactive = 0; interactive = 0;
close_me_head = NULL; close_me_head = NULL;
@ -2650,7 +2652,20 @@ int shell_main(int argc, char **argv)
opt = parse_file_outer(input); opt = parse_file_outer(input);
#ifdef BB_FEATURE_CLEAN_UP #ifdef BB_FEATURE_CLEAN_UP
fclose(input.file); fclose(input);
if (cwd && cwd != unknown)
free((char*)cwd);
{
struct variables *cur, *tmp;
for(cur = top_vars; cur; cur = tmp) {
tmp = cur->next;
if (!cur->flg_read_only) {
free(cur->name);
free(cur->value);
free(cur);
}
}
}
#endif #endif
final_return: final_return:

View File

@ -1243,6 +1243,9 @@ static void checkjobs()
break; break;
} }
if(pi==NULL)
return;
if (WIFEXITED(status) || WIFSIGNALED(status)) { if (WIFEXITED(status) || WIFSIGNALED(status)) {
/* child exited */ /* child exited */
pi->running_progs--; pi->running_progs--;
@ -1253,8 +1256,6 @@ static void checkjobs()
remove_bg_job(pi); remove_bg_job(pi);
} }
} else { } else {
if(pi==NULL)
break;
/* child stopped */ /* child stopped */
pi->stopped_progs++; pi->stopped_progs++;
pi->progs[prognum].is_stopped = 1; pi->progs[prognum].is_stopped = 1;
@ -1727,31 +1728,33 @@ static int set_local_var(const char *s, int flg_export)
cur->flg_export=flg_export; cur->flg_export=flg_export;
else else
result++; result++;
free(newval);
} else { } else {
if(cur->flg_read_only) { if(cur->flg_read_only) {
result = -1;
error_msg("%s: readonly variable", name); error_msg("%s: readonly variable", name);
free(newval);
result = -1;
} else { } else {
if(flg_export>0 || cur->flg_export>1) if(flg_export>0 || cur->flg_export>1)
cur->flg_export=1; cur->flg_export=1;
free(cur->value); free(cur->value);
cur->value = newval; cur->value = newval;
newval = 0; /* protect free */
} }
} }
} else { } else {
cur = malloc(sizeof(struct variables)); cur = malloc(sizeof(struct variables));
if(cur==0) { if(cur==0) {
free(newval);
result = -1; result = -1;
} else { } else {
cur->name = strdup(name); cur->name = strdup(name);
if(cur->name == 0) { if(cur->name == 0) {
free(cur); free(cur);
free(newval);
result = -1; result = -1;
} else { } else {
struct variables *bottom = top_vars; struct variables *bottom = top_vars;
cur->value = newval; cur->value = newval;
newval = 0; /* protect free */
cur->next = 0; cur->next = 0;
cur->flg_export = flg_export; cur->flg_export = flg_export;
cur->flg_read_only = 0; cur->flg_read_only = 0;
@ -1770,7 +1773,6 @@ static int set_local_var(const char *s, int flg_export)
if(result>0) /* equivalent to previous set */ if(result>0) /* equivalent to previous set */
result = 0; result = 0;
} }
free(newval);
return result; return result;
} }
@ -2549,7 +2551,7 @@ int shell_main(int argc, char **argv)
* shell_main(), therefore we cannot rely on the BSS to zero out this * shell_main(), therefore we cannot rely on the BSS to zero out this
* stuff. Reset these to 0 every time. */ * stuff. Reset these to 0 every time. */
ifs = NULL; ifs = NULL;
memset(map,0,sizeof(map)); /* map[] is taken care of with call to update_ifs_map() */
fake_mode = 0; fake_mode = 0;
interactive = 0; interactive = 0;
close_me_head = NULL; close_me_head = NULL;
@ -2650,7 +2652,20 @@ int shell_main(int argc, char **argv)
opt = parse_file_outer(input); opt = parse_file_outer(input);
#ifdef BB_FEATURE_CLEAN_UP #ifdef BB_FEATURE_CLEAN_UP
fclose(input.file); fclose(input);
if (cwd && cwd != unknown)
free((char*)cwd);
{
struct variables *cur, *tmp;
for(cur = top_vars; cur; cur = tmp) {
tmp = cur->next;
if (!cur->flg_read_only) {
free(cur->name);
free(cur->value);
free(cur);
}
}
}
#endif #endif
final_return: final_return: