diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.orig ksh-20120801/src/cmd/ksh93/sh/subshell.c --- ksh-20120801/src/cmd/ksh93/sh/subshell.c.orig 2014-08-23 20:20:24.676186573 -0300 +++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-08-23 20:29:00.772151283 -0300 @@ -481,12 +481,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ { struct subshell sub_data; register struct subshell *sp = &sub_data; - int jmpval,nsig=0,duped=0; + int jmpval,isig,nsig=0,duped=0; long savecurenv = shp->curenv; int savejobpgid = job.curpgid; int *saveexitval = job.exitval; int16_t subshell; - char *savsig; + char **savsig; Sfio_t *iop=0; struct checkpt buff; struct sh_scoped savst; @@ -561,10 +561,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ /* save trap table */ shp->st.otrapcom = 0; shp->st.otrap = savst.trap; - if((nsig=shp->st.trapmax*sizeof(char*))>0 || shp->st.trapcom[0]) + if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0]) { - nsig += sizeof(char*); - memcpy(savsig=malloc(nsig),(char*)&shp->st.trapcom[0],nsig); + ++nsig; + savsig = malloc(nsig * sizeof(char*)); + /* contents of shp->st.st.trapcom may change */ + for (isig = 0; isig < nsig; ++isig) + savsig[isig] = shp->st.trapcom[isig] ? strdup(shp->st.trapcom[isig]) : NULL; /* this nonsense needed for $(trap) */ shp->st.otrapcom = (char**)savsig; } @@ -729,7 +732,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ shp->st.otrap = 0; if(nsig) { - memcpy((char*)&shp->st.trapcom[0],savsig,nsig); + for (isig = 0; isig < nsig; ++isig) + if (shp->st.trapcom[isig]) + free(shp->st.trapcom[isig]); + memcpy((char*)&shp->st.trapcom[0],savsig,nsig*sizeof(char*)); free((void*)savsig); } shp->options = sp->options;