CFI Type Mismatch (Function Pointer Cast) in ARM Linux Parser
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 1.2k
- Forks
- 409
- PR merge metrics
- No merged PRs in 30d
Description
Hi, I spotted this when trying to run an Android application under UBSan. Upon digging, I found this issue:
A Clang Control Flow Integrity (CFI) type mismatch occurs in src/arm/linux/cpuinfo.c when invoking the parse_line callback through the cpuinfo_line_callback function pointer. This triggers a runtime SIGTRAP when CFI is enabled.
The issue is that parse_line is defined with a specific structure pointer as its third argument, but it is cast to cpuinfo_line_callback which expects void* for that argument.
In src/arm/linux/cpuinfo.c we have parse_line which takes a proc_cpuinfo_parser_state argument
In cpuinfo_arm_linux_parse_proc_cpuinfo:
The callback type is defined in src/linux/api.h as:
https://github.com/pytorch/cpuinfo/blob/ae5443646e5092d42d2a5b6e202b548169bc023e/src/linux/api.h#L37
The problem is specifically here, where we cast parse_line to cpuinfo_line_callback. These functions have different signatures:
Calling a function through a pointer of a different type (even if they are pointer-compatible in some ABIs) is Undefined Behavior in C and is flagged by Clang's -fsanitize=cfi-icall.
Suggested fix: Change parse_line to accept void* for the context argument, and cast it inside the function. Remove the cast when passing it to cpuinfo_linux_parse_multiline_file.
--- a/src/arm/linux/cpuinfo.c
+++ b/src/arm/linux/cpuinfo.c
@@ -726,8 +726,9 @@
static bool parse_line(
const char* line_start,
const char* line_end,
- struct proc_cpuinfo_parser_state state[restrict static 1],
+ void* context,
uint64_t line_number) {
+ struct proc_cpuinfo_parser_state* restrict state = (struct proc_cpuinfo_parser_state*)context;
/* Empty line. Skip. */
if (line_start == line_end) {
return true;
@@ -1019,5 +1018,5 @@
.processors = processors,
};
return cpuinfo_linux_parse_multiline_file(
- "/proc/cpuinfo", BUFFER_SIZE, (cpuinfo_line_callback)parse_line, &state);
+ "/proc/cpuinfo", BUFFER_SIZE, parse_line, &state);
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/arm/linux/cpuinfo.c at parse_line and cpuinfo_arm_linux_parse_proc_cpuinfo, then compare the callback declaration in src/linux/api.h. Make the callback signatures agree without a function-pointer cast, and verify the ARM Linux parser under Clang CFI/UBSan so the SIGTRAP no longer occurs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100