mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix off-by-one error, possible crash (re: 6193c6a3
)
The ksh-20120801-trapcom.patch patch contains an off-by-one error,
which was also imported into 93u+m. When saving signals:
ceb77b136f/src/cmd/ksh93/sh/subshell.c (L572-L592)
572 if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
573 {
574 ++nsig;
575 savsig = malloc(nsig * sizeof(char*));
576 /*
577 * the data is, usually, modified in code like:
578 * tmp = buf[i]; buf[i] = strdup(tmp); free(tmp);
579 * so shp->st.trapcom needs a "deep copy" to properly save/restore pointers.
580 */
581 for (isig = 0; isig < nsig; ++isig)
582 {
583 if(shp->st.trapcom[isig] == Empty)
584 savsig[isig] = Empty;
585 else if(shp->st.trapcom[isig])
586 savsig[isig] = strdup(shp->st.trapcom[isig]);
587 else
588 savsig[isig] = NULL;
589 }
On line 574, the number of signals 'nsig' is increased by one. That
increase is permanent, so the 'for' loop on line 581 tries to save
one signal state too many.
The increase was a holdout from the ksh93 code from before the
patch. After the patch, it is not required; it is fine to malloc as
many records as there are trapcom elements to save. So it should
simply be removed. xec.c has the same code to save trap states for
ksh functions, and the same applies.
src/cmd/ksh93/sh/subshell.c: sh_subshell():
- Don't increase nsig.
src/cmd/ksh93/sh/xec.c: sh_funscope():
- Same.
src/cmd/ksh93/tests/signal.sh:
- Add test.
This commit is contained in:
parent
f527706f6c
commit
3aee10d781
3 changed files with 14 additions and 2 deletions
|
@ -571,7 +571,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
|
||||||
shp->st.otrap = savst.trap;
|
shp->st.otrap = savst.trap;
|
||||||
if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
|
if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
|
||||||
{
|
{
|
||||||
++nsig;
|
|
||||||
savsig = malloc(nsig * sizeof(char*));
|
savsig = malloc(nsig * sizeof(char*));
|
||||||
/*
|
/*
|
||||||
* the data is, usually, modified in code like:
|
* the data is, usually, modified in code like:
|
||||||
|
|
|
@ -3096,7 +3096,6 @@ int sh_funscope(int argn, char *argv[],int(*fun)(void*),void *arg,int execflg)
|
||||||
/* save trap table */
|
/* save trap table */
|
||||||
if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
|
if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
|
||||||
{
|
{
|
||||||
++nsig;
|
|
||||||
savsig = malloc(nsig * sizeof(char*));
|
savsig = malloc(nsig * sizeof(char*));
|
||||||
/*
|
/*
|
||||||
* the data is, usually, modified in code like:
|
* the data is, usually, modified in code like:
|
||||||
|
|
|
@ -480,5 +480,19 @@ then
|
||||||
kill -INFO $$ || err_exit '`kill` cannot send SIGINFO to processes when passed `-INFO`'
|
kill -INFO $$ || err_exit '`kill` cannot send SIGINFO to processes when passed `-INFO`'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# ======
|
||||||
|
# Due to an off-by-one error, the last signal in 'kill -l' output wasn't treated properly and could crash.
|
||||||
|
|
||||||
|
sig=$(kill -l | tail -n 1)
|
||||||
|
exp="OK: $sig"
|
||||||
|
|
||||||
|
got=$(export sig; "$SHELL" -c '
|
||||||
|
trap "print '\''OK: $sig'\''" "$sig"
|
||||||
|
(kill -s "$sig" "$$")
|
||||||
|
trap - "$sig"
|
||||||
|
' 2>&1)
|
||||||
|
((!(e = $?))) && [[ $got == "$exp" ]] || err_exit "failed to handle SIG$sig from subshell" \
|
||||||
|
"(got status $e$( ((e>128)) && print -n / && kill -l "$e"), $(printf %q "$got"))"
|
||||||
|
|
||||||
# ======
|
# ======
|
||||||
exit $((Errors<125?Errors:125))
|
exit $((Errors<125?Errors:125))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue