From 0c455ebf9c1aa80db9e8c435fb75875673815b2c Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Wed, 9 Dec 2015 17:15:48 -0800 Subject: [PATCH 1/8] [test suite] ensure fko-wrapper passes 16-byte string to fko_set_rand_value() --- test/fko-wrapper/fko_wrapper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/fko-wrapper/fko_wrapper.c b/test/fko-wrapper/fko_wrapper.c index 127380f0..f524009a 100644 --- a/test/fko-wrapper/fko_wrapper.c +++ b/test/fko-wrapper/fko_wrapper.c @@ -33,8 +33,9 @@ */ #define ENC_KEY "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" /* 32 bytes (RIJNDAEL_MAX_KEYSIZE) */ #define HMAC_KEY "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" /* 128 bytes (SHA512_BLOCK_LEN) */ -#define STR_64BYTES "1234567890123456789012345678901234567890123456789012345678901234" #define STR_8BYTES "12345678" +#define STR_16BYTES "1234567890123456" +#define STR_64BYTES "1234567890123456789012345678901234567890123456789012345678901234" #define SPA_MSG1 "1.1.1.1,tcp/22" #define SPA_MSG2 "123.123.123.123,tcp/22" #define SPA_NAT_MSG "1.2.3.4,1234" @@ -252,7 +253,8 @@ static void ctx_set_null_vals(fko_ctx_t *ctx) static void ctx_add_dupe_data(fko_ctx_t *ctx) { fko_set_rand_value(*ctx, STR_8BYTES); - fko_set_rand_value(*ctx, STR_8BYTES); + fko_set_rand_value(*ctx, STR_16BYTES); + fko_set_rand_value(*ctx, STR_16BYTES); fko_set_username(*ctx, STR_64BYTES); fko_set_username(*ctx, STR_64BYTES); fko_set_timestamp(*ctx, 12345); From 60919a9141cadd958d21321462f29ccc073440fe Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Wed, 9 Dec 2015 17:16:38 -0800 Subject: [PATCH 2/8] [test suite] make ASan error detection more generic to catch things like LeakSanitizer errors --- test/test-fwknop.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-fwknop.pl b/test/test-fwknop.pl index 22293d1e..7d1b9a99 100755 --- a/test/test-fwknop.pl +++ b/test/test-fwknop.pl @@ -1454,8 +1454,8 @@ () if ($rv) { &run_cmd('./a.out', "../$cmd_out_tmp", "../$curr_test_file"); - unless (&file_find_regex([qr/ERROR\:\sAddressSanitizer/, - qr/SUMMARY\:\sAddressSanitizer/], + unless (&file_find_regex([qr/ERROR\:\s\w+Sanitizer/, + qr/SUMMARY\:\s\w+Sanitizer/], $MATCH_ALL, $NO_APPEND_RESULTS, "../$curr_test_file")) { $rv = 0; } From d50992582283bc6b47932630d3a98383b707953a Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Wed, 9 Dec 2015 18:19:42 -0800 Subject: [PATCH 3/8] [extras] add build support for Google's UndefinedBehaviorSanitizer --- Makefile.am | 1 + configure.ac | 15 ++++++++++++++- extras/sanitizer/asan-build.sh | 2 +- extras/sanitizer/ubsan-build.sh | 15 +++++++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) create mode 100755 extras/sanitizer/ubsan-build.sh diff --git a/Makefile.am b/Makefile.am index 967d015d..5e1a7ba1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -70,6 +70,7 @@ EXTRA_DIST = \ extras/ramdisk/ramdisk-create-osx.sh \ extras/console-qr/console-qr.sh \ extras/sanitizer/asan-build.sh \ + extras/sanitizer/ubsan-build.sh \ fwknop.spec \ iphone/main.m \ iphone/Fwknop.xcodeproj \ diff --git a/configure.ac b/configure.ac index 044d3c2c..9abf965f 100644 --- a/configure.ac +++ b/configure.ac @@ -179,7 +179,7 @@ dnl want_asan_support=no AC_ARG_ENABLE([asan-support], [AS_HELP_STRING([--enable-asan-support], - [Build fwknop binaries with address sanitizer support @<:@default is to disable@:>@])], + [Build fwknop binaries with AddressSanitizer support @<:@default is to disable@:>@])], [want_asan_support=$enableval], []) @@ -187,6 +187,19 @@ if test "x$want_asan_support" = "xyes"; then FKO_CHECK_COMPILER_ARG([-fsanitize=address -fno-omit-frame-pointer]) fi +dnl Decide whether or not to enable MemorySanitizer support +dnl +want_ubsan_support=no +AC_ARG_ENABLE([ubsan-support], + [AS_HELP_STRING([--enable-ubsan-support], + [Build fwknop binaries with UndefinedBehaviorSanitizer support @<:@default is to disable@:>@])], + [want_ubsan_support=$enableval], + []) + +if test "x$want_ubsan_support" = "xyes"; then + FKO_CHECK_COMPILER_ARG([-fsanitize=undefined]) +fi + dnl Decide whether or not force 32-bit mode dnl want_32bit_mode=no diff --git a/extras/sanitizer/asan-build.sh b/extras/sanitizer/asan-build.sh index ed42691b..41f42b6e 100755 --- a/extras/sanitizer/asan-build.sh +++ b/extras/sanitizer/asan-build.sh @@ -1,7 +1,7 @@ #!/bin/sh -x # -# In some cases when enabling Google's Address Sanitizer, errors like the +# In some cases when enabling Google's AddressSanitizer, errors like the # following can be generated. This script provides a workaround. # # fwknop-spa_comm.o: In function `send_spa_packet_http': diff --git a/extras/sanitizer/ubsan-build.sh b/extras/sanitizer/ubsan-build.sh new file mode 100755 index 00000000..4cfbe94c --- /dev/null +++ b/extras/sanitizer/ubsan-build.sh @@ -0,0 +1,15 @@ +#!/bin/sh -x +# +# Enabling Google's UndefinedBehaviorSanitizer +# + +if [ -x ./configure ]; then + export ac_cv_func_malloc_0_nonnull=yes + export ac_cv_func_realloc_0_nonnull=yes + ./autogen.sh + ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/run --enable-ubsan-support $@ + make clean + make +else + echo "[*] Execute from the fwknop top level sources directory" +fi From 4cab37acf9440250a539b01a6b06657646e41d81 Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Thu, 10 Dec 2015 14:32:30 -0800 Subject: [PATCH 4/8] [test suite] client --time-offset code coverage --- test/tests/basic_operations.pl | 47 ++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/test/tests/basic_operations.pl b/test/tests/basic_operations.pl index 6c7d9f7b..81f5040d 100644 --- a/test/tests/basic_operations.pl +++ b/test/tests/basic_operations.pl @@ -1442,6 +1442,20 @@ 'positive_output_matches' => [qr/Message.*0.0.0.0/], 'rc_positive_output_matches' => [qr/ALLOW_IP.*0.0.0.0/], }, + + { + 'category' => 'basic operations', + 'subcategory' => 'client save rc file', + 'detail' => '--server-resolve-ipv4', + 'function' => \&client_rc_file, + 'cmdline' => "$lib_view_str $valgrind_str $fwknopCmd -A tcp/22 -a $fake_ip " . + "-D $loopback_ip --rc-file $save_rc_file --save-rc-stanza " . + "--force-stanza --test -n default -R --server-resolve-ipv4", + 'save_rc_stanza' => [{'name' => 'default', + 'vars' => {'KEY' => 'testtest', 'HMAC_KEY' => 'hmactest', + 'HMAC_DIGEST_TYPE' => 'SHA1', + 'SERVER_RESOLVE_IPV4' => 'Y'}}], + }, { 'category' => 'basic operations', 'subcategory' => 'client save rc file', @@ -1452,31 +1466,36 @@ 'vars' => {'KEY' => 'testtest', 'HMAC_KEY' => 'hmactest', 'HMAC_DIGEST_TYPE' => 'SHA1'}}], 'positive_output_matches' => [qr/Resolved/], - 'rc_positive_output_matches' => [qr/RESOLVE_IP_HTTP.*Y/, qr/HTTP_USER_AGENT.*FwknopTestSuite\/2.6/], + 'rc_positive_output_matches' => [qr/RESOLVE_IP_HTTP.*Y/, + qr/HTTP_USER_AGENT.*FwknopTestSuite\/2.6/], }, { 'category' => 'basic operations', 'subcategory' => 'client save rc file', 'detail' => '-R resolve http (1)', 'function' => \&client_rc_file, - 'cmdline' => "$client_save_rc_args_no_test -n default -R --resolve-url http://www.cipherdyne.org/cgi-bin/myip", + 'cmdline' => "$client_save_rc_args_no_test -n default -R " . + "--resolve-url http://www.cipherdyne.org/cgi-bin/myip", 'save_rc_stanza' => [{'name' => 'default', 'vars' => {'KEY' => 'testtest', 'HMAC_KEY' => 'hmactest', 'HMAC_DIGEST_TYPE' => 'SHA1'}}], 'positive_output_matches' => [qr/Resolved/], - 'rc_positive_output_matches' => [qr/RESOLVE_IP_HTTP.*Y/, qr/RESOLVE_URL.*cipherdyne.org.*myip/], + 'rc_positive_output_matches' => [qr/RESOLVE_IP_HTTP.*Y/, + qr/RESOLVE_URL.*cipherdyne.org.*myip/], }, { 'category' => 'basic operations', 'subcategory' => 'client save rc file', 'detail' => '-R resolve http (2)', 'function' => \&client_rc_file, - 'cmdline' => "$client_save_rc_args_no_test -n default -R --resolve-url www.cipherdyne.org/cgi-bin/myip", + 'cmdline' => "$client_save_rc_args_no_test -n default " . + "-R --resolve-url www.cipherdyne.org/cgi-bin/myip", 'save_rc_stanza' => [{'name' => 'default', 'vars' => {'KEY' => 'testtest', 'HMAC_KEY' => 'hmactest', 'HMAC_DIGEST_TYPE' => 'SHA1'}}], 'positive_output_matches' => [qr/Resolved/], - 'rc_positive_output_matches' => [qr/RESOLVE_IP_HTTP.*Y/, qr/RESOLVE_URL.*\swww.cipherdyne.org.*myip/], + 'rc_positive_output_matches' => [qr/RESOLVE_IP_HTTP.*Y/, + qr/RESOLVE_URL.*\swww.cipherdyne.org.*myip/], }, { 'category' => 'basic operations', @@ -1693,6 +1712,24 @@ 'positive_output_matches' => [qr/Parameter\serror/], 'rc_positive_output_matches' => [qr/TIME_OFFSET.*123456789999/], }, + { + 'category' => 'basic operations', + 'subcategory' => 'client save rc file', + 'detail' => 'time offset invalid (3)', + 'function' => \&generic_exec, + 'cmdline' => "$fwknopCmd --test -A tcp/22 -s -D 127.0.0.2 --time-offset-plus 99999999999999999", + 'exec_err' => $YES, + 'positive_output_matches' => [qr/Invalid time offset/], + }, + { + 'category' => 'basic operations', + 'subcategory' => 'client save rc file', + 'detail' => 'time offset invalid (4)', + 'function' => \&generic_exec, + 'cmdline' => "$fwknopCmd --test -A tcp/22 -s -D 127.0.0.2 --time-offset-minus 99999999999999999", + 'exec_err' => $YES, + 'positive_output_matches' => [qr/Invalid time offset/], + }, { 'category' => 'basic operations', From 75b059af760f883a181f4e15ab1751c4676b5277 Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Thu, 10 Dec 2015 14:33:51 -0800 Subject: [PATCH 5/8] [test suite] use killall to ensure fwknopd is stopped between tests --- test/test-fwknop.pl | 7 +++++++ test/tests/rijndael_hmac_cmd_exec.pl | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/test/test-fwknop.pl b/test/test-fwknop.pl index 7d1b9a99..f761a148 100755 --- a/test/test-fwknop.pl +++ b/test/test-fwknop.pl @@ -7920,6 +7920,8 @@ () } else { &write_test_file("[-] stop_fwknopd() fwknopd is not running.\n", $curr_test_file); + ### make certain there is no running fwknopd process + system "$killall_path fwknopd 2> /dev/null" if $killall_path; return; } @@ -7976,6 +7978,11 @@ () } } + ### make certain fwknopd is stopped. Test suite interactions with fwknop + ### are complex, and having a running fwknopd process that may be been + ### "lost" can interfere with test results + system "$killall_path fwknopd 2> /dev/null" if $killall_path; + return; } diff --git a/test/tests/rijndael_hmac_cmd_exec.pl b/test/tests/rijndael_hmac_cmd_exec.pl index 1febb9ed..66754f38 100644 --- a/test/tests/rijndael_hmac_cmd_exec.pl +++ b/test/tests/rijndael_hmac_cmd_exec.pl @@ -119,6 +119,10 @@ 'fwknopd_cmdline' => "$fwknopdCmd -c $cf{'def'} -a $sudo_access_conf " . "-d $default_digest_file -p $default_pid_file $intf_str", 'sudo_test' => $YES, + ### write_sudo_access_conf() swaps out 'TOUCH' with the path to + ### the touch binary, which might change from system to system. Also + ### 'USER' is swapped out with the owner of the test suite files + ### (not necessarily root). 'sudo_conf' => 'USER localhost = NOPASSWD: /usr/bin/cat, TOUCH', 'cmd_exec_file_owner' => 'root', 'fw_rule_created' => $REQUIRE_NO_NEW_RULE, From f0269751e6014b94498886d358c9b17672fec8ea Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Thu, 10 Dec 2015 14:34:35 -0800 Subject: [PATCH 6/8] [test suite] fix FORCE_SNAT tests --- test/tests/basic_operations.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tests/basic_operations.pl b/test/tests/basic_operations.pl index 81f5040d..72efe56a 100644 --- a/test/tests/basic_operations.pl +++ b/test/tests/basic_operations.pl @@ -3859,7 +3859,7 @@ 'FORCE_NAT a a' ], 'server_conf_file' => [ - '### comment line' + "ENABLE_${FW_PREFIX}_FORWARDING Y" ], 'positive_output_matches' => [qr/invalid FORCE_NAT arg/], }, @@ -3957,7 +3957,7 @@ 'server_conf_file' => [ "ENABLE_${FW_PREFIX}_FORWARDING N" ], - 'positive_output_matches' => [qr/invalid FORCE_SNAT IP/], + 'positive_output_matches' => [qr/FORCE_SNAT requires either/], }, { 'category' => 'basic operations', From 885b8c3a0964f154f10045fbb4dbdbb64f2e6744 Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Thu, 10 Dec 2015 14:35:46 -0800 Subject: [PATCH 7/8] [test suite] consolidate *Sanitizer crash detection in a single function --- test/test-fwknop.pl | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/test/test-fwknop.pl b/test/test-fwknop.pl index f761a148..8691a0a1 100755 --- a/test/test-fwknop.pl +++ b/test/test-fwknop.pl @@ -220,6 +220,7 @@ my $valgrind_suppressions_file = cwd() . '/valgrind_suppressions'; our $valgrind_str = ''; my $asan_mode = 0; +my $ubsan_mode = 0; my %cached_fw_policy = (); my $cpan_valgrind_mod = 'Test::Valgrind'; my %prev_valgrind_cov = (); @@ -1454,11 +1455,7 @@ () if ($rv) { &run_cmd('./a.out', "../$cmd_out_tmp", "../$curr_test_file"); - unless (&file_find_regex([qr/ERROR\:\s\w+Sanitizer/, - qr/SUMMARY\:\s\w+Sanitizer/], - $MATCH_ALL, $NO_APPEND_RESULTS, "../$curr_test_file")) { - $rv = 0; - } + $rv = 0 unless &is_sanitizer_crash("../$curr_test_file"); } chdir '..' or die $!; @@ -1641,6 +1638,7 @@ () my $make_arg = $test_hr->{'wrapper_compile'}; $make_arg = 'asan' if $asan_mode; + $make_arg = 'ubsan' if $asan_mode; if ($test_hr->{'wrapper_binary'} =~ m|/fko_wrapper$|) { if ($enable_fuzzing_interfaces_tests) { @@ -1793,29 +1791,40 @@ () return $rv; } -sub is_crash() { +sub is_sanitizer_crash() { my $file = shift; + my $rv = 0; - if (&file_find_regex([qr/segmentation\sfault/i, qr/core\sdumped/i], + + if (&file_find_regex([qr/ERROR\:\s\w+Sanitizer/, + qr/SUMMARY\:\s\w+Sanitizer/], $MATCH_ANY, $NO_APPEND_RESULTS, $file)) { - &write_test_file("[-] crash message found in: $file\n", + &write_test_file("[-] Sanitizer crash found in: $file\n", $curr_test_file); $rv = 1; } - if (&file_find_regex([qr/ERROR\:\sAddressSanitizer/, - qr/SUMMARY\:\sAddressSanitizer/], + return $rv; +} + +sub is_crash() { + my $file = shift; + my $rv = 0; + if (&file_find_regex([qr/segmentation\sfault/i, qr/core\sdumped/i], $MATCH_ANY, $NO_APPEND_RESULTS, $file)) { - &write_test_file("[-] AddressSanitizer crash found in: $file\n", + &write_test_file("[-] crash message found in: $file\n", $curr_test_file); $rv = 1; } + $rv = 1 if &is_sanitizer_crash($file); + ### ASan and valgrind don't appear to be compatible, and and ASan ### will throw an error when the two are mixed if (&file_find_regex([qr/Shadow memory range interleaves/], $MATCH_ANY, $NO_APPEND_RESULTS, $file)) { - &write_test_file("[-] AddressSanitizer not compatible with valgrind: $file\n", + &write_test_file("[-] Sanitizer infrastructure not " . + "compatible with valgrind: $file\n", $curr_test_file); $rv = 1; } @@ -7324,7 +7333,7 @@ () push @tests_to_exclude, qr/down interface/; } - ### see if we're compiled with ASAN support + ### see if we're compiled with AddressSanitizer support if (&file_find_regex([qr/enable\-asan\-support/], $MATCH_ALL, $NO_APPEND_RESULTS, $config_log)) { $asan_mode = 1; @@ -7334,6 +7343,16 @@ () push @tests_to_exclude, qr/ASAN/; } + ### see if we're compiled with UndefinedBehaviorSanitizer support + if (&file_find_regex([qr/enable\-ubsan\-support/], + $MATCH_ALL, $NO_APPEND_RESULTS, $config_log)) { + $asan_mode = 1; + } else { + &write_test_file("[-] Can't find --enable-ubsan-support in $config_log\n", + $curr_test_file); + push @tests_to_exclude, qr/UBSAN/; + } + if ($gcov_path) { if ($enable_profile_coverage_check and not $list_mode) { From d70e3f3fbb15e76e1af38991dfbdc711e680d36e Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Thu, 10 Dec 2015 14:36:14 -0800 Subject: [PATCH 8/8] [fko-wrapper] add 'usban' compilation directive --- test/fko-wrapper/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/fko-wrapper/Makefile b/test/fko-wrapper/Makefile index 5283737e..88f81ab8 100644 --- a/test/fko-wrapper/Makefile +++ b/test/fko-wrapper/Makefile @@ -7,6 +7,10 @@ asan : fko_wrapper.c fko_basic.c cc -Wall -fsanitize=address -fno-omit-frame-pointer -g -I../../lib fko_wrapper.c -o fko_wrapper -L../../lib/.libs -lfko cc -Wall -fsanitize=address -fno-omit-frame-pointer -g -I../../lib fko_basic.c -o fko_basic -L../../lib/.libs -lfko +ubsan : fko_wrapper.c fko_basic.c + cc -Wall -fsanitize=undefined -g -I../../lib fko_wrapper.c -o fko_wrapper -L../../lib/.libs -lfko + cc -Wall -fsanitize=undefined -fno-omit-frame-pointer -g -I../../lib fko_basic.c -o fko_basic -L../../lib/.libs -lfko + fuzzing: fko_wrapper.c cc -Wall -g -DFUZZING_INTERFACES -I../../lib fko_wrapper.c -o fko_wrapper -L../../lib/.libs -lfko