admin管理员组文章数量:1416051
This is a follow-up related to Inconsistent false positives with Clang CFI sanitizer and function pointers, but it is for a separate issue
Issue
Background
I have an array of structs which store function pointers, which I loop over and call (my real code is more complex than the sample given). To ensure correct behaviour, I enabled CFI with -fsanitize=cfi -fvisiblity=hidden -flto -fcf-protection=full
.
I then started to encounter false positives, where CFI is trapping upon calling these function pointers. These only seem to occur on compilers clang-11
through clang-15
(I will use clang-15
). This also only occurs when -fsanitize=cfi, -fcf-protection=full
are used together.
Issue
Upon calling the first function pointer, it seems to jump to the wrong address, which immediately causes a trap:
$ clang-15 -o main main.c -Wall -Wextra -Wpedantic -O3 -fsanitize=cfi -fvisibility=hidden -flto -fcf-protection=full
$ gdb ./main -ex run
Program received signal SIGTRAP, Trace/breakpoint trap.
0x000000000040123b in func_a ()
(gdb) where
#0 0x000000000040123b in func_a ()
Backtrace stopped: Cannot access memory at address 0xffffde57
(gdb)
This issue only occurs when I have more than one function in the array - with a single function it works fine, but multiple functions always causes a trap.
Looking at the disassembly, it appears that in the single case, clang
just inlines the call, which is why the issue only occurs with multiple elements in the array.
My question is: why is this happening, and is it a bug in my code, or in clang?
My System
$ uname -srvpio
Linux 6.9.3-76060903-generic #202405300957~1736980680~22.04~44ea8a9 SMP PREEMPT_DYNAMIC Thu J x86_64 x86_64 GNU/Linux
I can however reproduce this with on Compiler Explorer (see link below)
Code
Source
#include <stdio.h>
typedef void (Func)(void);
typedef struct { char *name; Func *ptr; } Function;
static void func_a(void) { printf("()"); }
static void func_b(void) { printf("()"); }
static void func_c(void) { printf("()"); }
static void func_d(void) { printf("()"); }
Function
function_a = { "a", &func_a },
function_b = { "b", &func_b },
function_c = { "c", &func_c },
function_d = { "d", &func_d };
Function *const functions[] = {
&function_a,
&function_b,
&function_c,
&function_d,
};
size_t functions_len = sizeof functions / sizeof *functions;
int main(void) {
size_t i;
setbuf(stdout, NULL);
for (i = 0; i < functions_len; i++) {
Function *const func = functions[i];
printf("%s", func->name);
func->ptr();
printf(";");
}
return 0;
}
Disassembly
本文标签: cFalse positives with Clang CFI sanitizer and array of functionsStack Overflow
版权声明:本文标题:c - False positives with Clang CFI sanitizer and array of functions - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745248146a2649656.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论