// 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/seccomp-bpf/errorcode.h"

#include <errno.h>

#include "base/macros.h"
#include "sandbox/linux/bpf_dsl/bpf_dsl.h"
#include "sandbox/linux/bpf_dsl/policy.h"
#include "sandbox/linux/bpf_dsl/policy_compiler.h"
#include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
#include "sandbox/linux/seccomp-bpf/trap.h"
#include "sandbox/linux/tests/unit_tests.h"

namespace sandbox {

namespace {

class DummyPolicy : public bpf_dsl::Policy {
 public:
  DummyPolicy() {}
  ~DummyPolicy() override {}

  bpf_dsl::ResultExpr EvaluateSyscall(int sysno) const override {
    return bpf_dsl::Allow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(DummyPolicy);
};

SANDBOX_TEST(ErrorCode, ErrnoConstructor) {
  ErrorCode e0;
  SANDBOX_ASSERT(e0.err() == SECCOMP_RET_INVALID);

  ErrorCode e1(ErrorCode::ERR_ALLOWED);
  SANDBOX_ASSERT(e1.err() == SECCOMP_RET_ALLOW);

  ErrorCode e2(EPERM);
  SANDBOX_ASSERT(e2.err() == SECCOMP_RET_ERRNO + EPERM);

  DummyPolicy dummy_policy;
  bpf_dsl::PolicyCompiler compiler(&dummy_policy, Trap::Registry());
  ErrorCode e3 = compiler.Trap(NULL, NULL, true /* safe */);
  SANDBOX_ASSERT((e3.err() & SECCOMP_RET_ACTION)  == SECCOMP_RET_TRAP);

  uint16_t data = 0xdead;
  ErrorCode e4(ErrorCode::ERR_TRACE + data);
  SANDBOX_ASSERT(e4.err() == SECCOMP_RET_TRACE + data);
}

SANDBOX_DEATH_TEST(ErrorCode,
                   InvalidSeccompRetTrace,
                   DEATH_MESSAGE("Invalid use of ErrorCode object")) {
  // Should die if the trace data does not fit in 16 bits.
  ErrorCode e(ErrorCode::ERR_TRACE + (1 << 16));
}

SANDBOX_TEST(ErrorCode, Trap) {
  DummyPolicy dummy_policy;
  bpf_dsl::PolicyCompiler compiler(&dummy_policy, Trap::Registry());
  ErrorCode e0 = compiler.Trap(NULL, "a", true /* safe */);
  ErrorCode e1 = compiler.Trap(NULL, "b", true /* safe */);
  SANDBOX_ASSERT((e0.err() & SECCOMP_RET_DATA) + 1 ==
                 (e1.err() & SECCOMP_RET_DATA));

  ErrorCode e2 = compiler.Trap(NULL, "a", true /* safe */);
  SANDBOX_ASSERT((e0.err() & SECCOMP_RET_DATA) ==
                 (e2.err() & SECCOMP_RET_DATA));
}

SANDBOX_TEST(ErrorCode, Equals) {
  ErrorCode e1(ErrorCode::ERR_ALLOWED);
  ErrorCode e2(ErrorCode::ERR_ALLOWED);
  SANDBOX_ASSERT(e1.Equals(e1));
  SANDBOX_ASSERT(e1.Equals(e2));
  SANDBOX_ASSERT(e2.Equals(e1));

  ErrorCode e3(EPERM);
  SANDBOX_ASSERT(!e1.Equals(e3));

  DummyPolicy dummy_policy;
  bpf_dsl::PolicyCompiler compiler(&dummy_policy, Trap::Registry());
  ErrorCode e4 = compiler.Trap(NULL, "a", true /* safe */);
  ErrorCode e5 = compiler.Trap(NULL, "b", true /* safe */);
  ErrorCode e6 = compiler.Trap(NULL, "a", true /* safe */);
  SANDBOX_ASSERT(!e1.Equals(e4));
  SANDBOX_ASSERT(!e3.Equals(e4));
  SANDBOX_ASSERT(!e5.Equals(e4));
  SANDBOX_ASSERT( e6.Equals(e4));
}

SANDBOX_TEST(ErrorCode, LessThan) {
  ErrorCode e1(ErrorCode::ERR_ALLOWED);
  ErrorCode e2(ErrorCode::ERR_ALLOWED);
  SANDBOX_ASSERT(!e1.LessThan(e1));
  SANDBOX_ASSERT(!e1.LessThan(e2));
  SANDBOX_ASSERT(!e2.LessThan(e1));

  ErrorCode e3(EPERM);
  SANDBOX_ASSERT(!e1.LessThan(e3));
  SANDBOX_ASSERT( e3.LessThan(e1));

  DummyPolicy dummy_policy;
  bpf_dsl::PolicyCompiler compiler(&dummy_policy, Trap::Registry());
  ErrorCode e4 = compiler.Trap(NULL, "a", true /* safe */);
  ErrorCode e5 = compiler.Trap(NULL, "b", true /* safe */);
  ErrorCode e6 = compiler.Trap(NULL, "a", true /* safe */);
  SANDBOX_ASSERT(e1.LessThan(e4));
  SANDBOX_ASSERT(e3.LessThan(e4));
  SANDBOX_ASSERT(e4.LessThan(e5));
  SANDBOX_ASSERT(!e4.LessThan(e6));
  SANDBOX_ASSERT(!e6.LessThan(e4));
}

}  // namespace

}  // namespace sandbox
