Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / sandbox / linux / seccomp-bpf / bpf_tests_unittest.cc
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 #include "sandbox/linux/seccomp-bpf/bpf_tests.h"
6
7 #include <errno.h>
8 #include <sys/ptrace.h>
9 #include <sys/syscall.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "build/build_config.h"
16 #include "sandbox/linux/bpf_dsl/bpf_dsl.h"
17 #include "sandbox/linux/bpf_dsl/policy.h"
18 #include "sandbox/linux/seccomp-bpf/sandbox_bpf.h"
19 #include "sandbox/linux/services/linux_syscalls.h"
20 #include "sandbox/linux/tests/unit_tests.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 using sandbox::bpf_dsl::Allow;
24 using sandbox::bpf_dsl::Error;
25 using sandbox::bpf_dsl::ResultExpr;
26
27 namespace sandbox {
28
29 namespace {
30
31 class FourtyTwo {
32  public:
33   static const int kMagicValue = 42;
34   FourtyTwo() : value_(kMagicValue) {}
35   int value() { return value_; }
36
37  private:
38   int value_;
39   DISALLOW_COPY_AND_ASSIGN(FourtyTwo);
40 };
41
42 class EmptyClassTakingPolicy : public bpf_dsl::Policy {
43  public:
44   explicit EmptyClassTakingPolicy(FourtyTwo* fourty_two) {
45     BPF_ASSERT(fourty_two);
46     BPF_ASSERT(FourtyTwo::kMagicValue == fourty_two->value());
47   }
48   virtual ~EmptyClassTakingPolicy() {}
49
50   virtual ResultExpr EvaluateSyscall(int sysno) const override {
51     DCHECK(SandboxBPF::IsValidSyscallNumber(sysno));
52     return Allow();
53   }
54 };
55
56 BPF_TEST(BPFTest,
57          BPFAUXPointsToClass,
58          EmptyClassTakingPolicy,
59          FourtyTwo /* *BPF_AUX */) {
60   // BPF_AUX should point to an instance of FourtyTwo.
61   BPF_ASSERT(BPF_AUX);
62   BPF_ASSERT(FourtyTwo::kMagicValue == BPF_AUX->value());
63 }
64
65 void DummyTestFunction(FourtyTwo *fourty_two) {
66 }
67
68 TEST(BPFTest, BPFTesterCompatibilityDelegateLeakTest) {
69   // Don't do anything, simply gives dynamic tools an opportunity to detect
70   // leaks.
71   {
72     BPFTesterCompatibilityDelegate<EmptyClassTakingPolicy, FourtyTwo>
73         simple_delegate(DummyTestFunction);
74   }
75   {
76     // Test polymorphism.
77     scoped_ptr<BPFTesterDelegate> simple_delegate(
78         new BPFTesterCompatibilityDelegate<EmptyClassTakingPolicy, FourtyTwo>(
79             DummyTestFunction));
80   }
81 }
82
83 class EnosysPtracePolicy : public bpf_dsl::Policy {
84  public:
85   EnosysPtracePolicy() {
86     my_pid_ = syscall(__NR_getpid);
87   }
88   virtual ~EnosysPtracePolicy() {
89     // Policies should be able to bind with the process on which they are
90     // created. They should never be created in a parent process.
91     BPF_ASSERT_EQ(my_pid_, syscall(__NR_getpid));
92   }
93
94   virtual ResultExpr EvaluateSyscall(int system_call_number) const override {
95     CHECK(SandboxBPF::IsValidSyscallNumber(system_call_number));
96     if (system_call_number == __NR_ptrace) {
97       // The EvaluateSyscall function should run in the process that created
98       // the current object.
99       BPF_ASSERT_EQ(my_pid_, syscall(__NR_getpid));
100       return Error(ENOSYS);
101     } else {
102       return Allow();
103     }
104   }
105
106  private:
107   pid_t my_pid_;
108   DISALLOW_COPY_AND_ASSIGN(EnosysPtracePolicy);
109 };
110
111 class BasicBPFTesterDelegate : public BPFTesterDelegate {
112  public:
113   BasicBPFTesterDelegate() {}
114   virtual ~BasicBPFTesterDelegate() {}
115
116   virtual scoped_ptr<bpf_dsl::Policy> GetSandboxBPFPolicy() override {
117     return scoped_ptr<bpf_dsl::Policy>(new EnosysPtracePolicy());
118   }
119   virtual void RunTestFunction() override {
120     errno = 0;
121     int ret = ptrace(PTRACE_TRACEME, -1, NULL, NULL);
122     BPF_ASSERT(-1 == ret);
123     BPF_ASSERT(ENOSYS == errno);
124   }
125
126  private:
127   DISALLOW_COPY_AND_ASSIGN(BasicBPFTesterDelegate);
128 };
129
130 // This is the most powerful and complex way to create a BPF test, but it
131 // requires a full class definition (BasicBPFTesterDelegate).
132 BPF_TEST_D(BPFTest, BPFTestWithDelegateClass, BasicBPFTesterDelegate);
133
134 // This is the simplest form of BPF tests.
135 BPF_TEST_C(BPFTest, BPFTestWithInlineTest, EnosysPtracePolicy) {
136   errno = 0;
137   int ret = ptrace(PTRACE_TRACEME, -1, NULL, NULL);
138   BPF_ASSERT(-1 == ret);
139   BPF_ASSERT(ENOSYS == errno);
140 }
141
142 const char kHelloMessage[] = "Hello";
143
144 BPF_DEATH_TEST_C(BPFTest,
145                  BPFDeathTestWithInlineTest,
146                  DEATH_MESSAGE(kHelloMessage),
147                  EnosysPtracePolicy) {
148   LOG(ERROR) << kHelloMessage;
149   _exit(1);
150 }
151
152 }  // namespace
153
154 }  // namespace sandbox