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
27using 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
44static struct IoctlInit {
45  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
54TEST(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.
79TEST(SanitizerIoctl, KVM_GET_MP_STATE) {
80  ioctl_desc desc;
81  bool res = ioctl_decode(0x8004ae98U, &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  bool res = ioctl_decode(0x8400ae8eU, &desc);
90  EXPECT_TRUE(res);
91  EXPECT_EQ(ioctl_desc::WRITE, desc.type);
92  EXPECT_EQ(1024U, desc.size);
93}
94
95TEST(SanitizerIoctl, KVM_GET_MSR_INDEX_LIST) {
96  ioctl_desc desc;
97  bool res = ioctl_decode(0xc004ae02U, &desc);
98  EXPECT_TRUE(res);
99  EXPECT_EQ(ioctl_desc::READWRITE, desc.type);
100  EXPECT_EQ(4U, desc.size);
101}
102
103#endif // SANITIZER_LINUX
104