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 |