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/sandbox_bpf.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/linux/seccomp-bpf/syscall_iterator.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/linux/tests/unit_tests.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace sandbox { 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, Monotonous) { 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool invalid_only = !i; // Testing both |invalid_only| cases. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(invalid_only); 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!invalid_only) { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should start at 0. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0); 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; !iter.Done(); last = next) { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(last < next); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should always return 0xFFFFFFFFu as the last value. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0xFFFFFFFFu); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, PublicSyscallRange) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(false); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should cover the public syscall range 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MIN_SYSCALL..MAX_PUBLIC_SYSCALL, without skipping syscalls. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're assuming MIN_SYSCALL == 0 for all architectures, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this is currently valid for Intel and ARM EABI. 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(MIN_SYSCALL == 0); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_SYSCALL); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; next < MAX_PUBLIC_SYSCALL + 1; last = next) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT((next = iter.Next()) == last + 1); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__arm__) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, ARMPrivateSyscallRange) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(false); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < MIN_PRIVATE_SYSCALL - 1) { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should cover the ARM private syscall range 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without skipping syscalls. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; next < MAX_PRIVATE_SYSCALL + 1; last = next) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT((next = iter.Next()) == last + 1); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_PRIVATE_SYSCALL + 1); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, ARMHiddenSyscallRange) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(false); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < MIN_GHOST_SYSCALL - 1) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should cover the ARM hidden syscall range 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without skipping syscalls. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (uint32_t last = next; next < MAX_SYSCALL + 1; last = next) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT((next = iter.Next()) == last + 1); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, Invalid) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool invalid_only = !i; // Testing both |invalid_only| cases. 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(invalid_only); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < MAX_SYSCALL + 1) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next < 0x7FFFFFFFu) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should return the signed/unsigned corner cases. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0x7FFFFFFFu); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0x80000000u); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(!iter.Done()); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(iter.Done()); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == 0xFFFFFFFFu); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_TEST(SyscallIterator, InvalidOnly) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool invalid_only = true; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyscallIterator iter(invalid_only); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t next = iter.Next(); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're assuming MIN_SYSCALL == 0 for all architectures, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this is currently valid for Intel and ARM EABI. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First invalid syscall should then be |MAX_PUBLIC_SYSCALL + 1|. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(MIN_SYSCALL == 0); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(__arm__) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should skip until the last invalid syscall in this range. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next <= MAX_PRIVATE_SYSCALL) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The iterator should skip until the last invalid syscall in this range. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (next <= MAX_SYSCALL) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = iter.Next(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SANDBOX_ASSERT(next == MAX_SYSCALL + 1); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace sandbox 137