Skip to content

Commit

Permalink
[hwasan] Fix rare false negative (zero tag) in stack-uar.c (llvm#69374)
Browse files Browse the repository at this point in the history
stack-uar.c is flaky (1 in 256 executions) because the random tag
may be zero (llvm#69221).

This patch works around the issue in the same way as deep-recursion.c

(llvm@aa4dfd3),
by falling back to a neighboring object, which must have a different
(non-zero) tag.

This patch also does a minor cleanup of the aforementioned
deep-recursion.c, for consistency with stack-uar.c.

Co-authored-by: Thurston Dang <[email protected]>
  • Loading branch information
thurstond and thurstond authored Oct 18, 2023
1 parent 192d332 commit ddf1de2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 9 deletions.
14 changes: 8 additions & 6 deletions compiler-rt/test/hwasan/TestCases/deep-recursion.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
// Stack histories are currently not recorded on x86.
// XFAIL: target=x86_64{{.*}}

#include <stdint.h>
#include <assert.h>
#include <sanitizer/hwasan_interface.h>
#include <stdlib.h>

// At least -O1 is needed for this function to not have a stack frame on
Expand All @@ -33,11 +34,12 @@ __attribute__((noinline)) void OOB() {
int y[4];

// Tags for stack-allocated variables can occasionally be zero, resulting in
// a false negative for this test. This is not easy to fix, hence we work
// around it: if the tag is zero, we use the neighboring variable instead,
// which must have a different (hence non-zero) tag.
// This tag check assumes aarch64.
if (((uintptr_t)&x) >> 56 == 0) {
// a false negative for this test. The tag allocation algorithm is not easy
// to fix, hence we work around it: if the tag is zero, we use the
// neighboring variable instead, which must have a different (hence non-zero)
// tag.
if (__hwasan_tag_pointer(x, 0) == x) {
assert(__hwasan_tag_pointer(y, 0) != y);
y[four] = 0;
} else {
x[four] = 0;
Expand Down
21 changes: 18 additions & 3 deletions compiler-rt/test/hwasan/TestCases/stack-uar.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,29 @@
// Stack histories currently are not recorded on x86.
// XFAIL: target=x86_64{{.*}}

#include <assert.h>
#include <sanitizer/hwasan_interface.h>

void USE(void *x) { // pretend_to_do_something(void *x)
__asm__ __volatile__("" : : "r" (x) : "memory");
}

__attribute__((noinline))
char *buggy() {
char zzz[0x1000];
char *volatile p = zzz;
char zzz[0x800];
char yyy[0x800];
// Tags for stack-allocated variables can occasionally be zero, resulting in
// a false negative for this test. The tag allocation algorithm is not easy
// to fix, hence we work around it: if the tag is zero, we use the
// neighboring variable instead, which must have a different (hence non-zero)
// tag.
char *volatile p;
if (__hwasan_tag_pointer(zzz, 0) == zzz) {
assert(__hwasan_tag_pointer(yyy, 0) != yyy);
p = yyy;
} else {
p = zzz;
}
return p;
}

Expand All @@ -35,7 +50,7 @@ int main() {
// CHECK: Cause: stack tag-mismatch
// CHECK: is located in stack of thread
// CHECK: Potentially referenced stack objects:
// CHECK-NEXT: zzz in buggy {{.*}}stack-uar.c:[[@LINE-20]]
// CHECK-NEXT: {{zzz|yyy}} in buggy {{.*}}stack-uar.c:
// CHECK-NEXT: Memory tags around the buggy address

// NOSYM: Previously allocated frames:
Expand Down

0 comments on commit ddf1de2

Please sign in to comment.