19642e337SNico Weber //===-- interception_linux_test.cpp ---------------------------------------===//
29642e337SNico Weber //
39642e337SNico Weber // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
49642e337SNico Weber // See https://llvm.org/LICENSE.txt for license information.
59642e337SNico Weber // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69642e337SNico Weber //
79642e337SNico Weber //===----------------------------------------------------------------------===//
89642e337SNico Weber //
99642e337SNico Weber // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
109642e337SNico Weber // Tests for interception_linux.h.
119642e337SNico Weber //
129642e337SNico Weber //===----------------------------------------------------------------------===//
139642e337SNico Weber
14*37445e96SMarco Elver // Do not declare functions in ctype.h.
159642e337SNico Weber #define __NO_CTYPE
169642e337SNico Weber
179642e337SNico Weber #include "interception/interception.h"
189642e337SNico Weber
19*37445e96SMarco Elver #include <stdlib.h>
20*37445e96SMarco Elver
219642e337SNico Weber #include "gtest/gtest.h"
229642e337SNico Weber
239642e337SNico Weber #if SANITIZER_LINUX
249642e337SNico Weber
25*37445e96SMarco Elver static int isdigit_called;
26*37445e96SMarco Elver namespace __interception {
27*37445e96SMarco Elver int isalpha_called;
28*37445e96SMarco Elver int isalnum_called;
29*37445e96SMarco Elver int islower_called;
30*37445e96SMarco Elver } // namespace __interception
31*37445e96SMarco Elver using namespace __interception;
329642e337SNico Weber
339642e337SNico Weber DECLARE_REAL(int, isdigit, int);
34*37445e96SMarco Elver DECLARE_REAL(int, isalpha, int);
35*37445e96SMarco Elver DECLARE_REAL(int, isalnum, int);
36*37445e96SMarco Elver DECLARE_REAL(int, islower, int);
37*37445e96SMarco Elver
INTERCEPTOR(void *,malloc,SIZE_T s)38*37445e96SMarco Elver INTERCEPTOR(void *, malloc, SIZE_T s) { return calloc(1, s); }
39*37445e96SMarco Elver INTERCEPTOR(void, dummy_doesnt_exist__, ) { __builtin_trap(); }
409642e337SNico Weber
INTERCEPTOR(int,isdigit,int d)419642e337SNico Weber INTERCEPTOR(int, isdigit, int d) {
42*37445e96SMarco Elver ++isdigit_called;
439642e337SNico Weber return d >= '0' && d <= '9';
449642e337SNico Weber }
459642e337SNico Weber
INTERCEPTOR(int,isalpha,int d)46*37445e96SMarco Elver INTERCEPTOR(int, isalpha, int d) {
47*37445e96SMarco Elver // Use non-commutative arithmetic to verify order of calls.
48*37445e96SMarco Elver isalpha_called = isalpha_called * 10 + 3;
49*37445e96SMarco Elver return (d >= 'a' && d <= 'z') || (d >= 'A' && d <= 'Z');
50*37445e96SMarco Elver }
51*37445e96SMarco Elver
INTERCEPTOR(int,isalnum,int d)52*37445e96SMarco Elver INTERCEPTOR(int, isalnum, int d) {
53*37445e96SMarco Elver isalnum_called = isalnum_called * 10 + 3;
54*37445e96SMarco Elver return __interceptor_isalpha(d) || __interceptor_isdigit(d);
55*37445e96SMarco Elver }
56*37445e96SMarco Elver
INTERCEPTOR(int,islower,int d)57*37445e96SMarco Elver INTERCEPTOR(int, islower, int d) {
58*37445e96SMarco Elver islower_called = islower_called * 10 + 3;
59*37445e96SMarco Elver return d >= 'a' && d <= 'z';
60*37445e96SMarco Elver }
61*37445e96SMarco Elver
629642e337SNico Weber namespace __interception {
639642e337SNico Weber
TEST(Interception,InterceptFunction)649642e337SNico Weber TEST(Interception, InterceptFunction) {
659642e337SNico Weber uptr malloc_address = 0;
66*37445e96SMarco Elver EXPECT_TRUE(InterceptFunction("malloc", &malloc_address, (uptr)&malloc,
67*37445e96SMarco Elver (uptr)&TRAMPOLINE(malloc)));
689642e337SNico Weber EXPECT_NE(0U, malloc_address);
69*37445e96SMarco Elver EXPECT_FALSE(InterceptFunction("malloc", &malloc_address, (uptr)&calloc,
70*37445e96SMarco Elver (uptr)&TRAMPOLINE(malloc)));
719642e337SNico Weber
729642e337SNico Weber uptr dummy_address = 0;
73*37445e96SMarco Elver EXPECT_FALSE(InterceptFunction("dummy_doesnt_exist__", &dummy_address,
74*37445e96SMarco Elver (uptr)&dummy_doesnt_exist__,
75*37445e96SMarco Elver (uptr)&TRAMPOLINE(dummy_doesnt_exist__)));
769642e337SNico Weber EXPECT_EQ(0U, dummy_address);
779642e337SNico Weber }
789642e337SNico Weber
TEST(Interception,Basic)799642e337SNico Weber TEST(Interception, Basic) {
809642e337SNico Weber EXPECT_TRUE(INTERCEPT_FUNCTION(isdigit));
819642e337SNico Weber
829642e337SNico Weber // After interception, the counter should be incremented.
83*37445e96SMarco Elver isdigit_called = 0;
849642e337SNico Weber EXPECT_NE(0, isdigit('1'));
85*37445e96SMarco Elver EXPECT_EQ(1, isdigit_called);
869642e337SNico Weber EXPECT_EQ(0, isdigit('a'));
87*37445e96SMarco Elver EXPECT_EQ(2, isdigit_called);
889642e337SNico Weber
899642e337SNico Weber // Calling the REAL function should not affect the counter.
90*37445e96SMarco Elver isdigit_called = 0;
919642e337SNico Weber EXPECT_NE(0, REAL(isdigit)('1'));
929642e337SNico Weber EXPECT_EQ(0, REAL(isdigit)('a'));
93*37445e96SMarco Elver EXPECT_EQ(0, isdigit_called);
949642e337SNico Weber }
959642e337SNico Weber
TEST(Interception,ForeignOverrideDirect)96*37445e96SMarco Elver TEST(Interception, ForeignOverrideDirect) {
97*37445e96SMarco Elver // Actual interceptor is overridden.
98*37445e96SMarco Elver EXPECT_FALSE(INTERCEPT_FUNCTION(isalpha));
99*37445e96SMarco Elver
100*37445e96SMarco Elver isalpha_called = 0;
101*37445e96SMarco Elver EXPECT_NE(0, isalpha('a'));
102*37445e96SMarco Elver EXPECT_EQ(13, isalpha_called);
103*37445e96SMarco Elver isalpha_called = 0;
104*37445e96SMarco Elver EXPECT_EQ(0, isalpha('_'));
105*37445e96SMarco Elver EXPECT_EQ(13, isalpha_called);
106*37445e96SMarco Elver
107*37445e96SMarco Elver isalpha_called = 0;
108*37445e96SMarco Elver EXPECT_NE(0, REAL(isalpha)('a'));
109*37445e96SMarco Elver EXPECT_EQ(0, REAL(isalpha)('_'));
110*37445e96SMarco Elver EXPECT_EQ(0, isalpha_called);
111*37445e96SMarco Elver }
112*37445e96SMarco Elver
113*37445e96SMarco Elver #if ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
TEST(Interception,ForeignOverrideIndirect)114*37445e96SMarco Elver TEST(Interception, ForeignOverrideIndirect) {
115*37445e96SMarco Elver // Actual interceptor is _not_ overridden.
116*37445e96SMarco Elver EXPECT_TRUE(INTERCEPT_FUNCTION(isalnum));
117*37445e96SMarco Elver
118*37445e96SMarco Elver isalnum_called = 0;
119*37445e96SMarco Elver EXPECT_NE(0, isalnum('a'));
120*37445e96SMarco Elver EXPECT_EQ(13, isalnum_called);
121*37445e96SMarco Elver isalnum_called = 0;
122*37445e96SMarco Elver EXPECT_EQ(0, isalnum('_'));
123*37445e96SMarco Elver EXPECT_EQ(13, isalnum_called);
124*37445e96SMarco Elver
125*37445e96SMarco Elver isalnum_called = 0;
126*37445e96SMarco Elver EXPECT_NE(0, REAL(isalnum)('a'));
127*37445e96SMarco Elver EXPECT_EQ(0, REAL(isalnum)('_'));
128*37445e96SMarco Elver EXPECT_EQ(0, isalnum_called);
129*37445e96SMarco Elver }
130*37445e96SMarco Elver
TEST(Interception,ForeignOverrideThree)131*37445e96SMarco Elver TEST(Interception, ForeignOverrideThree) {
132*37445e96SMarco Elver // Actual interceptor is overridden.
133*37445e96SMarco Elver EXPECT_FALSE(INTERCEPT_FUNCTION(islower));
134*37445e96SMarco Elver
135*37445e96SMarco Elver islower_called = 0;
136*37445e96SMarco Elver EXPECT_NE(0, islower('a'));
137*37445e96SMarco Elver EXPECT_EQ(123, islower_called);
138*37445e96SMarco Elver islower_called = 0;
139*37445e96SMarco Elver EXPECT_EQ(0, islower('A'));
140*37445e96SMarco Elver EXPECT_EQ(123, islower_called);
141*37445e96SMarco Elver
142*37445e96SMarco Elver islower_called = 0;
143*37445e96SMarco Elver EXPECT_NE(0, REAL(islower)('a'));
144*37445e96SMarco Elver EXPECT_EQ(0, REAL(islower)('A'));
145*37445e96SMarco Elver EXPECT_EQ(0, islower_called);
146*37445e96SMarco Elver }
147*37445e96SMarco Elver #endif // ASM_INTERCEPTOR_TRAMPOLINE_SUPPORT
148*37445e96SMarco Elver
1499642e337SNico Weber } // namespace __interception
1509642e337SNico Weber
1519642e337SNico Weber #endif // SANITIZER_LINUX
152