From c2b78ec073f36bff1c8545f8a28439b222adfc2c Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Mon, 24 Nov 2014 16:03:10 +0100 Subject: [PATCH] [mc] Test if the stack-cleaner has any effect In order to test this: * we compile the same test program with and without the stack cleaner (`-fstack-cleaner`, `-fno-stack-cleaner`); * in this program, we move random bytes in the stack; * we expect the stack-cleaner to zero them out. This test in only used if the configure stack-cleaner is detected to support the `-fstack-cleaner` CLI option (it is the stack-cleaner compiler wrapper). --- CMakeLists.txt | 3 + buildtools/Cmake/AddTests.cmake | 8 +++ examples/msg/mc/CMakeLists.txt | 15 ++++- examples/msg/mc/bugged1_liveness.c | 31 +++++++++- .../msg/mc/bugged1_liveness_stack_cleaner | 59 +++++++++++++++++++ 5 files changed, 113 insertions(+), 3 deletions(-) create mode 100755 examples/msg/mc/bugged1_liveness_stack_cleaner diff --git a/CMakeLists.txt b/CMakeLists.txt index a97eb9670b..80bc299ab5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,9 @@ endif() enable_language(CXX) +INCLUDE(CheckCCompilerFlag) +CHECK_C_COMPILER_FLAG(-fstack-cleaner HAVE_C_STACK_CLEANER) + if (APPLE) #MAC set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) diff --git a/buildtools/Cmake/AddTests.cmake b/buildtools/Cmake/AddTests.cmake index 297b6319a3..1343003f49 100644 --- a/buildtools/Cmake/AddTests.cmake +++ b/buildtools/Cmake/AddTests.cmake @@ -117,6 +117,14 @@ ENDIF() ADD_TESH(mc-bugged1-liveness-ucontext-sparse --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1_liveness_sparse.tesh) ADD_TESH(mc-bugged1-liveness-visited-ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1_liveness_visited.tesh) ADD_TESH(mc-bugged1-liveness-visited-ucontext-sparse --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/mc --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/mc bugged1_liveness_visited_sparse.tesh) + if(HAVE_C_STACK_CLEANER) + # This test checks if the stack cleaner is makign a difference: + add_test(mc-bugged1-liveness-stack-cleaner + ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/bugged1_liveness_stack_cleaner + ${CMAKE_HOME_DIRECTORY}/examples/msg/mc/ + ${CMAKE_BINARY_DIR}/examples/msg/mc/ + ) + endif() ENDIF() ENDIF() diff --git a/examples/msg/mc/CMakeLists.txt b/examples/msg/mc/CMakeLists.txt index 483500c018..5516685af1 100644 --- a/examples/msg/mc/CMakeLists.txt +++ b/examples/msg/mc/CMakeLists.txt @@ -17,7 +17,20 @@ if(HAVE_MC) target_link_libraries(bugged3 simgrid ) target_link_libraries(electric_fence simgrid ) target_link_libraries(bugged1_liveness simgrid ) - target_link_libraries(bugged2_liveness simgrid ) + target_link_libraries(bugged2_liveness simgrid ) + + if(HAVE_C_STACK_CLEANER) + add_executable(bugged1_liveness_cleaner_on bugged1_liveness.c ) + add_executable(bugged1_liveness_cleaner_off bugged1_liveness.c ) + + target_link_libraries(bugged1_liveness_cleaner_on simgrid ) + target_link_libraries(bugged1_liveness_cleaner_off simgrid ) + + set_target_properties(bugged1_liveness_cleaner_on + PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fstack-cleaner") + set_target_properties(bugged1_liveness_cleaner_off + PROPERTIES COMPILE_FLAGS "-DGARBAGE_STACK -fno-stack-cleaner") + endif() endif() diff --git a/examples/msg/mc/bugged1_liveness.c b/examples/msg/mc/bugged1_liveness.c index 09d374613f..5143623f2e 100644 --- a/examples/msg/mc/bugged1_liveness.c +++ b/examples/msg/mc/bugged1_liveness.c @@ -10,6 +10,12 @@ /* LTL property checked : G(r->F(cs)); (r=request of CS, cs=CS ok) */ /******************************************************************************/ +#ifdef GARBAGE_STACK +#include +#include +#include +#endif + #include "msg/msg.h" #include "mc/mc.h" #include "xbt/automaton.h" @@ -28,6 +34,16 @@ int predCS(){ return cs; } +#ifdef GARBAGE_STACK +/** Do not use a clean stack */ +static void garbage_stack(void) { + const size_t size = 256; + int fd = open("/dev/urandom", O_RDONLY); + char foo[size]; + read(fd, foo, size); + close(fd); +} +#endif int coordinator(int argc, char *argv[]) { @@ -84,7 +100,7 @@ int client(int argc, char *argv[]) char *my_mailbox = xbt_strdup(argv[1]); msg_task_t grant = NULL, release = NULL; - + while(1){ XBT_INFO("Ask the request"); MSG_task_send(MSG_task_create("request", 0, 1000, my_mailbox), "coordinator"); @@ -130,6 +146,17 @@ int client(int argc, char *argv[]) return 0; } +static int raw_client(int argc, char *argv[]) +{ +#ifdef GARBAGE_STACK + // At this point the stack of the callee (client) is probably filled with + // zeros and unitialized variables will contain 0. This call will place + // random byes in the stack of the callee: + garbage_stack(); +#endif + return client(argc, argv); +} + int main(int argc, char *argv[]) { @@ -146,7 +173,7 @@ int main(int argc, char *argv[]) MSG_create_environment(platform_file); MSG_function_register("coordinator", coordinator); - MSG_function_register("client", client); + MSG_function_register("client", raw_client); MSG_launch_application(application_file); MSG_main(); diff --git a/examples/msg/mc/bugged1_liveness_stack_cleaner b/examples/msg/mc/bugged1_liveness_stack_cleaner new file mode 100755 index 0000000000..2f372b629b --- /dev/null +++ b/examples/msg/mc/bugged1_liveness_stack_cleaner @@ -0,0 +1,59 @@ +#!/bin/sh +# Run the same test compiled with -fstack-cleaner / f-no-stack-cleaner +# and compare the output. + +srcdir="$1" +bindir="$2" + +cd "$srcdir" + +die() { + echo "$@" >&2 + exit 1 +} + +assert() { + if ! eval "$1"; then + die "Assertion failed: $@" + fi +} + +# If we don't have timeout, fake it: +if ! which timeout > /dev/null; then + timeout() { + shift + "$@" + } +fi + +run() { + state=$1 + shift + timeout 30s ${bindir:=.}/bugged1_liveness_cleaner_$state \ + ${srcdir:=.}/../../platforms/platform.xml \ + ${srcdir:=.}/deploy_bugged1_liveness.xml \ + --cfg=model-check:1 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" \ + --cfg=contexts/factory:ucontext \ + --cfg=contexts/stack_size:256 + assert 'test $? = 134' +} + +get_states() { + echo "$1" | grep "Expanded pairs = " | sed "s/^.*Expanded pairs = //" | head -n1 +} + +RES_ON="$(run on 2>&1 1>/dev/null)" +RES_OFF="$(run off 2>&1 1>/dev/null)" + +STATES_ON=$(get_states "$RES_ON") +STATES_OFF=$(get_states "$RES_OFF") + +# Both runs finished: +assert 'test -n "$STATES_ON"' +assert 'test -n "$STATES_OFF"' + +# We expect 21 visited pairs with the stack cleaner: +assert 'test "$STATES_ON" = 21' + +# We expect more states without the stack cleaner: +assert 'test "$STATES_ON" -lt "$STATES_OFF"' -- 2.20.1