From a554cedba4b98df6cfedf254f2be7cfb919ea526 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 19 May 2021 01:02:43 +0200 Subject: if_wg: pass back result of selftests and enable in CI Hopefully bad tests will cause the module to not insert, so the CI picks this up. It looks like a failure to insert the module at the moment actually causes another crash, though: Kernel page fault with the following non-sleepable locks held: exclusive sleep mutex if_cloners lock (if_cloners lock) r = 0 (0xffffffff81d9a9b8) locked @ /usr/src/sys/net/if_clone.c:447 stack backtrace: #0 0xffffffff80c66181 at witness_debugger+0x71 #1 0xffffffff80c6729d at witness_warn+0x40d #2 0xffffffff8109499e at trap_pfault+0x7e #3 0xffffffff81093fab at trap+0x2ab #4 0xffffffff810687f8 at calltrap+0x8 #5 0xffffffff82925610 at wg_module_event_handler+0x120 #6 0xffffffff80bd53c3 at module_register_init+0xd3 #7 0xffffffff80bc5c61 at linker_load_module+0xc01 #8 0xffffffff80bc73b9 at kern_kldload+0xe9 #9 0xffffffff80bc74db at sys_kldload+0x5b #10 0xffffffff810952f7 at amd64_syscall+0x147 #11 0xffffffff8106911e at fast_syscall_common+0xf8 Fatal trap 12: page fault while in kernel mode cpuid = 9; apic id = 09 fault virtual address = 0x70 fault code = supervisor read data, page not present instruction pointer = 0x20:0xffffffff80d18e37 stack pointer = 0x28:0xfffffe0115fb35a0 frame pointer = 0x28:0xfffffe0115fb35c0 code segment = base 0x0, limit 0xfffff, type 0x1b = DPL 0, pres 1, long 1, def32 0, gran 1 processor eflags = interrupt enabled, resume, IOPL = 0 current process = 1587 (kldload) trap number = 12 panic: page fault cpuid = 9 time = 1621380034 KDB: stack backtrace: #0 0xffffffff80c44695 at kdb_backtrace+0x65 #1 0xffffffff80bf9d01 at vpanic+0x181 #2 0xffffffff80bf9ad3 at panic+0x43 #3 0xffffffff81094917 at trap_fatal+0x387 #4 0xffffffff810949b7 at trap_pfault+0x97 #5 0xffffffff81093fab at trap+0x2ab #6 0xffffffff810687f8 at calltrap+0x8 #7 0xffffffff82925610 at wg_module_event_handler+0x120 #8 0xffffffff80bd53c3 at module_register_init+0xd3 #9 0xffffffff80bc5c61 at linker_load_module+0xc01 #10 0xffffffff80bc73b9 at kern_kldload+0xe9 #11 0xffffffff80bc74db at sys_kldload+0x5b #12 0xffffffff810952f7 at amd64_syscall+0x147 #13 0xffffffff8106911e at fast_syscall_common+0xf8 Signed-off-by: Jason A. Donenfeld --- .cirrus.yml | 3 +-- src/if_wg.c | 22 +++++++++++++++------- src/selftest/cookie.c | 33 +++++++++++++++++++++++---------- src/selftest/counter.c | 3 ++- src/wg_cookie.h | 2 +- src/wg_noise.h | 2 +- 6 files changed, 43 insertions(+), 22 deletions(-) diff --git a/.cirrus.yml b/.cirrus.yml index 0d0036c..bcca434 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -2,11 +2,10 @@ freebsd_task: timeout_in: 120m install_script: - ASSUME_ALWAYS_YES=yes pkg bootstrap -f ; pkg install -y bash iperf3 wireguard-tools - script: - fetch https://download.freebsd.org/ftp/releases/$(uname -m)/$(uname -r)/src.txz - tar -C / -x -f src.txz build_script: - - make -j $(sysctl -n hw.ncpu) -C src + - make -j $(sysctl -n hw.ncpu) -C src DEBUG_FLAGS=-DSELFTESTS test_script: - kldload src/if_wg.ko - tests/netns.sh diff --git a/src/if_wg.c b/src/if_wg.c index 2ab9a99..a6e19d6 100644 --- a/src/if_wg.c +++ b/src/if_wg.c @@ -2986,19 +2986,23 @@ wg_prison_remove(void *obj, void *data __unused) #ifdef SELFTESTS #include "selftest/allowedips.c" -static void wg_run_selftests(void) +static bool wg_run_selftests(void) { - wg_allowedips_selftest(); - noise_counter_selftest(); - cookie_selftest(); + bool ret = true; + ret &= wg_allowedips_selftest(); + ret &= noise_counter_selftest(); + ret &= cookie_selftest(); + return ret; } #else -static inline void wg_run_selftests(void) { } +static inline bool wg_run_selftests(void) { return true; } #endif static int wg_module_init(void) { + int ret = ENOMEM; + osd_method_t methods[PR_MAXMETHOD] = { [PR_METHOD_REMOVE] = wg_prison_remove, }; @@ -3010,13 +3014,17 @@ wg_module_init(void) goto free_zone; wg_osd_jail_slot = osd_jail_register(NULL, methods); - wg_run_selftests(); + + ret = ENOTRECOVERABLE; + if (!wg_run_selftests()) + goto free_zone; + return (0); free_zone: uma_zdestroy(wg_packet_zone); free_none: - return (ENOMEM); + return (ret); } static void diff --git a/src/selftest/cookie.c b/src/selftest/cookie.c index 543aacb..4076e4c 100644 --- a/src/selftest/cookie.c +++ b/src/selftest/cookie.c @@ -30,9 +30,10 @@ static const struct expected_results { static struct ratelimit rl; -static void +static bool cookie_ratelimit_timings_test(void) { + bool ret = false; struct sockaddr_in sin; #ifdef INET6 struct sockaddr_in6 sin6; @@ -91,15 +92,18 @@ cookie_ratelimit_timings_test(void) #endif } T_PASSED; + ret = true; cleanup: ratelimit_deinit(&rl); + return ret; } -static void +static bool cookie_ratelimit_capacity_test(void) { struct sockaddr_in sin; int i; + bool ret = false; bzero(&rl, sizeof(rl)); ratelimit_init(&rl); @@ -120,15 +124,18 @@ cookie_ratelimit_capacity_test(void) } } T_PASSED; + ret = true; cleanup: ratelimit_deinit(&rl); + return ret; } -static void +static bool cookie_ratelimit_gc_test(void) { struct sockaddr_in sin; int i; + bool ret = false; bzero(&rl, sizeof(rl)); ratelimit_init(&rl); @@ -165,11 +172,13 @@ cookie_ratelimit_gc_test(void) if (rl.rl_table_num != 0) T_FAILED("gc"); T_PASSED; + ret = true; cleanup: ratelimit_deinit(&rl); + return ret; } -static void +static bool cookie_mac_test(void) { struct cookie_checker checker; @@ -177,6 +186,7 @@ cookie_mac_test(void) struct cookie_macs cm; struct sockaddr_in sin; int res, i; + bool ret = false; uint8_t nonce[COOKIE_NONCE_SIZE]; uint8_t cookie[COOKIE_ENCRYPTED_SIZE]; @@ -280,15 +290,18 @@ cookie_mac_test(void) T_FAILED("validate_macs_load_normal_mac2_retry"); T_PASSED; + ret = true; cleanup: - return; + return ret; } -void +bool cookie_selftest(void) { - cookie_ratelimit_timings_test(); - cookie_ratelimit_capacity_test(); - cookie_ratelimit_gc_test(); - cookie_mac_test(); + bool ret = true; + ret &= cookie_ratelimit_timings_test(); + ret &= cookie_ratelimit_capacity_test(); + ret &= cookie_ratelimit_gc_test(); + ret &= cookie_mac_test(); + return ret; } diff --git a/src/selftest/counter.c b/src/selftest/counter.c index c715dec..1fedb71 100644 --- a/src/selftest/counter.c +++ b/src/selftest/counter.c @@ -16,7 +16,7 @@ } \ } while (0) -void +bool noise_counter_selftest(void) { struct noise_keypair kp; @@ -95,4 +95,5 @@ noise_counter_selftest(void) if (success) printf("nonce counter self-test: pass\n"); + return success; } diff --git a/src/wg_cookie.h b/src/wg_cookie.h index 099cda6..8e59c32 100644 --- a/src/wg_cookie.h +++ b/src/wg_cookie.h @@ -68,7 +68,7 @@ int cookie_checker_validate_macs(struct cookie_checker *, struct vnet *); #ifdef SELFTESTS -void cookie_selftest(void); +bool cookie_selftest(void); #endif /* SELFTESTS */ #endif /* __COOKIE_H__ */ diff --git a/src/wg_noise.h b/src/wg_noise.h index 6fa282b..219b268 100644 --- a/src/wg_noise.h +++ b/src/wg_noise.h @@ -129,7 +129,7 @@ int noise_consume_response( uint8_t en[0 + NOISE_AUTHTAG_LEN]); #ifdef SELFTESTS -void noise_counter_selftest(void); +bool noise_counter_selftest(void); #endif /* SELFTESTS */ #endif /* __NOISE_H__ */ -- cgit v1.2.3-59-g8ed1b