// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "sandbox/linux/bpf_dsl/syscall_set.h"

#include <stddef.h>
#include <stdint.h>

#include "base/stl_util.h"
#include "sandbox/linux/bpf_dsl/linux_syscall_ranges.h"
#include "sandbox/linux/tests/unit_tests.h"

namespace sandbox {

namespace {

const SyscallSet kSyscallSets[] = {
    SyscallSet::All(),
    SyscallSet::InvalidOnly(),
};

SANDBOX_TEST(SyscallSet, Monotonous) {
  for (const SyscallSet& set : kSyscallSets) {
    uint32_t prev = 0;
    bool have_prev = false;
    for (uint32_t sysnum : set) {
      if (have_prev) {
        SANDBOX_ASSERT(sysnum > prev);
      } else if (set == SyscallSet::All()) {
        // The iterator should start at 0.
        SANDBOX_ASSERT(sysnum == 0);
      }

      prev = sysnum;
      have_prev = true;
    }

    // The iterator should always return 0xFFFFFFFFu as the last value.
    SANDBOX_ASSERT(have_prev);
    SANDBOX_ASSERT(prev == 0xFFFFFFFFu);
  }
}

// AssertRange checks that SyscallIterator produces all system call
// numbers in the inclusive range [min, max].
void AssertRange(uint32_t min, uint32_t max) {
  SANDBOX_ASSERT(min < max);
  uint32_t prev = min - 1;
  for (uint32_t sysnum : SyscallSet::All()) {
    if (sysnum >= min && sysnum <= max) {
      SANDBOX_ASSERT(prev == sysnum - 1);
      prev = sysnum;
    }
  }
  SANDBOX_ASSERT(prev == max);
}

SANDBOX_TEST(SyscallSet, ValidSyscallRanges) {
  AssertRange(MIN_SYSCALL, MAX_PUBLIC_SYSCALL);
#if defined(__arm__)
  AssertRange(MIN_PRIVATE_SYSCALL, MAX_PRIVATE_SYSCALL);
  AssertRange(MIN_GHOST_SYSCALL, MAX_SYSCALL);
#endif
}

SANDBOX_TEST(SyscallSet, InvalidSyscalls) {
  static const uint32_t kExpected[] = {
#if defined(__mips__)
    0,
    MIN_SYSCALL - 1,
#endif
    MAX_PUBLIC_SYSCALL + 1,
#if defined(__arm__)
    MIN_PRIVATE_SYSCALL - 1,
    MAX_PRIVATE_SYSCALL + 1,
    MIN_GHOST_SYSCALL - 1,
    MAX_SYSCALL + 1,
#endif
    0x7FFFFFFFu,
    0x80000000u,
    0xFFFFFFFFu,
  };

  for (const SyscallSet& set : kSyscallSets) {
    size_t i = 0;
    for (uint32_t sysnum : set) {
      if (!SyscallSet::IsValid(sysnum)) {
        SANDBOX_ASSERT(i < base::size(kExpected));
        SANDBOX_ASSERT(kExpected[i] == sysnum);
        ++i;
      }
    }
    SANDBOX_ASSERT(i == base::size(kExpected));
  }
}

SANDBOX_TEST(SyscallSet, ValidOnlyIsOnlyValid) {
  for (uint32_t sysnum : SyscallSet::ValidOnly()) {
    SANDBOX_ASSERT(SyscallSet::IsValid(sysnum));
  }
}

SANDBOX_TEST(SyscallSet, InvalidOnlyIsOnlyInvalid) {
  for (uint32_t sysnum : SyscallSet::InvalidOnly()) {
    SANDBOX_ASSERT(!SyscallSet::IsValid(sysnum));
  }
}

SANDBOX_TEST(SyscallSet, AllIsValidOnlyPlusInvalidOnly) {
  std::vector<uint32_t> merged;
  const SyscallSet valid_only = SyscallSet::ValidOnly();
  const SyscallSet invalid_only = SyscallSet::InvalidOnly();
  std::merge(valid_only.begin(),
             valid_only.end(),
             invalid_only.begin(),
             invalid_only.end(),
             std::back_inserter(merged));

  const SyscallSet all = SyscallSet::All();
  SANDBOX_ASSERT(merged == std::vector<uint32_t>(all.begin(), all.end()));
}

}  // namespace

}  // namespace sandbox
