bpf_tester_compatibility_delegate.h revision 010d83a9304c5a91596085d917d248abff47903a
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
6#define SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
7
8#include <fcntl.h>
9#include <sys/stat.h>
10#include <sys/types.h>
11
12#include "base/memory/scoped_ptr.h"
13#include "sandbox/linux/seccomp-bpf/sandbox_bpf_compatibility_policy.h"
14#include "sandbox/linux/seccomp-bpf/sandbox_bpf_test_runner.h"
15#include "sandbox/linux/tests/sandbox_test_runner.h"
16#include "sandbox/linux/tests/unit_tests.h"
17
18namespace sandbox {
19
20// This templated class allows building a BPFTesterDelegate from a
21// deprecated-style BPF policy (that is a SyscallEvaluator function pointer,
22// instead of a SandboxBPFPolicy class), specified in |policy_function| and a
23// function pointer to a test in |test_function|.
24// This allows both the policy and the test function to take a pointer to an
25// object of type "Aux" as a parameter. This is used to implement the BPF_TEST
26// macro and should generally not be used directly.
27template <class Aux = void>
28class BPFTesterCompatibilityDelegate : public BPFTesterDelegate {
29 public:
30  typedef Aux AuxType;
31  BPFTesterCompatibilityDelegate(
32      void (*test_function)(AuxType*),
33      typename CompatibilityPolicy<AuxType>::SyscallEvaluator policy_function)
34      : aux_pointer_for_policy_(NULL),
35        test_function_(test_function),
36        policy_function_(policy_function) {
37    // This will be NULL iff AuxType is void.
38    aux_pointer_for_policy_ = NewAux();
39  }
40
41  virtual ~BPFTesterCompatibilityDelegate() {
42    DeleteAux(aux_pointer_for_policy_);
43  }
44
45  virtual scoped_ptr<SandboxBPFPolicy> GetSandboxBPFPolicy() OVERRIDE {
46    // The current method is guaranteed to only run in the child process
47    // running the test. In this process, the current object is guaranteed
48    // to live forever. So it's ok to pass aux_pointer_for_policy_ to
49    // the policy, which could in turn pass it to the kernel via Trap().
50    return scoped_ptr<SandboxBPFPolicy>(new CompatibilityPolicy<AuxType>(
51        policy_function_, aux_pointer_for_policy_));
52  }
53
54  virtual void RunTestFunction() OVERRIDE {
55    // Run the actual test.
56    // The current object is guaranteed to live forever in the child process
57    // where this will run.
58    test_function_(aux_pointer_for_policy_);
59  }
60
61 private:
62  // Allocate an object of type Aux. This is specialized to return NULL when
63  // trying to allocate a void.
64  static Aux* NewAux() { return new Aux(); }
65  static void DeleteAux(Aux* aux) { delete aux; }
66
67  AuxType* aux_pointer_for_policy_;
68  void (*test_function_)(AuxType*);
69  typename CompatibilityPolicy<AuxType>::SyscallEvaluator policy_function_;
70  DISALLOW_COPY_AND_ASSIGN(BPFTesterCompatibilityDelegate);
71};
72
73// Specialization of NewAux that returns NULL;
74template <>
75void* BPFTesterCompatibilityDelegate<void>::NewAux();
76template <>
77void BPFTesterCompatibilityDelegate<void>::DeleteAux(void* aux);
78
79}  // namespace sandbox
80
81#endif  // SANDBOX_LINUX_SECCOMP_BPF_BPF_TESTER_COMPATIBILITY_DELEGATE_H_
82