-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
-fsanitize=alignment false positive with intended unaligned struct member access #83710
Comments
IMNSHO not a false positive. In C/C++, UB would be already in the caller of f if entry isn't properly aligned, but neither LLVM nor GCC diagnose that in UBSAN. What is diagnosed is &entry->offset which implies that entry must be properly aligned. Use char * pointer arithmetics with offsetof instead to avoid UBSAN diagnosing it, and even better pass a void * or char * pointer instruct of struct dir_entry and use offsetof and __get_unaligned_t perhaps inside of some macro. |
Thanks for looking into this. It is somewhat misleading to call this a "false positive" as it is certainly UB in the specification. However, #67766 explicitly allows misaligned memory access when no struct member is involved. I see no reason to change the behavior only when struct member is involved. For example, consider the following functions: u64 f3(u64 *offset)
{
u64 buffer;
__builtin_memcpy(&buffer, offset, sizeof(buffer));
return buffer;
}
u64 f4(u64 *offset)
{
u64 buffer;
__builtin_memcpy(&buffer, (void *)offset, sizeof(buffer));
return buffer;
}
u64 f5(struct dir_entry *entry)
{
u64 buffer;
__builtin_memcpy(&buffer, (void *)&entry->offset, sizeof(buffer));
return buffer;
} There are already UBs if the callers of these functions create arguments of these functions by casting misaligned addresses to the respective pointers. In that sense, UBSan is allowed to generate errors for all of them, and an optimization pass can freely translate the Nevertheless, #67766 still tolerates I described my opinion regarding
|
Per discussions on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114217, Clang's behavior is expected.
https://lists.llvm.org/pipermail/llvm-dev/2016-January/094012.html has some background of Clang's behavior, which appears to match GCC's -fsanitize=alignment strategy as well. There are certainly rough edges (e.g. memcpy instrumentation before my #69240), but this issue isn't such a case. |
Thanks for sharing the RFC; it is very informative. The RFC says:
Does
|
Perhaps the following function is easier to understand: u64 f6(struct dir_entry *entry)
{
u64 buffer;
void *p = (void *)&entry->offset;
__builtin_memcpy(&buffer, p, sizeof(buffer));
return buffer;
} This should not be UB according to the RFC even if |
@rjmccall Hi, I'd like to ask your opinion since you are the author of the RFC: #83710 (comment) |
That's correct; according to our interpretation in the RFC, both of those should be valid (unless somehow |
Can you reopen this issue? I'm apparently not allowed to reopen it. |
@MaskRay Hi, can you check the above discussion and reopen this issue if it looks reasonable to you? |
-fsanitize=alignment
generates a false positive error for an intended unaligned struct member access. The intention of unaligned struct member access is expressed with__builtin_memcpy()
as done by QEMU or packed struct access as done by Linux. GCC translates such a construct to code to access memory unaligned for architectures like rv64gc as intended but also emits code to enforce the alignment.The relevant code of QEMU is at: https://gitlab.com/qemu-project/qemu/-/blob/v8.2.1/include/qemu/bswap.h?ref_type=tags
The relevant code of Linux is at: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/asm-generic/unaligned.h?h=v6.7
FYI, this issue is reproducible also with 13.2.0, and the relevant ticket is available at: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114217
To reproduce the issue, compile the code shown below with
-O2 -fsanitize=alignment
for rv64gc:The text was updated successfully, but these errors were encountered: