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

source code of compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cpp