152 lines · cpp
1//===-- interception_linux_test.cpp ---------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer/AddressSanitizer runtime.10// Tests for interception_linux.h.11//12//===----------------------------------------------------------------------===//13 14// Do not declare functions in ctype.h.15#define __NO_CTYPE16 17#include "interception/interception.h"18 19#include <stdlib.h>20 21#include "gtest/gtest.h"22 23#if SANITIZER_LINUX24 25static int isdigit_called;26namespace __interception {27int isalpha_called;28int isalnum_called;29int islower_called;30} // namespace __interception31using namespace __interception;32 33DECLARE_REAL(int, isdigit, int);34DECLARE_REAL(int, isalpha, int);35DECLARE_REAL(int, isalnum, int);36DECLARE_REAL(int, islower, int);37 38INTERCEPTOR(void *, malloc, SIZE_T s) { return calloc(1, s); }39INTERCEPTOR(void, dummy_doesnt_exist__, ) { __builtin_trap(); }40 41INTERCEPTOR(int, isdigit, int d) {42 ++isdigit_called;43 return d >= '0' && d <= '9';44}45 46INTERCEPTOR(int, isalpha, int d) {47 // Use non-commutative arithmetic to verify order of calls.48 isalpha_called = isalpha_called * 10 + 3;49 return (d >= 'a' && d <= 'z') || (d >= 'A' && d <= 'Z');50}51 52INTERCEPTOR(int, isalnum, int d) {53 isalnum_called = isalnum_called * 10 + 3;54 return __interceptor_isalpha(d) || __interceptor_isdigit(d);55}56 57INTERCEPTOR(int, islower, int d) {58 islower_called = islower_called * 10 + 3;59 return d >= 'a' && d <= 'z';60}61 62namespace __interception {63 64TEST(Interception, InterceptFunction) {65 uptr malloc_address = 0;66 EXPECT_TRUE(InterceptFunction("malloc", &malloc_address, (uptr)&malloc,67 (uptr)&TRAMPOLINE(malloc)));68 EXPECT_NE(0U, malloc_address);69 EXPECT_FALSE(InterceptFunction("malloc", &malloc_address, (uptr)&calloc,70 (uptr)&TRAMPOLINE(malloc)));71 72 uptr dummy_address = 0;73 EXPECT_FALSE(InterceptFunction("dummy_doesnt_exist__", &dummy_address,74 (uptr)&dummy_doesnt_exist__,75 (uptr)&TRAMPOLINE(dummy_doesnt_exist__)));76 EXPECT_EQ(0U, dummy_address);77}78 79TEST(Interception, Basic) {80 EXPECT_TRUE(INTERCEPT_FUNCTION(isdigit));81 82 // After interception, the counter should be incremented.83 isdigit_called = 0;84 EXPECT_NE(0, isdigit('1'));85 EXPECT_EQ(1, isdigit_called);86 EXPECT_EQ(0, isdigit('a'));87 EXPECT_EQ(2, isdigit_called);88 89 // Calling the REAL function should not affect the counter.90 isdigit_called = 0;91 EXPECT_NE(0, REAL(isdigit)('1'));92 EXPECT_EQ(0, REAL(isdigit)('a'));93 EXPECT_EQ(0, isdigit_called);94}95 96TEST(Interception, ForeignOverrideDirect) {97 // Actual interceptor is overridden.98 EXPECT_FALSE(INTERCEPT_FUNCTION(isalpha));99 100 isalpha_called = 0;101 EXPECT_NE(0, isalpha('a'));102 EXPECT_EQ(13, isalpha_called);103 isalpha_called = 0;104 EXPECT_EQ(0, isalpha('_'));105 EXPECT_EQ(13, isalpha_called);106 107 isalpha_called = 0;108 EXPECT_NE(0, REAL(isalpha)('a'));109 EXPECT_EQ(0, REAL(isalpha)('_'));110 EXPECT_EQ(0, isalpha_called);111}112 113#if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT114TEST(Interception, ForeignOverrideIndirect) {115 // Actual interceptor is _not_ overridden.116 EXPECT_TRUE(INTERCEPT_FUNCTION(isalnum));117 118 isalnum_called = 0;119 EXPECT_NE(0, isalnum('a'));120 EXPECT_EQ(13, isalnum_called);121 isalnum_called = 0;122 EXPECT_EQ(0, isalnum('_'));123 EXPECT_EQ(13, isalnum_called);124 125 isalnum_called = 0;126 EXPECT_NE(0, REAL(isalnum)('a'));127 EXPECT_EQ(0, REAL(isalnum)('_'));128 EXPECT_EQ(0, isalnum_called);129}130 131TEST(Interception, ForeignOverrideThree) {132 // Actual interceptor is overridden.133 EXPECT_FALSE(INTERCEPT_FUNCTION(islower));134 135 islower_called = 0;136 EXPECT_NE(0, islower('a'));137 EXPECT_EQ(123, islower_called);138 islower_called = 0;139 EXPECT_EQ(0, islower('A'));140 EXPECT_EQ(123, islower_called);141 142 islower_called = 0;143 EXPECT_NE(0, REAL(islower)('a'));144 EXPECT_EQ(0, REAL(islower)('A'));145 EXPECT_EQ(0, islower_called);146}147#endif // ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT148 149} // namespace __interception150 151#endif // SANITIZER_LINUX152