//===-- sanitizer_ioctl_test.cc -------------------------------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // Tests for ioctl interceptor implementation in sanitizer_common. // //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_LINUX #include <linux/input.h> #include <vector> #include "interception/interception.h" #include "sanitizer_test_utils.h" #include "sanitizer_common/sanitizer_platform_limits_posix.h" #include "sanitizer_common/sanitizer_common.h" #include "gtest/gtest.h" using namespace __sanitizer; #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, sz) \ do { \ (void) ctx; \ (void) ptr; \ (void) sz; \ } while (0) #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sz) \ do { \ (void) ctx; \ (void) ptr; \ (void) sz; \ } while (0) #include "sanitizer_common/sanitizer_common_interceptors_ioctl.inc" static struct IoctlInit { IoctlInit() { ioctl_init(); // Avoid unused function warnings. (void)&ioctl_common_pre; (void)&ioctl_common_post; (void)&ioctl_decode; } } ioctl_static_initializer; TEST(SanitizerIoctl, Fixup) { EXPECT_EQ((unsigned)FIONBIO, ioctl_request_fixup(FIONBIO)); EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(0, 16))); EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 16))); EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 17))); EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(31, 16))); EXPECT_NE(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(32, 16))); EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(0))); EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(5))); EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(63))); EXPECT_NE(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(64))); EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(0))); EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(5))); EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(63))); EXPECT_NE(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(64))); const ioctl_desc *desc = ioctl_lookup(EVIOCGKEY(16)); EXPECT_NE((void *)0, desc); EXPECT_EQ(EVIOCGKEY(0), desc->req); } // Test decoding KVM ioctl numbers. TEST(SanitizerIoctl, KVM_GET_MP_STATE) { ioctl_desc desc; unsigned int desc_value = SANITIZER_MIPS ? 0x4004ae98U : 0x8004ae98U; bool res = ioctl_decode(desc_value, &desc); EXPECT_TRUE(res); EXPECT_EQ(ioctl_desc::WRITE, desc.type); EXPECT_EQ(4U, desc.size); } TEST(SanitizerIoctl, KVM_GET_LAPIC) { ioctl_desc desc; unsigned int desc_value = SANITIZER_MIPS ? 0x4400ae8eU : 0x8400ae8eU; bool res = ioctl_decode(desc_value, &desc); EXPECT_TRUE(res); EXPECT_EQ(ioctl_desc::WRITE, desc.type); EXPECT_EQ(1024U, desc.size); } TEST(SanitizerIoctl, KVM_GET_MSR_INDEX_LIST) { ioctl_desc desc; bool res = ioctl_decode(0xc004ae02U, &desc); EXPECT_TRUE(res); EXPECT_EQ(ioctl_desc::READWRITE, desc.type); EXPECT_EQ(4U, desc.size); } #endif // SANITIZER_LINUX