Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: sandbox/linux/seccomp-bpf/syscall_iterator.cc

Issue 659723002: SyscallIterator: support C++11 range-based for loops (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sync and fix style Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h" 5 #include "sandbox/linux/seccomp-bpf/syscall_iterator.h"
6 6
7 #include "base/logging.h"
7 #include "base/macros.h" 8 #include "base/macros.h"
8 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h" 9 #include "sandbox/linux/seccomp-bpf/linux_seccomp.h"
9 10
10 namespace sandbox { 11 namespace sandbox {
11 12
12 namespace { 13 namespace {
13 14
14 #if defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32) 15 #if defined(__mips__) && (_MIPS_SIM == _MIPS_SIM_ABI32)
15 // This is true for Mips O32 ABI. 16 // This is true for Mips O32 ABI.
16 COMPILE_ASSERT(MIN_SYSCALL == __NR_Linux, min_syscall_should_be_4000); 17 COMPILE_ASSERT(MIN_SYSCALL == __NR_Linux, min_syscall_should_be_4000);
(...skipping 14 matching lines...) Expand all
31 {MIN_SYSCALL, MAX_PUBLIC_SYSCALL}, 32 {MIN_SYSCALL, MAX_PUBLIC_SYSCALL},
32 #if defined(__arm__) 33 #if defined(__arm__)
33 // ARM EABI includes "ARM private" system calls starting at 34 // ARM EABI includes "ARM private" system calls starting at
34 // MIN_PRIVATE_SYSCALL, and a "ghost syscall private to the kernel" at 35 // MIN_PRIVATE_SYSCALL, and a "ghost syscall private to the kernel" at
35 // MIN_GHOST_SYSCALL. 36 // MIN_GHOST_SYSCALL.
36 {MIN_PRIVATE_SYSCALL, MAX_PRIVATE_SYSCALL}, 37 {MIN_PRIVATE_SYSCALL, MAX_PRIVATE_SYSCALL},
37 {MIN_GHOST_SYSCALL, MAX_SYSCALL}, 38 {MIN_GHOST_SYSCALL, MAX_SYSCALL},
38 #endif 39 #endif
39 }; 40 };
40 41
41 uint32_t NextSyscall(uint32_t cur, bool invalid_only) { 42 // NextSyscall returns the next system call in the specified system
43 // call set after |cur|, or 0 if no such system call exists.
44 uint32_t NextSyscall(uint32_t cur, SyscallSet set) {
42 for (const SyscallRange& range : kValidSyscallRanges) { 45 for (const SyscallRange& range : kValidSyscallRanges) {
43 if (range.first > 0 && cur < range.first - 1) { 46 if (range.first > 0 && cur < range.first - 1) {
44 return range.first - 1; 47 return range.first - 1;
45 } 48 }
46 if (cur <= range.last) { 49 if (cur <= range.last) {
47 if (invalid_only && cur < range.last) { 50 if (set == SyscallSet::INVALID_ONLY) {
48 return range.last; 51 return range.last + 1;
49 } 52 }
50 return cur + 1; 53 return cur + 1;
51 } 54 }
52 } 55 }
53 56
54 // BPF programs only ever operate on unsigned quantities. So, that's how 57 // BPF programs only ever operate on unsigned quantities. So, that's how
55 // we iterate; we return values from 0..0xFFFFFFFFu. But there are places, 58 // we iterate; we return values from 0..0xFFFFFFFFu. But there are places,
56 // where the kernel might interpret system call numbers as signed 59 // where the kernel might interpret system call numbers as signed
57 // quantities, so the boundaries between signed and unsigned values are 60 // quantities, so the boundaries between signed and unsigned values are
58 // potential problem cases. We want to explicitly return these values from 61 // potential problem cases. We want to explicitly return these values from
59 // our iterator. 62 // our iterator.
60 if (cur < 0x7FFFFFFFu) 63 if (cur < 0x7FFFFFFFu)
61 return 0x7FFFFFFFu; 64 return 0x7FFFFFFFu;
62 if (cur < 0x80000000u) 65 if (cur < 0x80000000u)
63 return 0x80000000u; 66 return 0x80000000u;
64 67
65 return 0xFFFFFFFFu; 68 if (cur < 0xFFFFFFFFu)
69 return 0xFFFFFFFFu;
70 return 0;
66 } 71 }
67 72
68 } // namespace 73 } // namespace
69 74
70 uint32_t SyscallIterator::Next() { 75 SyscallIterator begin(SyscallSet set) {
71 if (done_) { 76 return SyscallIterator(set, false);
72 return num_; 77 }
78
79 SyscallIterator end(SyscallSet set) {
80 return SyscallIterator(set, true);
81 }
82
83 SyscallIterator::SyscallIterator(SyscallSet set, bool done)
84 : set_(set), done_(done), num_(0) {
85 if (set_ == SyscallSet::INVALID_ONLY && !done_ && IsValid(num_)) {
86 ++*this;
87 }
88 }
89
90 uint32_t SyscallIterator::operator*() const {
91 DCHECK(!done_);
92 return num_;
93 }
94
95 SyscallIterator& SyscallIterator::operator++() {
96 DCHECK(!done_);
97
98 num_ = NextSyscall(num_, set_);
99 if (num_ == 0) {
100 done_ = true;
73 } 101 }
74 102
75 uint32_t val; 103 return *this;
76 do {
77 val = num_;
78 num_ = NextSyscall(num_, invalid_only_);
79 } while (invalid_only_ && IsValid(val));
80
81 done_ |= val == 0xFFFFFFFFu;
82 return val;
83 } 104 }
84 105
85 bool SyscallIterator::IsValid(uint32_t num) { 106 bool SyscallIterator::IsValid(uint32_t num) {
86 for (const SyscallRange& range : kValidSyscallRanges) { 107 for (const SyscallRange& range : kValidSyscallRanges) {
87 if (num >= range.first && num <= range.last) { 108 if (num >= range.first && num <= range.last) {
88 return true; 109 return true;
89 } 110 }
90 } 111 }
91 return false; 112 return false;
92 } 113 }
93 114
115 bool operator==(const SyscallIterator& lhs, const SyscallIterator& rhs) {
116 DCHECK(lhs.set_ == rhs.set_);
117 return (lhs.done_ == rhs.done_) && (lhs.num_ == rhs.num_);
118 }
119
120 bool operator!=(const SyscallIterator& lhs, const SyscallIterator& rhs) {
121 return !(lhs == rhs);
122 }
123
94 } // namespace sandbox 124 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698