Discussion:
[ast-developers] $ clang -fsanitize=address # fixes for ast-ksh.2013-07-27 ...
Roland Mainz
2013-08-07 13:35:26 UTC
Permalink
Hi!

----

Attached (as "astksh20130727_clang_sanitize_address001.diff.txt") is a
small set of patches which fixes _some_ problems by "clangs" address
sanitizer feature (see
http://clang.llvm.org/docs/AddressSanitizer.html).

Themain issue in this patch is that ksh93 uses |memcmp()| to compare
part of strings... unfortunately this means that sometimes |memcpy()|
wanders intomemory areas which no longer belong to a string if the
size of the strings differs more than a byte or more.
The"fix" is to exchange |memcmp()| by |strncmp()| to ensure the comparison.

The original issue the patch fixes is this one:
-- snip --
# build
$ (export CC='/usr/bin/clang -std=gnu1x -fsanitize=address -g
-fno-omit-frame-pointer -fno-optimize-sibling-calls -Wno-parentheses
-Wno-logical-op-parentheses' LD="$CC" CCFLAGS="-g"; ksh ./bin/package
make PACKAGE_OPTIONS='map-libc' CC="$CC" CCFLAGS="$CCFLAGS" 2>&1 | tee
-a buildlog.log)

# run under gdb control. "break AsanDie" causes gdb to stop
# if the "address satiniser" kills the process
$ gdb --args ./arch/linux.i386-64/bin/ksh -c 'trap "print -v .sh.sig"
RTMIN ; kill -RTMIN $$ ; true'GNU gdb (GDB) SUSE (7.5.1-2.1.1)
[snip]
(gdb) break AsanDie
Breakpoint 1 at 0x429ed0: file
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_rtl.cc,
line 32.
(gdb) run
Starting program:
/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh
-c trap\ \"print\ -v\ .sh.sig\"\ RTMIN\ \;\ kill\ -RTMIN\ \$\$\ \;\
true

Program received signal SIG34, Real-time event 34.
0x00007ffff6d246b7 in kill () at ../sysdeps/unix/syscall-template.S:81
81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) cont
Continuing.

Program received signal SIGCONT, Continued.
0x00007ffff6d246b7 in kill () at ../sysdeps/unix/syscall-template.S:81
81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) cont
Continuing.
=================================================================
==54827==ERROR: AddressSanitizer: global-buffer-overflow on address
0x0000011958a4 at pc 0x4211a4 bp 0x7ffffffeb250 sp 0x7ffffffeb218
READ of size 5 at 0x0000011958a4 thread T0
#0 0x4211a3
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x4211a3)
#1 0x4c9147
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x4c9147)
#2 0x4c6051
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x4c6051)
#3 0x482ace
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x482ace)
#4 0x7affd5
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x7affd5)
#5 0x79be26
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x79be26)
#6 0x4399f5
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x4399f5)
#7 0x43fbfa
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x43fbfa)
#8 0x432f3a
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x432f3a)
#9 0x7ffff6d10a14 (/lib64/libc-2.17.so+0x21a14)
#10 0x432c4c
(/home/test001/work/ast_ksh_20130727/build_clang/arch/linux.i386-64/bin/ksh+0x432c4c)
0x0000011958a4 is located 60 bytes to the left of global variable
'.str86' from '/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/data/variables.c'
(0x11958e0) of size 6
'.str86' is ascii string 'signo'
0x0000011958a4 is located 0 bytes to the right of global variable
'.str85' from '/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/data/variables.c'
(0x11958a0) of size 4
'.str85' is ascii string 'pid'
Shadow bytes around the buggy address:
0x00008022aac0: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
0x00008022aad0: f9 f9 f9 f9 07 f9 f9 f9 f9 f9 f9 f9 06 f9 f9 f9
0x00008022aae0: f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9 05 f9 f9 f9
0x00008022aaf0: f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9 05 f9 f9 f9
0x00008022ab00: f9 f9 f9 f9 06 f9 f9 f9 f9 f9 f9 f9 05 f9 f9 f9
=>0x00008022ab10: f9 f9 f9 f9[04]f9 f9 f9 f9 f9 f9 f9 06 f9 f9 f9
0x00008022ab20: f9 f9 f9 f9 07 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
0x00008022ab30: f9 f9 f9 f9 06 f9 f9 f9 f9 f9 f9 f9 00 02 f9 f9
0x00008022ab40: f9 f9 f9 f9 00 02 f9 f9 f9 f9 f9 f9 00 00 00 00
0x00008022ab50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00008022ab60: 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 00 06 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
ASan internal: fe
==54827==ABORTING

Breakpoint 1, AsanDie () at
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_rtl.cc:32
32 /home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_rtl.cc:
No such file or directory.
(gdb) where
#0 AsanDie () at
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_rtl.cc:32
#1 0x000000000042b74f in Die () at
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/sanitizer_common/sanitizer_common.cc:47
#2 0x0000000000428dcd in ~ScopedInErrorReport () at
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_report.cc:493
#3 0x0000000000428d76 in ~ScopedInErrorReport () at
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_report.cc:480
#4 0x0000000000428cb0 in __asan_report_error () at
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_report.cc:734
#5 0x00000000004211bc in __interceptor_memcmp () at
/home/abuild/rpmbuild/BUILD/llvm-3.3/projects/compiler-rt/lib/asan/asan_interceptors.cc:283
#6 0x00000000004c9148 in create_svar (np=0x7ffff7f1ad50,
name=0x115d120 "signo", flag=0, fp=0x7ffff7f20640)
at /home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/init.c:1956
#7 0x00000000004c6052 in sh_setsiginfo (sip=0x7ffff7f1cf30) at
/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/init.c:2071
#8 0x0000000000482acf in sh_chktrap (shp=0x1ec7220 <sh>) at
/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/fault.c:491
#9 0x00000000007affd6 in sh_exec (shp=0x1ec7220 <sh>,
t=0x7ffff7f17920, flags=4) at
/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/xec.c:2960
#10 0x000000000079be27 in sh_exec (shp=0x1ec7220 <sh>,
t=0x7ffff7f17a30, flags=5) at
/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/xec.c:2223
#11 0x00000000004399f6 in exfile (shp=0x1ec7220 <sh>,
iop=0x7ffff7edb4d0, fno=-1) at
/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/main.c:603
#12 0x000000000043fbfb in sh_main (ac=3, av=0x7fffffffe1b8,
userinit=0x0) at
/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/main.c:375
#13 0x0000000000432f3b in main (argc=3, argv=0x7fffffffe1b8) at
/home/test001/work/ast_ksh_20130727/build_clang/src/cmd/ksh93/sh/pmain.c:45
-- snip --

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) roland.mainz at nrubsig.org
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)
-------------- next part --------------
diff -r -u original/src/cmd/ksh93/sh/init.c build_clang/src/cmd/ksh93/sh/init.c
--- src/cmd/ksh93/sh/init.c 2013-07-22 16:43:07.000000000 +0200
+++ src/cmd/ksh93/sh/init.c 2013-08-07 04:50:11.812662231 +0200
@@ -1953,7 +1953,7 @@
for(i=0; i < sp->numnodes; i++)
{
nq = nv_namptr(sp->nodes,i);
- if((n==0||memcmp(name,nq->nvname,n)==0) && nq->nvname[n]==0)
+ if((n==0||strncmp(name,nq->nvname,n)==0) && nq->nvname[n]==0)
goto found;
}
nq = 0;
diff -r -u original/src/cmd/ksh93/sh/nvtree.c build_clang/src/cmd/ksh93/sh/nvtree.c
--- src/cmd/ksh93/sh/nvtree.c 2013-07-15 23:37:36.000000000 +0200
+++ src/cmd/ksh93/sh/nvtree.c 2013-08-07 05:23:19.904382892 +0200
@@ -195,7 +195,7 @@
{
char *cp = nv_name(dp->hp);
c = strlen(cp);
- if(memcmp(name,cp,c) || name[c]!='[')
+ if(strncmp(name,cp,c) || name[c]!='[')
dp->hp = (Namval_t*)dtnext(dp->root,dp->hp);
else
{
@@ -279,7 +279,7 @@
{
if(dp->nextnode)
return((*dp->nextnode)(dp->hp,dp->root,dp->fun));
- if(dp->len && memcmp(dp->data, dp->hp->nvname, dp->len))
+ if(dp->len && strncmp(dp->data, dp->hp->nvname, dp->len))
return(0);
return((Namval_t*)dtnext(dp->root,dp->hp));
}
@@ -344,7 +344,7 @@
dp->hp = (*dp->nextnode)(np,(Dt_t*)0,dp->fun);
}
shp->last_table = last_table;
- if(!dp->len || memcmp(cp,dp->data,dp->len)==0)
+ if(!dp->len || strncmp(cp,dp->data,dp->len)==0)
{
if((nfp=nextdisc(np)) && (nfp->disc->getval||nfp->disc->getnum) && nv_isvtree(np) && strcmp(cp,dp->data))
nfp = 0;
@@ -1037,7 +1037,7 @@
continue;
break;
}
- else if(outfile && !wp->nofollow && argv[1] && memcmp(arg,argv[1],l=strlen(arg))==0 && argv[1][l]=='[')
+ else if(outfile && !wp->nofollow && argv[1] && strncmp(arg,argv[1],l=strlen(arg))==0 && argv[1][l]=='[')
{
int k=1;
Namarr_t *aq=0;
@@ -1094,7 +1094,7 @@
if(argv[1])
{
ssize_t r = (cp-argv[0]) + strlen(cp);
- if(argv[1][r]=='.' && memcmp(argv[0],argv[1],r)==0)
+ if(argv[1][r]=='.' && strncmp(argv[0],argv[1],r)==0)
wp->flags &= ~NV_COMVAR;
}
outval(cp,arg,wp);
@@ -1184,7 +1184,7 @@
mp = np;
name = stkfreeze(shp->stk,1);
shp->last_root = 0;
- if(shp->last_table && !nv_type(shp->last_table) && (cp=nv_name(shp->last_table)) && (len=strlen(cp)) && memcmp(name,cp,len)==0 && name[len]=='.')
+ if(shp->last_table && !nv_type(shp->last_table) && (cp=nv_name(shp->last_table)) && (len=strlen(cp)) && strncmp(name,cp,len)==0 && name[len]=='.')
name += len+1;
len = strlen(name);
dir = nv_diropen(mp,name,(void*)shp);
Loading...