Skip to content

Instantly share code, notes, and snippets.

@basinilya
Last active August 20, 2016 14:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save basinilya/e8f9cd09d96c6e255d68acfc2595d46e to your computer and use it in GitHub Desktop.
Save basinilya/e8f9cd09d96c6e255d68acfc2595d46e to your computer and use it in GitHub Desktop.
Building ksh from RedHat on other Linux (with -fsanitize=address)
==================================================================
Building ksh from RedHat on other Linux (with -fsanitize=address)
==================================================================
# First login to a RHEL 6.8 host
# download ksh source package
cd ~/rpmbuild/SRPMS/
yumdownloader --source ksh
# unpack and apply redhat patches
rpm -ivh ksh-20120801-33.el6.src.rpm
rpmbuild -bp ../SPECS/ksh.spec
cd ../BUILD/ksh-20120801
==================================================================
fix platform detection on other x86_64 Linux
==================================================================
# !!!
#
# bin/package recreates itself during build
# from ./src/cmd/INIT/package.sh
#
# !!!
./src/cmd/INIT/package.sh
-pc) arch=i386
+pc) arch=${arch:-i386}
./bin/package
-pc) arch=i386
+pc) arch=${arch:-i386}
==================================================================
remove the need to set gcc flag -P globally
fixes debug info pointing to temporary preprocessed files instead of real source files
==================================================================
./src/cmd/INIT/iffe.sh
compile() # $cc ...
{
_compile_arg1=$1
shift
"$_compile_arg1" $IFFELMARKFLAG "$@" 2>$tmp.err
==================================================================
fix reading past end of string in sh_isdevfd(e_dot)
AddressSanitizer did not allow memcmp(".","/dev/fd/",8)
==================================================================
./src/cmd/ksh93/sh/io.c
int sh_isdevfd(register const char *fd)
{
- if(!fd || memcmp(fd,"/dev/fd/",8) || fd[8]==0)
+ if(!fd || strncmp(fd,"/dev/fd/",8) || fd[8]==0)
==================================================================
fix strdup result leak in sh_subshell() when trap used
==================================================================
# TODO: test suite detects many regressions after this fix
./src/cmd/ksh93/sh/subshell.c
if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
{
++nsig;
savsig = malloc(nsig * sizeof(char*));
/* contents of shp->st.trapcom may change */
for (isig = 0; isig < nsig; ++isig)
savsig[isig] = shp->st.trapcom[isig] == Empty ? Empty : (shp->st.trapcom[isig] ? strdup(shp->st.trapcom[isig]) : NULL);
/* this nonsense needed for $(trap) */
shp->st.otrapcom = (char**)savsig;
}
sp->cpid = shp->cpid;
sp->coutpipe = shp->coutpipe;
sp->cpipe = shp->cpipe[1];
shp->cpid = 0;
- sh_sigreset(0);
+ sh_sigreset(1);
==================================================================
Changes in compile flags in ksh.spec
==================================================================
Remove '-P' from XTRAFLAGS. Instead:
export IFFELMARKFLAG=-P
The ksh code expects glob(3) implementation incompatible with glibc (no gl_list
member in glibc).
libast.a provides it, but the name may conflict with same symbol in libasan.a.
One way to fix it is to define -D_opt_map_libc, but it activates too many
custom functions in libast.
It's better to rename only glob-related functions. Append to CCFLAGS:
-Dglob=_ast_glob -Dglobfree=_ast_globfree
By default libast on RHEL installs its own malloc implementation via glibc __malloc_hook.
If __malloc_hook not found, libast installs its malloc by redefining it as _ast_malloc in the header.
If found, the macro _malloc_hook is defined in a generated header.
Custom malloc makes ASan unusable. Native malloc needs to be forced.
By default native malloc is used only on certain systems. To force it here, build with:
-D_std_malloc
Alternatively, to use native malloc indirectly from the _ast_malloc layer build with:
-D_AST_std_malloc
_std_malloc works fine with -fsanitize, but it fails without this flag.
The reason is that two macros _std_malloc and _malloc_hook don't work together because of the bug in src/lib/libast/vmalloc/malloc.c
When you build with -fsanitize, the feature test "gnu malloc hooks work" fails
and the _malloc_hook macro is undefined (TODO: check build with ASAN_OPTIONS=allocator_may_return_null=true).
If the feature test problem is fixed before the two macros problem, it won't build with -fsanitize too.
To ensure feature test fail, build also with:
-D__malloc_hook=badvar
==================================================================
Changes in ~/.rpmrc tp build with ASan
==================================================================
optflags: x86_64 -pipe -gdwarf-3 -O0 -fsanitize=address -fsanitize-recover=all -fno-omit-frame-pointer -D_std_malloc -D__malloc_hook=badvar
==================================================================
build using rpmbuild:
==================================================================
rm -rf arch/*
ASAN_OPTIONS=halt_on_error=0:detect_leaks=0 rpmbuild --short-circuit -bc ../../SPECS/ksh.spec
==================================================================
test using rpmbuild:
==================================================================
#(-fsanitize-recover=all does not prevent certain aborts. %check phase will fail)
ASAN_OPTIONS=halt_on_error=0:detect_leaks=0 rpmbuild --short-circuit -bi ../../SPECS/ksh.spec
# Remove dates from test log
sed -i 's/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9][+][0-9][0-9]:[0-9][0-9]:[0-9][0-9]/xxxx-xx-xx+xx:xx:xx/g' src/cmd/ksh93/tests/testresults.log
# save and compare ./src/cmd/ksh93/tests/testresults.log
==================================================================
build on other Linux:
==================================================================
# copy unpacked and prepared build directory
#rsync -az ~/rpmbuild/BUILD/ksh-20120801/ user@other-host:'~/'
# login
#PATH=/usr/lib/ccache/bin:$PATH
#PATH=/usr/lib64/ccache:$PATH
XTRAFLAGS=""
# -P
for f in -Wno-unknown-pragmas -Wno-missing-braces -Wno-unused-result -Wno-return-type -Wno-int-to-pointer-cast -Wno-parentheses -Wno-unused -Wno-unused-but-set-variable -Wno-cpp
do
gcc $f -E - </dev/null >/dev/null 2>&1 && XTRAFLAGS="$XTRAFLAGS $f"
done
./bin/package
./bin/package make mamake ||:
./bin/package make mamake ||:
export IFFELMARKFLAG=-P
export CC=gcc
# for ASan
RPM_OPT_FLAGS="-pipe -gdwarf-3 -O0 -fsanitize=address -fsanitize-recover=all -fno-omit-frame-pointer -D_std_malloc -D__malloc_hook=badvar"
#RPM_OPT_FLAGS="-pipe -gdwarf-3 -O2"
export CCFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing $XTRAFLAGS -DSHOPT_AUDIT -Dglob=_ast_glob -Dglobfree=_ast_globfree"
rm -rf arch/*
ASAN_OPTIONS=halt_on_error=0:detect_leaks=0 ./bin/package make -S
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment