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/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 
     12 namespace sandbox {
     13 
     14 namespace {
     15 
     16 SANDBOX_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__)
     36 SANDBOX_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
     53 SANDBOX_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__)
     71 SANDBOX_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 
     86 SANDBOX_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 
    102 SANDBOX_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__)
    129 SANDBOX_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 
    148 SANDBOX_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