1// Copyright (c) 2012 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/syscall_iterator.h" 6 7#include <stdint.h> 8 9#include "sandbox/linux/seccomp-bpf/linux_seccomp.h" 10#include "sandbox/linux/tests/unit_tests.h" 11 12namespace sandbox { 13 14namespace { 15 16SANDBOX_TEST(SyscallIterator, Monotonous) { 17 for (int i = 0; i < 2; ++i) { 18 bool invalid_only = !i; // Testing both |invalid_only| cases. 19 SyscallIterator iter(invalid_only); 20 uint32_t next = iter.Next(); 21 22 if (!invalid_only) { 23 // The iterator should start at 0. 24 SANDBOX_ASSERT(next == 0); 25 } 26 for (uint32_t last = next; !iter.Done(); last = next) { 27 next = iter.Next(); 28 SANDBOX_ASSERT(last < next); 29 } 30 // The iterator should always return 0xFFFFFFFFu as the last value. 31 SANDBOX_ASSERT(next == 0xFFFFFFFFu); 32 } 33} 34 35#if defined(__mips__) 36SANDBOX_TEST(SyscallIterator, PublicSyscallRangeMIPS) { 37 SyscallIterator iter(false); 38 uint32_t next = iter.Next(); 39 SANDBOX_ASSERT(next == 0); 40 41 // Since on MIPS MIN_SYSCALL != 0 we need to move iterator to valid range. 42 next = iter.Next(); 43 SANDBOX_ASSERT(next == MIN_SYSCALL - 1); 44 45 // The iterator should cover the public syscall range 46 // MIN_SYSCALL..MAX_PUBLIC_SYSCALL, without skipping syscalls. 47 for (uint32_t last = next; next < MAX_PUBLIC_SYSCALL + 1; last = next) { 48 SANDBOX_ASSERT((next = iter.Next()) == last + 1); 49 } 50 SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 51} 52#else 53SANDBOX_TEST(SyscallIterator, PublicSyscallRangeIntelArm) { 54 SyscallIterator iter(false); 55 uint32_t next = iter.Next(); 56 57 // The iterator should cover the public syscall range 58 // MIN_SYSCALL..MAX_PUBLIC_SYSCALL, without skipping syscalls. 59 // We're assuming MIN_SYSCALL == 0 for all architectures, 60 // this is currently valid for Intel and ARM EABI. 61 SANDBOX_ASSERT(MIN_SYSCALL == 0); 62 SANDBOX_ASSERT(next == MIN_SYSCALL); 63 for (uint32_t last = next; next < MAX_PUBLIC_SYSCALL + 1; last = next) { 64 SANDBOX_ASSERT((next = iter.Next()) == last + 1); 65 } 66 SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 67} 68#endif // defined(__mips__) 69 70#if defined(__arm__) 71SANDBOX_TEST(SyscallIterator, ARMPrivateSyscallRange) { 72 SyscallIterator iter(false); 73 uint32_t next = iter.Next(); 74 while (next < MIN_PRIVATE_SYSCALL - 1) { 75 next = iter.Next(); 76 } 77 // The iterator should cover the ARM private syscall range 78 // without skipping syscalls. 79 SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1); 80 for (uint32_t last = next; next < MAX_PRIVATE_SYSCALL + 1; last = next) { 81 SANDBOX_ASSERT((next = iter.Next()) == last + 1); 82 } 83 SANDBOX_ASSERT(next == MAX_PRIVATE_SYSCALL + 1); 84} 85 86SANDBOX_TEST(SyscallIterator, ARMHiddenSyscallRange) { 87 SyscallIterator iter(false); 88 uint32_t next = iter.Next(); 89 while (next < MIN_GHOST_SYSCALL - 1) { 90 next = iter.Next(); 91 } 92 // The iterator should cover the ARM hidden syscall range 93 // without skipping syscalls. 94 SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1); 95 for (uint32_t last = next; next < MAX_SYSCALL + 1; last = next) { 96 SANDBOX_ASSERT((next = iter.Next()) == last + 1); 97 } 98 SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 99} 100#endif 101 102SANDBOX_TEST(SyscallIterator, Invalid) { 103 for (int i = 0; i < 2; ++i) { 104 bool invalid_only = !i; // Testing both |invalid_only| cases. 105 SyscallIterator iter(invalid_only); 106 uint32_t next = iter.Next(); 107 108 while (next < MAX_SYSCALL + 1) { 109 next = iter.Next(); 110 } 111 112 SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 113 while (next < 0x7FFFFFFFu) { 114 next = iter.Next(); 115 } 116 117 // The iterator should return the signed/unsigned corner cases. 118 SANDBOX_ASSERT(next == 0x7FFFFFFFu); 119 next = iter.Next(); 120 SANDBOX_ASSERT(next == 0x80000000u); 121 SANDBOX_ASSERT(!iter.Done()); 122 next = iter.Next(); 123 SANDBOX_ASSERT(iter.Done()); 124 SANDBOX_ASSERT(next == 0xFFFFFFFFu); 125 } 126} 127 128#if defined(__mips__) 129SANDBOX_TEST(SyscallIterator, InvalidOnlyMIPS) { 130 bool invalid_only = true; 131 SyscallIterator iter(invalid_only); 132 uint32_t next = iter.Next(); 133 SANDBOX_ASSERT(next == 0); 134 // For Mips O32 ABI we're assuming MIN_SYSCALL == 4000. 135 SANDBOX_ASSERT(MIN_SYSCALL == 4000); 136 137 // Since on MIPS MIN_SYSCALL != 0, we need to move iterator to valid range 138 // The iterator should skip until the last invalid syscall in this range. 139 next = iter.Next(); 140 SANDBOX_ASSERT(next == MIN_SYSCALL - 1); 141 next = iter.Next(); 142 // First next invalid syscall should then be |MAX_PUBLIC_SYSCALL + 1|. 143 SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 144} 145 146#else 147 148SANDBOX_TEST(SyscallIterator, InvalidOnlyIntelArm) { 149 bool invalid_only = true; 150 SyscallIterator iter(invalid_only); 151 uint32_t next = iter.Next(); 152 // We're assuming MIN_SYSCALL == 0 for all architectures, 153 // this is currently valid for Intel and ARM EABI. 154 // First invalid syscall should then be |MAX_PUBLIC_SYSCALL + 1|. 155 SANDBOX_ASSERT(MIN_SYSCALL == 0); 156 SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 157 158#if defined(__arm__) 159 next = iter.Next(); 160 // The iterator should skip until the last invalid syscall in this range. 161 SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1); 162 while (next <= MAX_PRIVATE_SYSCALL) { 163 next = iter.Next(); 164 } 165 166 next = iter.Next(); 167 // The iterator should skip until the last invalid syscall in this range. 168 SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1); 169 while (next <= MAX_SYSCALL) { 170 next = iter.Next(); 171 } 172 SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 173#endif // defined(__arm__) 174} 175#endif // defined(__mips__) 176 177} // namespace 178 179} // namespace sandbox 180