15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/linux/seccomp-bpf/syscall_iterator.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <stdint.h> 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "sandbox/linux/seccomp-bpf/linux_seccomp.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/linux/tests/unit_tests.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace sandbox { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, Monotonous) { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool invalid_only = !i; // Testing both |invalid_only| cases. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(invalid_only); 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!invalid_only) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should start at 0. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; !iter.Done(); last = next) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(last < next); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should always return 0xFFFFFFFFu as the last value. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0xFFFFFFFFu); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(__mips__) 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SANDBOX_TEST(SyscallIterator, PublicSyscallRangeMIPS) { 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SyscallIterator iter(false); 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32_t next = iter.Next(); 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT(next == 0); 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Since on MIPS MIN_SYSCALL != 0 we need to move iterator to valid range. 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next = iter.Next(); 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT(next == MIN_SYSCALL - 1); 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The iterator should cover the public syscall range 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // MIN_SYSCALL..MAX_PUBLIC_SYSCALL, without skipping syscalls. 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (uint32_t last = next; next < MAX_PUBLIC_SYSCALL + 1; last = next) { 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT((next = iter.Next()) == last + 1); 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SANDBOX_TEST(SyscallIterator, PublicSyscallRangeIntelArm) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(false); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should cover the public syscall range 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MIN_SYSCALL..MAX_PUBLIC_SYSCALL, without skipping syscalls. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're assuming MIN_SYSCALL == 0 for all architectures, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this is currently valid for Intel and ARM EABI. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(MIN_SYSCALL == 0); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_SYSCALL); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; next < MAX_PUBLIC_SYSCALL + 1; last = next) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT((next = iter.Next()) == last + 1); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif // defined(__mips__) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__arm__) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, ARMPrivateSyscallRange) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(false); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < MIN_PRIVATE_SYSCALL - 1) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should cover the ARM private syscall range 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without skipping syscalls. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; next < MAX_PRIVATE_SYSCALL + 1; last = next) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT((next = iter.Next()) == last + 1); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_PRIVATE_SYSCALL + 1); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, ARMHiddenSyscallRange) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(false); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < MIN_GHOST_SYSCALL - 1) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should cover the ARM hidden syscall range 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without skipping syscalls. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; next < MAX_SYSCALL + 1; last = next) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT((next = iter.Next()) == last + 1); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, Invalid) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool invalid_only = !i; // Testing both |invalid_only| cases. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(invalid_only); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < MAX_SYSCALL + 1) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < 0x7FFFFFFFu) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should return the signed/unsigned corner cases. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0x7FFFFFFFu); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0x80000000u); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(!iter.Done()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(iter.Done()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0xFFFFFFFFu); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(__mips__) 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SANDBOX_TEST(SyscallIterator, InvalidOnlyMIPS) { 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool invalid_only = true; 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SyscallIterator iter(invalid_only); 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) uint32_t next = iter.Next(); 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT(next == 0); 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // For Mips O32 ABI we're assuming MIN_SYSCALL == 4000. 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT(MIN_SYSCALL == 4000); 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Since on MIPS MIN_SYSCALL != 0, we need to move iterator to valid range 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The iterator should skip until the last invalid syscall in this range. 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next = iter.Next(); 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT(next == MIN_SYSCALL - 1); 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next = iter.Next(); 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // First next invalid syscall should then be |MAX_PUBLIC_SYSCALL + 1|. 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)SANDBOX_TEST(SyscallIterator, InvalidOnlyIntelArm) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool invalid_only = true; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(invalid_only); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're assuming MIN_SYSCALL == 0 for all architectures, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this is currently valid for Intel and ARM EABI. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First invalid syscall should then be |MAX_PUBLIC_SYSCALL + 1|. 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(MIN_SYSCALL == 0); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__arm__) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should skip until the last invalid syscall in this range. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next <= MAX_PRIVATE_SYSCALL) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should skip until the last invalid syscall in this range. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next <= MAX_SYSCALL) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif // defined(__arm__) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif // defined(__mips__) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace sandbox 180