Hello,

  This is ksh-20120801 as packaged in fedora 20 and rhel 7, at least.

  A simple reproducer is:

---%<---
#!/bin/ksh
f()
{(
# trap "" HUP
)}
trap "" HUP
while [ 1 ] ; do
  f
done
---%<---

and the proposed patch is:
---%<---
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;

---%<---

The patch is required because some code may do the sequence:
tmp=strdup(shp->trapcom[i]);
free(shp->trapcom[i]);
shp->trapcom[i]=tmp;

or maybe just change it. The patch does a "deep copy" of the strings,
to ensure it will not restore to possibly already free'ed pointers.

Thanks,
Paulo
_______________________________________________
ast-users mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-users

Reply via email to