Author: jilles
Date: Sat Mar  4 22:58:34 2017
New Revision: 314686
URL: https://svnweb.freebsd.org/changeset/base/314686

Log:
  sh: Fix crash if a -T trap is taken during command substitution.
  
  Code like  t=$(stat -f %m "$file")  segfaulted if -T was active and a trap
  was taken while the shell was waiting for the child process to finish.
  
  What happened was that the dotrap() call in waitforjob() was hit. This
  re-entered command execution (including expand.c) at a point not expected by
  expbackq(), and global state (unallocated stack string and argbackq) was
  corrupted.
  
  To fix this, change expbackq() to prepare for command execution to be
  re-entered.
  
  Reported by:  bdrewery
  MFC after:    1 week

Added:
  head/bin/sh/tests/expansion/cmdsubst21.0   (contents, props changed)
  head/bin/sh/tests/expansion/cmdsubst22.0   (contents, props changed)
Modified:
  head/bin/sh/expand.c
  head/bin/sh/tests/expansion/Makefile

Modified: head/bin/sh/expand.c
==============================================================================
--- head/bin/sh/expand.c        Sat Mar  4 22:38:10 2017        (r314685)
+++ head/bin/sh/expand.c        Sat Mar  4 22:58:34 2017        (r314686)
@@ -460,7 +460,6 @@ expbackq(union node *cmd, int quoted, in
        p = grabstackstr(dest);
        evalbackcmd(cmd, &in);
        ungrabstackstr(p, dest);
-       argbackq = saveargbackq;
 
        p = in.buf;
        nnl = 0;
@@ -514,12 +513,16 @@ expbackq(union node *cmd, int quoted, in
                close(in.fd);
        if (in.buf)
                ckfree(in.buf);
-       if (in.jp)
+       if (in.jp) {
+               p = grabstackstr(dest);
                exitstatus = waitforjob(in.jp, (int *)NULL);
+               ungrabstackstr(p, dest);
+       }
        TRACE(("expbackq: size=%td: \"%.*s\"\n",
                ((dest - stackblock()) - startloc),
                (int)((dest - stackblock()) - startloc),
                stackblock() + startloc));
+       argbackq = saveargbackq;
        expdest = dest;
        INTON;
 }

Modified: head/bin/sh/tests/expansion/Makefile
==============================================================================
--- head/bin/sh/tests/expansion/Makefile        Sat Mar  4 22:38:10 2017        
(r314685)
+++ head/bin/sh/tests/expansion/Makefile        Sat Mar  4 22:58:34 2017        
(r314686)
@@ -42,6 +42,8 @@ ${PACKAGE}FILES+=     cmdsubst17.0
 ${PACKAGE}FILES+=      cmdsubst18.0
 ${PACKAGE}FILES+=      cmdsubst19.0
 ${PACKAGE}FILES+=      cmdsubst20.0
+${PACKAGE}FILES+=      cmdsubst21.0
+${PACKAGE}FILES+=      cmdsubst22.0
 ${PACKAGE}FILES+=      export1.0
 ${PACKAGE}FILES+=      export2.0
 ${PACKAGE}FILES+=      export3.0

Added: head/bin/sh/tests/expansion/cmdsubst21.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/bin/sh/tests/expansion/cmdsubst21.0    Sat Mar  4 22:58:34 2017        
(r314686)
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+set -T
+trapped=''
+trap "trapped=x$trapped" TERM
+[ "x$($SH -c "kill $$")y" = xy ] && [ "$trapped" = x ]

Added: head/bin/sh/tests/expansion/cmdsubst22.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/bin/sh/tests/expansion/cmdsubst22.0    Sat Mar  4 22:58:34 2017        
(r314686)
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+set -T
+trapped=''
+trap "trapped=x$trapped" TERM
+[ "x$(:; kill $$)y" = xy ] && [ "$trapped" = x ]
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to