Bug 1371630
| Summary: | Getting KSH Segfault even after applying the errata of #1247383 | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Filip Krska <fkrska> | ||||
| Component: | ksh | Assignee: | Siteshwar Vashisht <svashisht> | ||||
| Status: | CLOSED ERRATA | QA Contact: | Jan Kepler <jkejda> | ||||
| Severity: | medium | Docs Contact: | |||||
| Priority: | medium | ||||||
| Version: | 7.2 | CC: | fkrska, isenfeld, jkejda, qe-baseos-apps, srandhaw, svashisht | ||||
| Target Milestone: | rc | Keywords: | Reproducer | ||||
| Target Release: | --- | ||||||
| Hardware: | Unspecified | ||||||
| OS: | Unspecified | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | ksh-20120801-34.el7 | Doc Type: | If docs needed, set a value | ||||
| Doc Text: | Story Points: | --- | |||||
| Clone Of: | 1349280 | ||||||
| : | 1466399 (view as bug list) | Environment: | |||||
| Last Closed: | 2017-08-01 16:26:55 UTC | Type: | Bug | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Bug Depends On: | |||||||
| Bug Blocks: | 1298243, 1393867 | ||||||
| Attachments: |
|
||||||
|
Description
Filip Krska
2016-08-30 16:31:33 UTC
When tracing the while loop at typeset.c:1455
else while(namec--)
{
if((np=nv_search(*argv++,root,0)) && np!=onp && (!nv_isnull(np) || np->nvfun || nv_isattr(np,~NV_NOFREE)))
{
onp = np;
if(name)
{
char *newname = nv_name(np);
if(memcmp(name,newname,len)==0 && newname[len]== '.')
continue;
name = 0;
}
if(flag&NV_ARRAY)
{
if(nv_aindex(np)>=0)
{
if(!(flag&NV_IARRAY))
continue;
}
else if((flag&NV_IARRAY))
continue;
}
tp->scanmask = flag&~NV_NOSCOPE;
tp->scanroot = root;
print_namval(file,np,option,tp);
if(!is_abuiltin(np) && nv_isvtree(np))
{
name = nv_name(np);
len = strlen(name);
}
}
}
it seems that function print_namval(file,np,option,tp); damages argv[]:
(gdb)
1480 print_namval(file,np,option,tp);
3: argv[1] = 0x7ffff7f905d8 "C"
1: *argv = 0x7ffff7f903b8 "B"
(gdb) n
1481 if(!is_abuiltin(np) && nv_isvtree(np))
3: argv[1] = 0x27275c2724 <Address 0x27275c2724 out of bounds>
1: *argv = 0x7ffff7f903b8 "B"
next cycle of while then leads to segfault because nv_search gets the damaged *argv++ value.
Actually the $ was redundant in the reproducer, following is working as well:
# cat ksh_typeset.sh
A[0]="'"
B[0]=aa
C[0]=aa
typeset -a
This is what I got when watching *argv, rgv[1]:
(gdb) b typeset.c:1455
Breakpoint 1 at 0x4905aa: file /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c, line 1455.
(gdb) run ksh_typeset.sh
Starting program: /usr/bin/ksh ksh_typeset.sh
Breakpoint 1, print_scan (file=0x79cea0 <_Sfstdout>, flag=4195328, root=0x7ffff7fc8fc0, option=0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:1455
1455 else while(namec--)
(gdb) watch *argv
Watchpoint 2: *argv
(gdb) watch argv[1]
Watchpoint 3: argv[1]
(gdb) c
Continuing.
Watchpoint 2: *argv
Old value = 0x7ffff7f90198 "A"
New value = 0x7ffff7f903b8 "B"
Watchpoint 3: argv[1]
Old value = 0x7ffff7f903b8 "B"
New value = 0x7ffff7f905d8 "C"
0x00000000004905b6 in print_scan (file=0x79cea0 <_Sfstdout>, flag=4195328, root=0x7ffff7fc8fc0, option=0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:1457
1457 if((np=nv_search(*argv++,root,0)) && np!=onp && (!nv_isnull(np) || np->nvfun || nv_isattr(np,~NV_NOFREE)))
(gdb)
Continuing.
Watchpoint 3: argv[1]
Old value = 0x7ffff7f905d8 "C"
New value = 0x7ffff7f90524 ""
0x00007ffff739b1da in __memmove_sse2 (dest=<optimized out>, src=<optimized out>, len=<optimized out>) at ../string/memmove.c:85
85 BYTE_COPY_FWD (dstp, srcp, len);
(gdb) bt
#0 0x00007ffff739b1da in __memmove_sse2 (dest=<optimized out>, src=<optimized out>, len=<optimized out>) at ../string/memmove.c:85
#1 0x00000000004fd721 in sfwrite (f=0x79b0e0 <_Stak_data>, buf=0x52ec80, n=2)
at /usr/src/debug/ksh-20120801/src/lib/libast/sfio/sfwrite.c:138
#2 0x000000000045d21d in sh_fmtq (string=0x7ffff7f90350 "'") at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/string.c:383
#3 0x000000000044f72d in nv_outnode (np=0x7ffff7f90160, out=0x79cea0 <_Sfstdout>, indent=-1, special=0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/nvtree.c:661
#4 0x000000000048d5bd in print_value (iop=0x79cea0 <_Sfstdout>, np=0x7ffff7f90160, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:514
#5 0x0000000000490182 in print_namval (file=0x79cea0 <_Sfstdout>, np=0x7ffff7f90160, flag=0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:1367
#6 0x00000000004906f3 in print_scan (file=0x79cea0 <_Sfstdout>, flag=4195328, root=0x7ffff7fc8fc0, option=0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:1480
#7 0x000000000048e8be in setall (argv=0x7ffff7fac698, flag=4195840, troot=0x7ffff7fc8fc0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:860
#8 0x000000000048d226 in b_typeset (argc=2, argv=0x7ffff7fac698, context=0x79f830 <sh+1296>)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:459
#9 0x000000000046a290 in sh_exec (t=0x7ffff7fac7d1, flags=4) at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/xec.c:1410
#10 0x00000000004074ec in exfile (shp=0x7ffff7fac7d1, iop=0x52ec80, fno=36) at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/main.c:581
#11 0x000000000040690c in sh_main (ac=2, av=0x7fffffffe338, userinit=0x0) at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/main.c:353
#12 0x0000000000405ca2 in main (argc=2, argv=0x7fffffffe338) at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/pmain.c:45
(gdb) c
Continuing.
Watchpoint 3: argv[1]
Old value = 0x7ffff7f90524 ""
New value = 0x7ffff7f92724 ""
0x00007ffff739b1da in __memmove_sse2 (dest=<optimized out>, src=<optimized out>, len=<optimized out>) at ../string/memmove.c:85
85 BYTE_COPY_FWD (dstp, srcp, len);
(gdb) c
Continuing.
Watchpoint 3: argv[1]
Old value = 0x7ffff7f92724 ""
New value = 0x7ffff75c2724 <Address 0x7ffff75c2724 out of bounds>
sh_fmtq (string=0x7ffff7f90350 "'") at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/string.c:445
445 stakputc(c);
(gdb) bt
#0 sh_fmtq (string=0x7ffff7f90350 "'") at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/string.c:445
#1 0x000000000044f72d in nv_outnode (np=0x7ffff7f90160, out=0x79cea0 <_Sfstdout>, indent=-1, special=0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/nvtree.c:661
#2 0x000000000048d5bd in print_value (iop=0x79cea0 <_Sfstdout>, np=0x7ffff7f90160, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:514
#3 0x0000000000490182 in print_namval (file=0x79cea0 <_Sfstdout>, np=0x7ffff7f90160, flag=0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:1367
#4 0x00000000004906f3 in print_scan (file=0x79cea0 <_Sfstdout>, flag=4195328, root=0x7ffff7fc8fc0, option=0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:1480
#5 0x000000000048e8be in setall (argv=0x7ffff7fac698, flag=4195840, troot=0x7ffff7fc8fc0, tp=0x7fffffffd9a0)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:860
#6 0x000000000048d226 in b_typeset (argc=2, argv=0x7ffff7fac698, context=0x79f830 <sh+1296>)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/bltins/typeset.c:459
#7 0x000000000046a290 in sh_exec (t=0x799ec4 <_ast_info+36>, flags=4) at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/xec.c:1410
#8 0x00000000004074ec in exfile (shp=0x799ec4 <_ast_info+36>, iop=0x7ffff7f90350, fno=-134559789)
at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/main.c:581
#9 0x000000000040690c in sh_main (ac=2, av=0x7fffffffe338, userinit=0x0) at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/main.c:353
#10 0x0000000000405ca2 in main (argc=2, argv=0x7fffffffe338) at /usr/src/debug/ksh-20120801/src/cmd/ksh93/sh/pmain.c:45
I don't know yet which function is to blame but imho argv[] shall not be altered inside print_namval()...
Thanks Filip for the reproducer and debugging information.
I will add some more notes.
It seems ksh handles "'" specially and it goes through below codepath in sh_fmtq() function in src/cmd/ksh93/sh/string.c :
char *sh_fmtq(const char *string)
...
...
#if SHOPT_MULTIBYTE
if(c=='\'' || c>=128 || c<0 || !iswprint(c))
#else
if(c=='\'' || !isprint(c))
#endif /* SHOPT_MULTIBYTE */
state = 2;
...
...
}
if(state<2)
{
...
...
}
else
{
int isbyte=0;
stakwrite("$'",2);
...
...
if(state)
{
stakputc('\\');
stakputc(c);
}
...
...
stakputc('\'');
}
stakputc(0);
....
So at the end "'" is being expanded to "$'\\''".
This codepath is probably corrupting the stack data structure that ksh maintains.
Created attachment 1231648 [details]
ksh-20120801-typeset.patch
Fix a bug in memory allocation while listing indexed arrays with typeset
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2017:1936 |