Home | History | Annotate | Download | only in seccomp-bpf
      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/sandbox_bpf.h"
      6 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
      7 #include "sandbox/linux/tests/unit_tests.h"
      8 
      9 namespace sandbox {
     10 
     11 namespace {
     12 
     13 SANDBOX_TEST(SyscallIterator, Monotonous) {
     14   for (int i = 0; i < 2; ++i) {
     15     bool invalid_only = !i;  // Testing both |invalid_only| cases.
     16     SyscallIterator iter(invalid_only);
     17     uint32_t next = iter.Next();
     18 
     19     if (!invalid_only) {
     20       // The iterator should start at 0.
     21       SANDBOX_ASSERT(next == 0);
     22     }
     23     for (uint32_t last = next; !iter.Done(); last = next) {
     24       next = iter.Next();
     25       SANDBOX_ASSERT(last < next);
     26     }
     27     // The iterator should always return 0xFFFFFFFFu as the last value.
     28     SANDBOX_ASSERT(next == 0xFFFFFFFFu);
     29   }
     30 }
     31 
     32 SANDBOX_TEST(SyscallIterator, PublicSyscallRange) {
     33   SyscallIterator iter(false);
     34   uint32_t next = iter.Next();
     35 
     36   // The iterator should cover the public syscall range
     37   // MIN_SYSCALL..MAX_PUBLIC_SYSCALL, without skipping syscalls.
     38   // We're assuming MIN_SYSCALL == 0 for all architectures,
     39   // this is currently valid for Intel and ARM EABI.
     40   SANDBOX_ASSERT(MIN_SYSCALL == 0);
     41   SANDBOX_ASSERT(next == MIN_SYSCALL);
     42   for (uint32_t last = next; next < MAX_PUBLIC_SYSCALL + 1; last = next) {
     43     SANDBOX_ASSERT((next = iter.Next()) == last + 1);
     44   }
     45   SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1);
     46 }
     47 
     48 #if defined(__arm__)
     49 SANDBOX_TEST(SyscallIterator, ARMPrivateSyscallRange) {
     50   SyscallIterator iter(false);
     51   uint32_t next = iter.Next();
     52   while (next < MIN_PRIVATE_SYSCALL - 1) {
     53     next = iter.Next();
     54   }
     55   // The iterator should cover the ARM private syscall range
     56   // without skipping syscalls.
     57   SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1);
     58   for (uint32_t last = next; next < MAX_PRIVATE_SYSCALL + 1; last = next) {
     59     SANDBOX_ASSERT((next = iter.Next()) == last + 1);
     60   }
     61   SANDBOX_ASSERT(next == MAX_PRIVATE_SYSCALL + 1);
     62 }
     63 
     64 SANDBOX_TEST(SyscallIterator, ARMHiddenSyscallRange) {
     65   SyscallIterator iter(false);
     66   uint32_t next = iter.Next();
     67   while (next < MIN_GHOST_SYSCALL - 1) {
     68     next = iter.Next();
     69   }
     70   // The iterator should cover the ARM hidden syscall range
     71   // without skipping syscalls.
     72   SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1);
     73   for (uint32_t last = next; next < MAX_SYSCALL + 1; last = next) {
     74     SANDBOX_ASSERT((next = iter.Next()) == last + 1);
     75   }
     76   SANDBOX_ASSERT(next == MAX_SYSCALL + 1);
     77 }
     78 #endif
     79 
     80 SANDBOX_TEST(SyscallIterator, Invalid) {
     81   for (int i = 0; i < 2; ++i) {
     82     bool invalid_only = !i;  // Testing both |invalid_only| cases.
     83     SyscallIterator iter(invalid_only);
     84     uint32_t next = iter.Next();
     85 
     86     while (next < MAX_SYSCALL + 1) {
     87       next = iter.Next();
     88     }
     89 
     90     SANDBOX_ASSERT(next == MAX_SYSCALL + 1);
     91     while (next < 0x7FFFFFFFu) {
     92       next = iter.Next();
     93     }
     94 
     95     // The iterator should return the signed/unsigned corner cases.
     96     SANDBOX_ASSERT(next == 0x7FFFFFFFu);
     97     next = iter.Next();
     98     SANDBOX_ASSERT(next == 0x80000000u);
     99     SANDBOX_ASSERT(!iter.Done());
    100     next = iter.Next();
    101     SANDBOX_ASSERT(iter.Done());
    102     SANDBOX_ASSERT(next == 0xFFFFFFFFu);
    103   }
    104 }
    105 
    106 SANDBOX_TEST(SyscallIterator, InvalidOnly) {
    107   bool invalid_only = true;
    108   SyscallIterator iter(invalid_only);
    109   uint32_t next = iter.Next();
    110   // We're assuming MIN_SYSCALL == 0 for all architectures,
    111   // this is currently valid for Intel and ARM EABI.
    112   // First invalid syscall should then be |MAX_PUBLIC_SYSCALL + 1|.
    113   SANDBOX_ASSERT(MIN_SYSCALL == 0);
    114   SANDBOX_ASSERT(next == MAX_PUBLIC_SYSCALL + 1);
    115 
    116 #if defined(__arm__)
    117   next = iter.Next();
    118   // The iterator should skip until the last invalid syscall in this range.
    119   SANDBOX_ASSERT(next == MIN_PRIVATE_SYSCALL - 1);
    120   while (next <= MAX_PRIVATE_SYSCALL) {
    121     next = iter.Next();
    122   }
    123 
    124   next = iter.Next();
    125   // The iterator should skip until the last invalid syscall in this range.
    126   SANDBOX_ASSERT(next == MIN_GHOST_SYSCALL - 1);
    127   while (next <= MAX_SYSCALL) {
    128     next = iter.Next();
    129   }
    130   SANDBOX_ASSERT(next == MAX_SYSCALL + 1);
    131 #endif
    132 }
    133 
    134 }  // namespace
    135 
    136 }  // namespace sandbox
    137