1// Copyright 2017 The Fuchsia 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 <assert.h>
6#include <stdio.h>
7#include <threads.h>
8
9#include <lib/zx/channel.h>
10#include <lib/zx/event.h>
11#include <lib/zx/handle.h>
12#include <lib/zx/job.h>
13#include <lib/zx/port.h>
14#include <lib/zx/process.h>
15#include <lib/zx/thread.h>
16#include <lib/zx/vmar.h>
17
18#include <fbl/algorithm.h>
19#include <fbl/type_support.h>
20
21#include <zircon/process.h>
22#include <zircon/syscalls/debug.h>
23#include <zircon/syscalls/exception.h>
24#include <zircon/syscalls/policy.h>
25#include <zircon/syscalls/port.h>
26
27#include <mini-process/mini-process.h>
28
29#include <unistd.h>
30#include <unittest/unittest.h>
31
32static const unsigned kExceptionPortKey = 42u;
33
34// Basic job operation is tested by core-tests.
35static zx::job make_job() {
36    zx::job job;
37    if (zx::job::create(*zx::job::default_job(), 0u, &job) != ZX_OK)
38        return zx::job();
39    return job;
40}
41
42static zx::process make_test_process(const zx::job& job, zx::thread* out_thread,
43                                     zx_handle_t* ctrl) {
44    zx::vmar vmar;
45    zx::process proc;
46    zx_status_t status = zx::process::create(job, "poltst", 6u, 0u, &proc, &vmar);
47    if (status != ZX_OK)
48        return zx::process();
49
50    zx::thread thread;
51    status = zx::thread::create(proc, "poltst", 6u, 0, &thread);
52    if (status != ZX_OK)
53        return zx::process();
54    if (out_thread) {
55        status = thread.duplicate(ZX_RIGHT_SAME_RIGHTS, out_thread);
56        if (status != ZX_OK)
57            return zx::process();
58    }
59
60    zx::event event;
61    status = zx::event::create(0u, &event);
62    if (status != ZX_OK)
63        return zx::process();
64
65    auto thr = thread.release();
66    status = start_mini_process_etc(proc.get(), thr, vmar.get(), event.release(), ctrl);
67    if (status != ZX_OK)
68        return zx::process();
69
70    return proc;
71}
72
73static bool abs_then_rel() {
74    BEGIN_TEST;
75
76    zx_policy_basic_t policy[] = {
77        { ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL } };
78
79    auto job = make_job();
80    EXPECT_EQ(job.set_policy(
81        ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy, static_cast<uint32_t>(fbl::count_of(policy))), ZX_OK);
82
83    // A contradictory policy should fail.
84    policy[0].policy = ZX_POL_ACTION_EXCEPTION | ZX_POL_ACTION_DENY;
85    EXPECT_EQ(job.set_policy(
86        ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy, static_cast<uint32_t>(fbl::count_of(policy))), ZX_ERR_ALREADY_EXISTS);
87
88    // The same again will succeed.
89    policy[0].policy = ZX_POL_ACTION_KILL;
90    EXPECT_EQ(job.set_policy(
91        ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy, static_cast<uint32_t>(fbl::count_of(policy))), ZX_OK);
92
93    // A contradictory relative policy will succeed, but is a no-op
94    policy[0].policy = ZX_POL_ACTION_ALLOW;
95    EXPECT_EQ(job.set_policy(
96        ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, policy, static_cast<uint32_t>(fbl::count_of(policy))), ZX_OK);
97
98    zx_policy_basic_t more[] = {
99        { ZX_POL_NEW_CHANNEL, ZX_POL_ACTION_ALLOW | ZX_POL_ACTION_EXCEPTION },
100        { ZX_POL_NEW_FIFO, ZX_POL_ACTION_DENY } };
101
102    // An additional absolute policy that doesn't contradict existing
103    // policy can be added.
104    EXPECT_EQ(job.set_policy(
105        ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, more, static_cast<uint32_t>(fbl::count_of(more))), ZX_OK);
106
107    END_TEST;
108}
109
110static bool invalid_calls(uint32_t options) {
111    auto job = make_job();
112
113    EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, nullptr, 0u), ZX_ERR_INVALID_ARGS);
114
115    EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, nullptr, 5u), ZX_ERR_INVALID_ARGS);
116
117    zx_policy_basic_t policy1[] = {
118        { ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL },
119    };
120
121    EXPECT_EQ(job.set_policy(options, ZX_JOB_POL_BASIC, policy1, 0u), ZX_ERR_INVALID_ARGS);
122
123    zx_policy_basic_t policy2[] = {
124        { 100001u, ZX_POL_ACTION_KILL },
125    };
126
127    EXPECT_EQ(job.set_policy(
128        options, ZX_JOB_POL_BASIC, policy2, static_cast<uint32_t>(fbl::count_of(policy2))), ZX_ERR_INVALID_ARGS);
129
130    zx_policy_basic_t policy3[] = {
131        { ZX_POL_BAD_HANDLE, 100001u },
132    };
133
134    EXPECT_EQ(job.set_policy(
135        options, ZX_JOB_POL_BASIC, policy3, static_cast<uint32_t>(fbl::count_of(policy2))), ZX_ERR_NOT_SUPPORTED);
136
137    // The job will still accept a valid combination:
138    zx_policy_basic_t policy4[] = {
139        { ZX_POL_BAD_HANDLE, ZX_POL_ACTION_KILL } };
140
141    EXPECT_EQ(job.set_policy(
142        options, ZX_JOB_POL_BASIC, policy4, static_cast<uint32_t>(fbl::count_of(policy4))), ZX_OK);
143
144    return true;
145}
146
147static bool invalid_calls_abs() {
148    BEGIN_TEST;
149
150    invalid_calls(ZX_JOB_POL_ABSOLUTE);
151
152    END_TEST;
153}
154
155static bool invalid_calls_rel() {
156    BEGIN_TEST;
157
158    invalid_calls(ZX_JOB_POL_RELATIVE);
159
160    END_TEST;
161}
162
163// Test that executing the given mini-process.h command (|minip_cmd|)
164// produces the given result (|expect|) when the given policy is in force.
165static bool test_invoking_policy(
166    zx_policy_basic_t* pol, uint32_t pol_count, uint32_t minip_cmd, zx_status_t expect) {
167    auto job = make_job();
168    ASSERT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, pol, pol_count), ZX_OK);
169
170    zx_handle_t ctrl;
171    auto proc = make_test_process(job, nullptr, &ctrl);
172    ASSERT_TRUE(proc.is_valid());
173    ASSERT_NE(ctrl, ZX_HANDLE_INVALID);
174
175    zx_handle_t obj;
176    EXPECT_EQ(mini_process_cmd(ctrl, minip_cmd, &obj), expect);
177    EXPECT_EQ(mini_process_cmd(ctrl, MINIP_CMD_EXIT_NORMAL, nullptr), ZX_ERR_PEER_CLOSED);
178
179    zx_handle_close(ctrl);
180    return true;
181}
182
183static bool enforce_deny_event() {
184    BEGIN_TEST;
185
186    zx_policy_basic_t policy[] = { { ZX_POL_NEW_EVENT, ZX_POL_ACTION_DENY } };
187    test_invoking_policy(policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_EVENT,
188                         ZX_ERR_ACCESS_DENIED);
189
190    END_TEST;
191}
192
193static bool enforce_deny_channel() {
194    BEGIN_TEST;
195
196    zx_policy_basic_t policy[] = { { ZX_POL_NEW_CHANNEL, ZX_POL_ACTION_DENY } };
197    test_invoking_policy(policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_CHANNEL,
198                         ZX_ERR_ACCESS_DENIED);
199
200    END_TEST;
201}
202
203static bool enforce_deny_any() {
204    BEGIN_TEST;
205
206    zx_policy_basic_t policy[] = { { ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY } };
207    test_invoking_policy(policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_EVENT,
208                         ZX_ERR_ACCESS_DENIED);
209
210    END_TEST;
211}
212
213static bool enforce_allow_any() {
214    BEGIN_TEST;
215
216    zx_policy_basic_t policy[] = { { ZX_POL_NEW_ANY, ZX_POL_ACTION_ALLOW } };
217    test_invoking_policy(policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_EVENT,
218                         ZX_OK);
219
220    END_TEST;
221}
222
223static bool enforce_deny_but_event() {
224    BEGIN_TEST;
225
226    zx_policy_basic_t policy[] = {
227        { ZX_POL_NEW_ANY, ZX_POL_ACTION_DENY },
228        { ZX_POL_NEW_EVENT, ZX_POL_ACTION_ALLOW }
229    };
230    test_invoking_policy(policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_EVENT,
231                         ZX_OK);
232    test_invoking_policy(policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_CHANNEL,
233                         ZX_ERR_ACCESS_DENIED);
234
235    END_TEST;
236}
237
238static bool get_koid(zx_handle_t handle, zx_koid_t* koid) {
239    zx_info_handle_basic_t info;
240    ASSERT_EQ(zx_object_get_info(
241                  handle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info),
242                  nullptr, nullptr), ZX_OK);
243    *koid = info.koid;
244    return true;
245}
246
247#if defined(__x86_64__)
248
249static uint64_t get_syscall_result(zx_thread_state_general_regs_t* regs) {
250    return regs->rax;
251}
252
253#elif defined(__aarch64__)
254
255static uint64_t get_syscall_result(zx_thread_state_general_regs_t* regs) {
256    return regs->r[0];
257}
258
259#else
260# error Unsupported architecture
261#endif
262
263// Like test_invoking_policy(), this tests that executing the given
264// mini-process.h command produces the given result when the given policy
265// is in force.  In addition, it tests that a debug port exception gets
266// generated.
267static bool test_invoking_policy_with_exception(
268    zx_policy_basic_t* policy, uint32_t policy_count, uint32_t minip_cmd,
269    zx_status_t expected_syscall_result) {
270    auto job = make_job();
271    ASSERT_EQ(job.set_policy(ZX_JOB_POL_ABSOLUTE, ZX_JOB_POL_BASIC, policy,
272                             policy_count), ZX_OK);
273
274    zx_handle_t ctrl;
275    zx::thread thread;
276    auto proc = make_test_process(job, &thread, &ctrl);
277    ASSERT_TRUE(proc.is_valid());
278    ASSERT_NE(ctrl, ZX_HANDLE_INVALID);
279
280    zx_handle_t exc_port;
281    ASSERT_EQ(zx_port_create(0, &exc_port), ZX_OK);
282    ASSERT_EQ(zx_task_bind_exception_port(
283                  proc.get(), exc_port, kExceptionPortKey,
284                  ZX_EXCEPTION_PORT_DEBUGGER),
285              ZX_OK);
286
287    EXPECT_EQ(mini_process_cmd_send(ctrl, minip_cmd), ZX_OK);
288
289    // Check that the subprocess did not return a reply yet (indicating
290    // that it was suspended).
291    EXPECT_EQ(zx_object_wait_one(ctrl, ZX_CHANNEL_READABLE,
292                                 zx_deadline_after(ZX_MSEC(1)), nullptr),
293              ZX_ERR_TIMED_OUT);
294
295    // Check that we receive an exception message.
296    zx_port_packet_t packet;
297    ASSERT_EQ(zx_port_wait(exc_port, ZX_TIME_INFINITE, &packet), ZX_OK);
298
299    // Check the exception message contents.
300    ASSERT_EQ(packet.key, kExceptionPortKey);
301    ASSERT_EQ(packet.type, (uint32_t)ZX_EXCP_POLICY_ERROR);
302
303    zx_koid_t pid;
304    zx_koid_t tid;
305    ASSERT_TRUE(get_koid(proc.get(), &pid));
306    ASSERT_TRUE(get_koid(thread.get(), &tid));
307    ASSERT_EQ(packet.exception.pid, pid);
308    ASSERT_EQ(packet.exception.tid, tid);
309
310    // Check that we can read the thread's register state.
311    zx_thread_state_general_regs_t regs;
312    ASSERT_EQ(zx_thread_read_state(thread.get(), ZX_THREAD_STATE_GENERAL_REGS, &regs, sizeof(regs)),
313              ZX_OK);
314    ASSERT_EQ(get_syscall_result(&regs), (uint64_t)expected_syscall_result);
315    // TODO(mseaborn): Check the values of other registers.  We could check
316    // that rip/pc is within the VDSO, which will require figuring out
317    // where the VDSO is mapped.  We could check that unwinding the stack
318    // using crashlogger gives a correct backtrace.
319
320    // Resume the thread.
321    ASSERT_EQ(zx_task_resume(thread.get(), ZX_RESUME_EXCEPTION), ZX_OK);
322    // Check that the read-ready state of the channel changed compared with
323    // the earlier check.
324    EXPECT_EQ(zx_object_wait_one(ctrl, ZX_CHANNEL_READABLE, ZX_TIME_INFINITE,
325                                 nullptr),
326              ZX_OK);
327
328    // Check that we receive a reply message from the resumed thread.
329    zx_handle_t obj;
330    EXPECT_EQ(mini_process_cmd_read_reply(ctrl, &obj),
331              expected_syscall_result);
332    if (expected_syscall_result == ZX_OK)
333        EXPECT_EQ(zx_handle_close(obj), ZX_OK);
334
335    // Clean up: Tell the subprocess to exit.
336    EXPECT_EQ(mini_process_cmd(ctrl, MINIP_CMD_EXIT_NORMAL, nullptr),
337              ZX_ERR_PEER_CLOSED);
338
339    zx_handle_close(ctrl);
340
341    return true;
342}
343
344static bool test_exception_on_new_event_and_deny() {
345    BEGIN_TEST;
346
347    zx_policy_basic_t policy[] = {
348        { ZX_POL_NEW_EVENT, ZX_POL_ACTION_DENY | ZX_POL_ACTION_EXCEPTION },
349    };
350    test_invoking_policy_with_exception(
351        policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_EVENT, ZX_ERR_ACCESS_DENIED);
352
353    END_TEST;
354}
355
356static bool test_exception_on_new_event_but_allow() {
357    BEGIN_TEST;
358
359    zx_policy_basic_t policy[] = {
360        { ZX_POL_NEW_EVENT, ZX_POL_ACTION_ALLOW | ZX_POL_ACTION_EXCEPTION },
361    };
362    test_invoking_policy_with_exception(
363        policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_CREATE_EVENT, ZX_OK);
364
365    END_TEST;
366}
367
368// Test ZX_POL_BAD_HANDLE when syscalls are allowed to continue.
369static bool test_error_on_bad_handle() {
370    BEGIN_TEST;
371
372    // The ALLOW and DENY actions should be equivalent for ZX_POL_BAD_HANDLE.
373    uint32_t actions[] = { ZX_POL_ACTION_ALLOW, ZX_POL_ACTION_DENY };
374    for (uint32_t action : actions) {
375        unittest_printf_critical("Testing action=%d\n", action);
376        zx_policy_basic_t policy[] = {
377            { ZX_POL_BAD_HANDLE, action },
378        };
379        test_invoking_policy(
380            policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_USE_BAD_HANDLE_CLOSED,
381            ZX_ERR_BAD_HANDLE);
382        test_invoking_policy(
383            policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_USE_BAD_HANDLE_TRANSFERRED,
384            ZX_ERR_BAD_HANDLE);
385    }
386
387    END_TEST;
388}
389
390// Test ZX_POL_BAD_HANDLE with ZX_POL_ACTION_EXCEPTION.
391static bool test_exception_on_bad_handle() {
392    BEGIN_TEST;
393
394    // The ALLOW and DENY actions should be equivalent for ZX_POL_BAD_HANDLE.
395    uint32_t actions[] = { ZX_POL_ACTION_ALLOW, ZX_POL_ACTION_DENY };
396    for (uint32_t action : actions) {
397        unittest_printf_critical("Testing action=%d\n", action);
398        zx_policy_basic_t policy[] = {
399            { ZX_POL_BAD_HANDLE, action | ZX_POL_ACTION_EXCEPTION },
400        };
401        test_invoking_policy_with_exception(
402            policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_USE_BAD_HANDLE_CLOSED,
403            ZX_ERR_BAD_HANDLE);
404        test_invoking_policy_with_exception(
405            policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_USE_BAD_HANDLE_TRANSFERRED,
406            ZX_ERR_BAD_HANDLE);
407    }
408
409    END_TEST;
410}
411
412// The one exception for ZX_POL_BAD_HANDLE is zx_object_info( ZX_INFO_HANDLE_VALID).
413static bool test_get_info_on_bad_handle() {
414    BEGIN_TEST;
415
416    zx_policy_basic_t policy[] = {{
417        ZX_POL_BAD_HANDLE, ZX_POL_ACTION_DENY | ZX_POL_ACTION_EXCEPTION }};
418    test_invoking_policy(
419        policy, static_cast<uint32_t>(fbl::count_of(policy)), MINIP_CMD_VALIDATE_CLOSED_HANDLE,
420        ZX_ERR_BAD_HANDLE);
421
422    END_TEST;
423}
424
425BEGIN_TEST_CASE(job_policy)
426RUN_TEST(invalid_calls_abs)
427RUN_TEST(invalid_calls_rel)
428RUN_TEST(abs_then_rel)
429RUN_TEST(enforce_deny_event)
430RUN_TEST(enforce_deny_channel)
431RUN_TEST(enforce_deny_any)
432RUN_TEST(enforce_allow_any)
433RUN_TEST(enforce_deny_but_event)
434RUN_TEST(test_exception_on_new_event_and_deny)
435RUN_TEST(test_exception_on_new_event_but_allow)
436RUN_TEST(test_error_on_bad_handle)
437RUN_TEST(test_exception_on_bad_handle)
438RUN_TEST(test_get_info_on_bad_handle)
439END_TEST_CASE(job_policy)
440
441int main(int argc, char** argv) {
442    bool success = unittest_run_all_tests(argc, argv);
443    return success ? 0 : -1;
444}
445