// RUN: %clang_scudo %s -o %t // RUN: %run %t after 2>&1 | FileCheck %s // RUN: %run %t before 2>&1 | FileCheck %s // Test that we hit a guard page when writing past the end of a chunk // allocated by the Secondary allocator, or writing too far in front of it. #include #include #include #include #include #include void handler(int signo, siginfo_t *info, void *uctx) { if (info->si_code == SEGV_ACCERR) { fprintf(stderr, "SCUDO SIGSEGV\n"); exit(0); } exit(1); } int main(int argc, char **argv) { // The size must be large enough to be serviced by the secondary allocator. long page_size = sysconf(_SC_PAGESIZE); size_t size = (1U << 17) + page_size; struct sigaction a; assert(argc == 2); memset(&a, 0, sizeof(a)); a.sa_sigaction = handler; a.sa_flags = SA_SIGINFO; char *p = (char *)malloc(size); assert(p); memset(p, 'A', size); // This should not trigger anything. // Set up the SIGSEGV handler now, as the rest should trigger an AV. sigaction(SIGSEGV, &a, NULL); if (!strcmp(argv[1], "after")) { for (int i = 0; i < page_size; i++) p[size + i] = 'A'; } if (!strcmp(argv[1], "before")) { for (int i = 1; i < page_size; i++) p[-i] = 'A'; } free(p); return 1; // A successful test means we shouldn't reach this. } // CHECK: SCUDO SIGSEGV