From 8a7c59dc9406f8c8ec821844ce3309ddd23549ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 13 Mar 2024 23:38:37 +0200 Subject: [PATCH] test: Avoid the compiler optimizing out the cfguard check call When calling make_indirect_call with a parameter which is known, Clang, since the 18.x release, can end up producing a specialized version of the function which omits the cfguard check call (as the target is known) and calls the known target directly. The function is marked with a noinline attribute, to avoid the compiler optimizing out the cfguard check call when the target is known, but even with a noinline function, the compiler apparently can make a separate specialized version of it. To avoid the compiler doing such optimizations, reference the target function via a global variable - the compiler can't assume anything about the contents of them (they could be altered between initialization and reading them later). This fixes the cfguard invalid_icall test with Clang 18.x, when compiled with optimizations enabled. --- test/cfguard-test.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/cfguard-test.c b/test/cfguard-test.c index 24642cf..e552754 100644 --- a/test/cfguard-test.c +++ b/test/cfguard-test.c @@ -76,6 +76,8 @@ int check_cfguard_status(void) { return policy.EnableControlFlowGuard; } +void *nop_sled_target_ptr = nop_sled_target; + int main(int argc, char *argv[]) { if (argc == 2) { if (strcmp(argv[1], "check_enabled") == 0) { @@ -93,7 +95,7 @@ int main(int argc, char *argv[]) { return 0; } if (strcmp(argv[1], "invalid_icall") == 0) { - void *target = nop_sled_target; + void *target = nop_sled_target_ptr; target += 16; puts("Performing invalid indirect call. If CFG is enabled this " "should crash with exit code 0xc0000409 (-1073740791)..."); @@ -103,7 +105,7 @@ int main(int argc, char *argv[]) { return 1; } if (strcmp(argv[1], "invalid_icall_nocf") == 0) { - void *target = nop_sled_target; + void *target = nop_sled_target_ptr; target += 16; puts("Performing invalid indirect call without CFG. You should " "get an exit code 2...");