diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index 31b65ca06152..69b7ca9eaa2e 100755 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -529,7 +529,7 @@ static bool ioctl_decode(unsigned req, ioctl_desc *desc) { desc->name = ""; desc->size = IOC_SIZE(req); // Sanity check. - if (desc->size > 1024) return false; + if (desc->size > 0xFFFF) return false; unsigned dir = IOC_DIR(req); switch (dir) { case IOC_NONE: @@ -547,10 +547,10 @@ static bool ioctl_decode(unsigned req, ioctl_desc *desc) { default: return false; } - if (desc->type != IOC_NONE && desc->size == 0) return false; - char id = IOC_TYPE(req); + // Size can be 0 iff type is NONE. + if ((desc->type == IOC_NONE) != (desc->size == 0)) return false; // Sanity check. - if (!(id >= 'a' && id <= 'z') && !(id >= 'A' && id <= 'Z')) return false; + if (IOC_TYPE(req) == 0) return false; return true; } diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc index 4a32af5c6cde..22fa5228dfbd 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc @@ -75,4 +75,29 @@ TEST(SanitizerIoctl, Fixup) { EXPECT_EQ(EVIOCGKEY(0), desc->req); } +// Test decoding KVM ioctl numbers. +TEST(SanitizerIoctl, KVM_GET_MP_STATE) { + ioctl_desc desc; + bool res = ioctl_decode(0x8004ae98U, &desc); + EXPECT_TRUE(res); + EXPECT_EQ(ioctl_desc::WRITE, desc.type); + EXPECT_EQ(4U, desc.size); +} + +TEST(SanitizerIoctl, KVM_GET_LAPIC) { + ioctl_desc desc; + bool res = ioctl_decode(0x8400ae8eU, &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