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 26 using 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 43 static 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 53 TEST(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. 78 TEST(SanitizerIoctl, KVM_GET_MP_STATE) { 79 ioctl_desc desc; 80 unsigned int desc_value = SANITIZER_MIPS ? 0x4004ae98U : 0x8004ae98U; 81 bool res = ioctl_decode(desc_value, &desc); 82 EXPECT_TRUE(res); 83 EXPECT_EQ(ioctl_desc::WRITE, desc.type); 84 EXPECT_EQ(4U, desc.size); 85 } 86 87 TEST(SanitizerIoctl, KVM_GET_LAPIC) { 88 ioctl_desc desc; 89 unsigned int desc_value = SANITIZER_MIPS ? 0x4400ae8eU : 0x8400ae8eU; 90 bool res = ioctl_decode(desc_value, &desc); 91 EXPECT_TRUE(res); 92 EXPECT_EQ(ioctl_desc::WRITE, desc.type); 93 EXPECT_EQ(1024U, desc.size); 94 } 95 96 TEST(SanitizerIoctl, KVM_GET_MSR_INDEX_LIST) { 97 ioctl_desc desc; 98 bool res = ioctl_decode(0xc004ae02U, &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