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
This commit is contained in:
parent
9c4241c3d7
commit
586fd24857
@ -460,7 +460,6 @@ expbackq(union node *cmd, int quoted, int flag, struct worddest *dst)
|
||||
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, int flag, struct worddest *dst)
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
6
bin/sh/tests/expansion/cmdsubst21.0
Normal file
6
bin/sh/tests/expansion/cmdsubst21.0
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -T
|
||||
trapped=''
|
||||
trap "trapped=x$trapped" TERM
|
||||
[ "x$($SH -c "kill $$")y" = xy ] && [ "$trapped" = x ]
|
6
bin/sh/tests/expansion/cmdsubst22.0
Normal file
6
bin/sh/tests/expansion/cmdsubst22.0
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -T
|
||||
trapped=''
|
||||
trap "trapped=x$trapped" TERM
|
||||
[ "x$(:; kill $$)y" = xy ] && [ "$trapped" = x ]
|
Loading…
Reference in New Issue
Block a user