]>
Commit | Line | Data |
---|---|---|
a39ff7e2 A |
1 | #include <darwintest.h> |
2 | ||
3 | #include <mach/mach_error.h> | |
4 | #include <mach/mach_host.h> | |
5 | ||
6 | T_GLOBAL_META(T_META_NAMESPACE("xnu.debugging")); | |
7 | ||
8 | /* | |
9 | * The low 8 bits may be in use, so modify one | |
0a7de745 | 10 | * of the upper 8 bits to ensure round-tripping. |
a39ff7e2 A |
11 | */ |
12 | #define LIBTRACE_PRIVATE_DATA 0x01000000 | |
13 | ||
14 | extern void drop_priv(void); | |
15 | ||
16 | static bool _needs_reset; | |
17 | static uint32_t _original; | |
18 | ||
19 | static uint32_t | |
20 | _save_atm_diagnostic_flag(void) | |
21 | { | |
0a7de745 A |
22 | kern_return_t kr; |
23 | kr = host_get_atm_diagnostic_flag(mach_host_self(), &_original); | |
24 | T_QUIET; T_ASSERT_MACH_SUCCESS(kr, "host_get_atm_diagnostic_flag()"); | |
25 | T_LOG("Original ATM diagnostic flag: 0x%08x", _original); | |
26 | return _original; | |
a39ff7e2 A |
27 | } |
28 | ||
29 | static kern_return_t | |
30 | _mutate_atm_diagnostic_flag(uint32_t v) | |
31 | { | |
0a7de745 A |
32 | T_LOG("Try to set ATM diagnostic flag to: 0x%08x", v); |
33 | kern_return_t kr = host_set_atm_diagnostic_flag(mach_host_self(), v); | |
34 | if (kr == KERN_SUCCESS) { | |
35 | _needs_reset = true; | |
36 | } | |
37 | return kr; | |
a39ff7e2 A |
38 | } |
39 | ||
40 | static void | |
41 | _reset_atm_diagnostic_flag(void) | |
42 | { | |
0a7de745 A |
43 | if (!_needs_reset) { |
44 | return; | |
45 | } | |
46 | T_LOG("Reset ATM diagnostic flag to: 0x%08x", _original); | |
47 | kern_return_t kr; | |
48 | kr = host_set_atm_diagnostic_flag(mach_host_self(), _original); | |
49 | if (kr != KERN_SUCCESS) { | |
50 | T_ASSERT_FAIL("host_set_atm_diagnostic_flag() failed: %s", | |
51 | mach_error_string(kr)); | |
52 | } | |
a39ff7e2 A |
53 | } |
54 | ||
c6bf4f31 A |
55 | static void |
56 | _toggle_atm_diagnostic_flag(void) | |
a39ff7e2 | 57 | { |
0a7de745 A |
58 | T_ATEND(_reset_atm_diagnostic_flag); |
59 | uint32_t f = _save_atm_diagnostic_flag(); | |
60 | f ^= LIBTRACE_PRIVATE_DATA; | |
61 | kern_return_t kr = _mutate_atm_diagnostic_flag(f); | |
62 | if (kr == KERN_NOT_SUPPORTED) { | |
63 | T_SKIP("Seems ATM is disabled on this platform. " | |
64 | "Ignoring host_set_atm_diagnostic_flag functionality. " | |
65 | "Bailing gracefully."); | |
66 | } | |
c6bf4f31 A |
67 | T_EXPECT_MACH_ERROR(KERN_NO_ACCESS, kr, |
68 | "Deny change to atm_diagnostic_flag"); | |
69 | } | |
70 | ||
71 | T_DECL(atm_diagnostic_flag_unentitled_privileged, | |
72 | "expect to fail to set the atm_diagnostic_flag (unentitled, privileged)", | |
73 | T_META_ASROOT(true)) | |
74 | { | |
75 | _toggle_atm_diagnostic_flag(); | |
a39ff7e2 A |
76 | } |
77 | ||
c6bf4f31 A |
78 | T_DECL(atm_diagnostic_flag_unentitled_unprivileged, |
79 | "expect to fail to set the atm_diagnostic_flag (unentitled, unprivileged)", | |
0a7de745 | 80 | T_META_ASROOT(false)) |
a39ff7e2 | 81 | { |
0a7de745 | 82 | drop_priv(); |
c6bf4f31 | 83 | _toggle_atm_diagnostic_flag(); |
a39ff7e2 | 84 | } |