reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
//===-- sanitizer_ioctl_test.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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