1 //===-- sanitizer_ioctl_test.cc -------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Tests for ioctl interceptor implementation in sanitizer_common.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "sanitizer_common/sanitizer_platform.h"
15 #if SANITIZER_LINUX
16 
17 #include <linux/input.h>
18 #include <vector>
19 
20 #include "interception/interception.h"
21 #include "sanitizer_test_utils.h"
22 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
23 #include "sanitizer_common/sanitizer_common.h"
24 #include "gtest/gtest.h"
25 
26 
27 using namespace __sanitizer;
28 
29 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, sz) \
30   do {                                              \
31     (void) ctx;                                     \
32     (void) ptr;                                     \
33     (void) sz;                                      \
34   } while (0)
35 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sz) \
36   do {                                               \
37     (void) ctx;                                      \
38     (void) ptr;                                      \
39     (void) sz;                                       \
40   } while (0)
41 
42 #include "sanitizer_common/sanitizer_common_interceptors_ioctl.inc"
43 
44 static struct IoctlInit {
IoctlInitIoctlInit45   IoctlInit() {
46     ioctl_init();
47     // Avoid unused function warnings.
48     (void)&ioctl_common_pre;
49     (void)&ioctl_common_post;
50     (void)&ioctl_decode;
51   }
52 } ioctl_static_initializer;
53 
TEST(SanitizerIoctl,Fixup)54 TEST(SanitizerIoctl, Fixup) {
55   EXPECT_EQ((unsigned)FIONBIO, ioctl_request_fixup(FIONBIO));
56 
57   EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(0, 16)));
58   EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 16)));
59   EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 17)));
60   EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(31, 16)));
61   EXPECT_NE(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(32, 16)));
62 
63   EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(0)));
64   EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(5)));
65   EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(63)));
66   EXPECT_NE(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(64)));
67 
68   EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(0)));
69   EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(5)));
70   EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(63)));
71   EXPECT_NE(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(64)));
72 
73   const ioctl_desc *desc = ioctl_lookup(EVIOCGKEY(16));
74   EXPECT_NE((void *)0, desc);
75   EXPECT_EQ(EVIOCGKEY(0), desc->req);
76 }
77 
78 // Test decoding KVM ioctl numbers.
TEST(SanitizerIoctl,KVM_GET_MP_STATE)79 TEST(SanitizerIoctl, KVM_GET_MP_STATE) {
80   ioctl_desc desc;
81   unsigned int desc_value = SANITIZER_MIPS ? 0x4004ae98U : 0x8004ae98U;
82   bool res = ioctl_decode(desc_value, &desc);
83   EXPECT_TRUE(res);
84   EXPECT_EQ(ioctl_desc::WRITE, desc.type);
85   EXPECT_EQ(4U, desc.size);
86 }
87 
TEST(SanitizerIoctl,KVM_GET_LAPIC)88 TEST(SanitizerIoctl, KVM_GET_LAPIC) {
89   ioctl_desc desc;
90   unsigned int desc_value = SANITIZER_MIPS ? 0x4400ae8eU : 0x8400ae8eU;
91   bool res = ioctl_decode(desc_value, &desc);
92   EXPECT_TRUE(res);
93   EXPECT_EQ(ioctl_desc::WRITE, desc.type);
94   EXPECT_EQ(1024U, desc.size);
95 }
96 
TEST(SanitizerIoctl,KVM_GET_MSR_INDEX_LIST)97 TEST(SanitizerIoctl, KVM_GET_MSR_INDEX_LIST) {
98   ioctl_desc desc;
99   bool res = ioctl_decode(0xc004ae02U, &desc);
100   EXPECT_TRUE(res);
101   EXPECT_EQ(ioctl_desc::READWRITE, desc.type);
102   EXPECT_EQ(4U, desc.size);
103 }
104 
105 #endif // SANITIZER_LINUX
106