Hi,

  I have this test case:

---8<---
#!/bin/ksh
toto="s"
alarm -r alarm_handler +1
function alarm_handler.alarm
{
if [[ $toto == "s" ]]
then
toto="e"
else
toto="f"
fi
}
IFS=","
(echo "2";sleep 1;echo "3") | while IFS="," read  arg1
#(echo "2";sleep 1;echo "3") | while  read  arg1
do
print "$arg1"
done
---8<---

provided by a user. The test case causes it to start reading
random memory in src/cmd/ksh93/bltins/read.c in this chunk
of sh_readline:

---%<---
            /* skip over word characters */
            wrd = -1;
            while(1)
            {
                while((c=shp->ifstable[*cp++])==0)     <<<=== HERE
                    if(!wrd)
                        wrd = 1;
---%<---

A example gdb session after finding the root of the problem is:

---%<---
$ gdb --args /home/pcpa/rhel/ksh/ksh-20120801/arch/linux.i386-64/bin/ksh t2.ksh
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-51.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from
/home/pcpa/rhel/ksh/ksh-20120801/arch/linux.i386-64/bin/ksh...done.
(gdb) b sh_readline
Breakpoint 1 at 0x4825f9: file
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c, line
215.
(gdb) r
Starting program:
/home/pcpa/rhel/ksh/ksh-20120801/arch/linux.i386-64/bin/ksh t2.ksh
Detaching after fork from child process 11872.

Breakpoint 1, sh_readline (shp=0x795300 <sh>, names=0x7ffff7fae9a8,
fd=0, flags=0, size=0, timeout=0)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:215
215        char            was_escape = 0;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7_0.1.x86_64
(gdb) p &shp->ifstable [0]
$1 = 0x795930 <sh+1584> ""
(gdb) watch *(char*)$1
Hardware watchpoint 2: *(char*)$1
(gdb) p $1
$2 = 0x795930 <sh+1584> ""
(gdb) c
Continuing.
Hardware watchpoint 2: *(char*)$1

Old value = 0 '\000'
New value = 2 '\002'
sh_readline (shp=0x7fffffffc0dc, names=0x7ffff7fae9b0, fd=0, flags=0,
size=0, timeout=0)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:310
310            if((flags&SS_FLAG))
(gdb) bt
#0  sh_readline (shp=0x7fffffffc0dc, names=0x7ffff7fae9b0, fd=0,
flags=0, size=0, timeout=0)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:310
#1  0x00000000004824ef in b_read (argc=2, argv=0x7ffff7fae9a8,
context=0x795810 <sh+1296>)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:177
#2  0x0000000000466b98 in sh_exec (t=0x7fffffffc0dc, flags=512) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1410
#3  0x000000000046a326 in sh_exec (t=0x7fffffffc0dc, flags=4) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2485
#4  0x0000000000468847 in sh_exec (t=0x7fffffffc0dc, flags=4) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1978
#5  0x00000000004693d2 in sh_exec (t=0x7fffffffc0dc, flags=4) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2195
#6  0x000000000040738f in exfile (shp=0x7fffffffc0dc,
iop=0x7ffff7f930e1, fno=0) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:581
#7  0x0000000000406847 in sh_main (ac=2, av=0x7fffffffe0a8,
userinit=0x0) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:353
#8  0x0000000000405c55 in main (argc=2, argv=0x7fffffffe0a8) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/pmain.c:45
(gdb) c
Continuing.
Hardware watchpoint 2: *(char*)$1

Old value = 2 '\002'
New value = 0 '\000'
0x00007ffff739bc1f in __memset_sse2 () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff739bc1f in __memset_sse2 () from /lib64/libc.so.6
#1  0x0000000000421cd3 in get_ifs (np=0x7ffff7fb0b38,
fp=0x7ffff7fb0610) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/init.c:546
#2  0x0000000000407a49 in nv_getv (np=0x7ffff7fb0b38, nfp=0x795930
<sh+1584>) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/nvdisc.c:58
#3  0x0000000000448b6e in nv_getval (np=0x7ffff7fb0b38) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/name.c:2801
#4  0x0000000000447da2 in table_unset (shp=0x795300 <sh>,
root=0x7ffff7f93290, flags=524289, oroot=0x7ffff7fcaf80)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/name.c:2446
#5  0x000000000044ab37 in sh_unscope (shp=0x795300 <sh>) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/name.c:3548
#6  0x000000000046d760 in sh_funscope (argn=1, argv=0x7fffffffb9c8,
fun=0x0, arg=0x7fffffffb8e0, execflg=0)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:3482
#7  0x000000000046dc27 in sh_funct (shp=0x795300 <sh>,
np=0x7ffff7f92910, argn=1, argv=0x7fffffffb9c8, envlist=0x0,
execflg=0)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:3556
#8  0x000000000046e1dd in sh_fun (np=0x7ffff7f92910,
nq=0x7ffff7f92240, argv=0x7fffffffb9c8)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:3630
#9  0x000000000047952c in sh_timetraps (shp=0x795300 <sh>) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/alarm.c:144
#10 0x00000000004794ab in trap_timeout (handle=0x7ffff7f922d0) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/alarm.c:126
#11 0x0000000000461456 in sigalrm (sig=14) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/timers.c:162
#12 <signal handler called>
#13 _sffilbuf (f=0x792dc0 <_Sfstdin>, n=-1) at
/home/pcpa/rhel/ksh/ksh-20120801/src/lib/libast/sfio/sffilbuf.c:94
#14 0x00000000004e0556 in sfgetr (f=0x792dc0 <_Sfstdin>, rc=10,
type=0) at /home/pcpa/rhel/ksh/ksh-20120801/src/lib/libast/sfio/sfgetr.c:81
#15 0x0000000000483830 in sh_readline (shp=0x792dc0 <_Sfstdin>,
names=0x7ffff7fae9b0, fd=0, flags=0, size=0, timeout=0)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:496
#16 0x00000000004824ef in b_read (argc=2, argv=0x7ffff7fae9a8,
context=0x795810 <sh+1296>)
    at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/bltins/read.c:177
#17 0x0000000000466b98 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=512)
at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1410
#18 0x000000000046a326 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=4) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2485
#19 0x0000000000468847 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=4) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:1978
#20 0x00000000004693d2 in sh_exec (t=0x792dc0 <_Sfstdin>, flags=4) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/xec.c:2195
#21 0x000000000040738f in exfile (shp=0x792dc0 <_Sfstdin>, iop=0x1,
fno=65536) at /home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:581
#22 0x0000000000406847 in sh_main (ac=2, av=0x7fffffffe0a8,
userinit=0x0) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/main.c:353
#23 0x0000000000405c55 in main (argc=2, argv=0x7fffffffe0a8) at
/home/pcpa/rhel/ksh/ksh-20120801/src/cmd/ksh93/sh/pmain.c:45
(gdb) q
A debugging session is active.

    Inferior 1 [process 11868] will be killed.

Quit anyway? (y or n) y
---%<---

The code "memset(shp->ifstable,0,(1<<CHAR_BIT));" in
src/cmd/ksh93/sh/init.c:get_ifs()
is causing it to not stop when reading a null byte.

The attached patch corrects the problem, but I think an alternative
that could be
better would be to save/restore shp->ifstable in the signal handler,
or a function
called by it.

  On a normal run, shp->ifstable would be:
{2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}
but if the alarm signal handler is called, it would become, without the patch:
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}

The patch force 0 as 2 (S_EOF), and remaining differences are
3 at offset 10, 39 at offset 92.

Do you think it would be better to save/restore shp->ifstable in
the alarm handler? src/cmd/ksh93/sh/timers.c:sigalrm()
or some other alternative? for example, adding hardcoded
shp->ifstable['\n'] = S_NL;
shp->ifstable['\\'] = S_ESC;
(what looks like extra sensible hardcoded defaults),
or not calling memset.

Thanks,
Paulo
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.orig ksh-20120801/src/cmd/ksh93/sh/init.c
--- ksh-20120801/src/cmd/ksh93/sh/init.c.orig	2014-12-10 20:11:17.693446084 -0200
+++ ksh-20120801/src/cmd/ksh93/sh/init.c	2014-12-10 20:11:24.753442619 -0200
@@ -576,6 +576,7 @@ static char* get_ifs(register Namval_t*
 			shp->ifstable[' '] = shp->ifstable['\t'] = S_SPACE;
 			shp->ifstable['\n'] = S_NL;
 		}
+		shp->ifstable[0] = S_EOF;
 	}
 	return(value);
 }
_______________________________________________
ast-users mailing list
ast-users@lists.research.att.com
http://lists.research.att.com/mailman/listinfo/ast-users

Reply via email to