Skip to content

[HWASAN]Implement memcmp interceptor in HWASAN #67204

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

Merged
merged 10 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions compiler-rt/lib/hwasan/hwasan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@

using namespace __hwasan;

struct HWAsanInterceptorContext {
const char *interceptor_name;
};

# define ACCESS_MEMORY_RANGE(ctx, offset, size, access) \
do { \
__hwasan::CheckAddressSized<ErrorAction::Abort, access>((uptr)offset, \
size); \
} while (0)

# define HWASAN_READ_RANGE(ctx, offset, size) \
ACCESS_MEMORY_RANGE(ctx, offset, size, AccessType::Load)
# define HWASAN_WRITE_RANGE(ctx, offset, size) \
ACCESS_MEMORY_RANGE(ctx, offset, size, AccessType::Store)

# if !SANITIZER_APPLE
# define HWASAN_INTERCEPT_FUNC(name) \
do { \
Expand Down Expand Up @@ -79,13 +94,11 @@ using namespace __hwasan;
} while (false)

# define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
do { \
(void)(ctx); \
(void)(ptr); \
(void)(size); \
} while (false)
HWASAN_READ_RANGE(ctx, ptr, size)

# define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
HWAsanInterceptorContext _ctx = {#func}; \
ctx = (void *)&_ctx; \
do { \
(void)(ctx); \
(void)(func); \
Expand Down
4 changes: 2 additions & 2 deletions compiler-rt/lib/hwasan/hwasan_platform_interceptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@
#undef SANITIZER_INTERCEPT_MEMCPY
#define SANITIZER_INTERCEPT_MEMCPY 0

#undef SANITIZER_INTERCEPT_MEMCMP
#define SANITIZER_INTERCEPT_MEMCMP 0
// #undef SANITIZER_INTERCEPT_MEMCMP
// #define SANITIZER_INTERCEPT_MEMCMP 0

#undef SANITIZER_INTERCEPT_BCMP
#define SANITIZER_INTERCEPT_BCMP 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,13 @@ INTERCEPTOR(char*, textdomain, const char *domainname) {
#define INIT_TEXTDOMAIN
#endif

#if SANITIZER_INTERCEPT_STRCMP
#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP
static inline int CharCmpX(unsigned char c1, unsigned char c2) {
return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
}
#endif

#if SANITIZER_INTERCEPT_STRCMP
DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
const char *s1, const char *s2, int result)

Expand Down
27 changes: 27 additions & 0 deletions compiler-rt/test/hwasan/TestCases/memcmp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// RUN: %clangxx_hwasan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_hwasan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_hwasan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_hwasan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s

#include <sanitizer/hwasan_interface.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv) {
__hwasan_enable_allocator_tagging();
char a[] = {static_cast<char>(argc), 2, 3, 4};
volatile int size = sizeof(a);
char *volatile p = (char *)malloc(size);
memcpy(p, a, size);
free(p);
return memcmp(p, a, size);
// CHECK: HWAddressSanitizer: tag-mismatch on address
// CHECK: READ of size 4
// CHECK: #{{[[:digit:]]+}} 0x{{[[:xdigit:]]+}} in main {{.*}}memcmp.cpp:[[@LINE-3]]
// CHECK: Cause: use-after-free
// CHECK: freed by thread
// CHECK: #{{[[:digit:]]+}} 0x{{[[:xdigit:]]+}} in main {{.*}}memcmp.cpp:[[@LINE-7]]
// CHECK: previously allocated by thread
// CHECK: #{{[[:digit:]]+}} 0x{{[[:xdigit:]]+}} in main {{.*}}memcmp.cpp:[[@LINE-11]]
}