Skip to content

Commit db9fbbf

Browse files
committed
rtsan: Support free_sized and free_aligned_sized from C23
Signed-off-by: Justin King <[email protected]>
1 parent 04e2e58 commit db9fbbf

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,48 @@ INTERCEPTOR(void, free, void *ptr) {
869869
return REAL(free)(ptr);
870870
}
871871

872+
#if SANITIZER_INTERCEPT_FREE_SIZED
873+
INTERCEPTOR(void, free_sized, void *ptr, SIZE_T size) {
874+
if (DlsymAlloc::PointerIsMine(ptr))
875+
return DlsymAlloc::Free(ptr);
876+
877+
// According to the C and C++ standard, freeing a nullptr is guaranteed to be
878+
// a no-op (and thus real-time safe). This can be confirmed for looking at
879+
// __libc_free in the glibc source.
880+
if (ptr != nullptr)
881+
__rtsan_notify_intercepted_call("free_sized");
882+
883+
if (REAL(free_sized))
884+
return REAL(free_sized)(ptr, size);
885+
return REAL(free)(ptr);
886+
}
887+
#define RTSAN_MAYBE_INTERCEPT_FREE_SIZED INTERCEPT_FUNCTION(free_sized)
888+
#else
889+
#define RTSAN_MAYBE_INTERCEPT_FREE_SIZED
890+
#endif
891+
892+
#if SANITIZER_INTERCEPT_FREE_ALIGNED_SIZED
893+
INTERCEPTOR(void, free_aligned_sized, void *ptr, SIZE_T alignment,
894+
SIZE_T size) {
895+
if (DlsymAlloc::PointerIsMine(ptr))
896+
return DlsymAlloc::Free(ptr);
897+
898+
// According to the C and C++ standard, freeing a nullptr is guaranteed to be
899+
// a no-op (and thus real-time safe). This can be confirmed for looking at
900+
// __libc_free in the glibc source.
901+
if (ptr != nullptr)
902+
__rtsan_notify_intercepted_call("free_aligned_sized");
903+
904+
if (REAL(free_aligned_sized))
905+
return REAL(free_aligned_sized)(ptr, alignment, size);
906+
return REAL(free)(ptr);
907+
}
908+
#define RTSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED \
909+
INTERCEPT_FUNCTION(free_aligned_sized)
910+
#else
911+
#define RTSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED
912+
#endif
913+
872914
INTERCEPTOR(void *, malloc, SIZE_T size) {
873915
if (DlsymAlloc::Use())
874916
return DlsymAlloc::Allocate(size);
@@ -1493,6 +1535,8 @@ INTERCEPTOR(INT_TYPE_SYSCALL, syscall, INT_TYPE_SYSCALL number, ...) {
14931535
void __rtsan::InitializeInterceptors() {
14941536
INTERCEPT_FUNCTION(calloc);
14951537
INTERCEPT_FUNCTION(free);
1538+
RTSAN_MAYBE_INTERCEPT_FREE_SIZED;
1539+
RTSAN_MAYBE_INTERCEPT_FREE_ALIGNED_SIZED;
14961540
INTERCEPT_FUNCTION(malloc);
14971541
INTERCEPT_FUNCTION(realloc);
14981542
INTERCEPT_FUNCTION(reallocf);
Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
// RUN: %clang -std=c23 -O0 %s -o %t && %run %t
2-
// UNSUPPORTED: asan, hwasan, rtsan, tsan, ubsan
2+
// UNSUPPORTED: asan, hwasan, tsan, ubsan
33

44
#include <stddef.h>
55
#include <stdlib.h>
66

7+
#if defined(__has_feature) && __has_feature(realtime_sanitizer)
8+
# include <sanitizer/rtsan_interface.h>
9+
#endif
10+
11+
extern void *aligned_alloc(size_t alignment, size_t size);
12+
713
extern void free_aligned_sized(void *p, size_t alignment, size_t size);
814

915
int main() {
16+
#if defined(__has_feature) && __has_feature(realtime_sanitizer)
17+
__rtsan_disable();
18+
#endif
1019
volatile void *p = aligned_alloc(128, 1024);
1120
free_aligned_sized((void *)p, 128, 1024);
21+
#if defined(__has_feature) && __has_feature(realtime_sanitizer)
22+
__rtsan_enable();
23+
#endif
1224
return 0;
1325
}
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
// RUN: %clang -std=c23 -O0 %s -o %t && %run %t
2-
// UNSUPPORTED: asan, hwasan, rtsan, tsan, ubsan
2+
// UNSUPPORTED: asan, hwasan, tsan, ubsan
33

44
#include <stddef.h>
55
#include <stdlib.h>
66

7-
extern void *aligned_alloc(size_t alignment, size_t size);
7+
#if defined(__has_feature) && __has_feature(realtime_sanitizer)
8+
# include <sanitizer/rtsan_interface.h>
9+
#endif
810

911
extern void free_sized(void *p, size_t size);
1012

1113
int main() {
14+
#if defined(__has_feature) && __has_feature(realtime_sanitizer)
15+
__rtsan_disable();
16+
#endif
1217
volatile void *p = malloc(64);
1318
free_sized((void *)p, 64);
19+
#if defined(__has_feature) && __has_feature(realtime_sanitizer)
20+
__rtsan_enable();
21+
#endif
1422
return 0;
1523
}

0 commit comments

Comments
 (0)