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

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

Issue 215173002: Linux Sandbox: fix BPF compiler bug (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add assertions. Created 6 years, 8 months 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 | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/seccomp-bpf/codegen.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <errno.h> 5 #include <errno.h>
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 // common code paths in the topo-sort algorithm. 136 // common code paths in the topo-sort algorithm.
137 // This also gives us a diamond-shaped pattern in our graph, which stresses 137 // This also gives us a diamond-shaped pattern in our graph, which stresses
138 // another aspect of the topo-sort algorithm (namely, the ability to 138 // another aspect of the topo-sort algorithm (namely, the ability to
139 // correctly count the incoming branches for subtrees that are not disjunct). 139 // correctly count the incoming branches for subtrees that are not disjunct).
140 Instruction *insn6 = codegen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, 42, 140 Instruction *insn6 = codegen->MakeInstruction(BPF_JMP+BPF_JEQ+BPF_K, 42,
141 insn5, insn4); 141 insn5, insn4);
142 142
143 return insn6; 143 return insn6;
144 } 144 }
145 145
146 Instruction* SampleProgramConfusingTails(CodeGen* codegen, int* flags) {
147 // This simple program demonstrates https://crbug.com/351103/
148 // The two "LOAD 0" instructions are blocks of their own. MergeTails() could
149 // be tempted to merge them since they are the same. However, they are
150 // not mergeable because they fall-through to non semantically equivalent
151 // blocks.
152 // Without the fix for this bug, this program should trigger the check in
153 // CompileAndCompare: the serialized graphs from the program and its compiled
154 // version will differ.
155 //
156 // 0) LOAD 1 // ???
157 // 1) if A == 0x1; then JMP 2 else JMP 3
158 // 2) LOAD 0 // System call number
159 // 3) if A == 0x2; then JMP 4 else JMP 5
160 // 4) LOAD 0 // System call number
161 // 5) if A == 0x1; then JMP 6 else JMP 7
162 // 6) RET 0x50000 // errno = 0
163 // 7) RET 0x50001 // errno = 1
164 *flags = NO_FLAGS;
165
166 Instruction* i7 = codegen->MakeInstruction(BPF_RET, ErrorCode(1));
167 Instruction* i6 = codegen->MakeInstruction(BPF_RET, ErrorCode(0));
168 Instruction* i5 =
169 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i6, i7);
170 Instruction* i4 = codegen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i5);
171 Instruction* i3 =
172 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5);
173 Instruction* i2 = codegen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i3);
174 Instruction* i1 =
175 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3);
176 Instruction* i0 = codegen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1);
177
178 return i0;
179 }
180
181 Instruction* SampleProgramConfusingTailsBasic(CodeGen* codegen, int* flags) {
182 // Without the fix for https://crbug.com/351103/, (see
183 // SampleProgramConfusingTails()), this would generate a cyclic graph and
184 // crash as the two "LOAD 0" instructions would get merged.
185 //
186 // 0) LOAD 1 // ???
187 // 1) if A == 0x1; then JMP 2 else JMP 3
188 // 2) LOAD 0 // System call number
189 // 3) if A == 0x2; then JMP 4 else JMP 5
190 // 4) LOAD 0 // System call number
191 // 5) RET 0x50001 // errno = 1
192 *flags = NO_FLAGS;
193
194 Instruction* i5 = codegen->MakeInstruction(BPF_RET, ErrorCode(1));
195 Instruction* i4 = codegen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i5);
196 Instruction* i3 =
197 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5);
198 Instruction* i2 = codegen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 0, i3);
199 Instruction* i1 =
200 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3);
201 Instruction* i0 = codegen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1);
202
203 return i0;
204 }
205
206 Instruction* SampleProgramConfusingTailsMergeable(CodeGen* codegen,
207 int* flags) {
208 // This is similar to SampleProgramConfusingTails(), except that
209 // instructions 2 and 4 are now RET instructions.
210 // In PointerCompare(), this exercises the path where two blocks are of the
211 // same length and identical and the last instruction is a JMP or RET, so the
212 // following blocks don't need to be looked at and the blocks are mergeable.
213 //
214 // 0) LOAD 1 // ???
215 // 1) if A == 0x1; then JMP 2 else JMP 3
216 // 2) RET 0x5002a // errno = 42
217 // 3) if A == 0x2; then JMP 4 else JMP 5
218 // 4) RET 0x5002a // errno = 42
219 // 5) if A == 0x1; then JMP 6 else JMP 7
220 // 6) RET 0x50000 // errno = 0
221 // 7) RET 0x50001 // errno = 1
222 *flags = HAS_MERGEABLE_TAILS;
223
224 Instruction* i7 = codegen->MakeInstruction(BPF_RET, ErrorCode(1));
225 Instruction* i6 = codegen->MakeInstruction(BPF_RET, ErrorCode(0));
226 Instruction* i5 =
227 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i6, i7);
228 Instruction* i4 = codegen->MakeInstruction(BPF_RET, ErrorCode(42));
229 Instruction* i3 =
230 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 2, i4, i5);
231 Instruction* i2 = codegen->MakeInstruction(BPF_RET, ErrorCode(42));
232 Instruction* i1 =
233 codegen->MakeInstruction(BPF_JMP + BPF_JEQ + BPF_K, 1, i2, i3);
234 Instruction* i0 = codegen->MakeInstruction(BPF_LD + BPF_W + BPF_ABS, 1, i1);
235
236 return i0;
237 }
238
146 void ForAllPrograms(void (*test)(CodeGenUnittestHelper *, Instruction *, int)){ 239 void ForAllPrograms(void (*test)(CodeGenUnittestHelper *, Instruction *, int)){
147 Instruction *(*function_table[])(CodeGen *codegen, int *flags) = { 240 Instruction *(*function_table[])(CodeGen *codegen, int *flags) = {
148 SampleProgramOneInstruction, 241 SampleProgramOneInstruction,
149 SampleProgramSimpleBranch, 242 SampleProgramSimpleBranch,
150 SampleProgramAtypicalBranch, 243 SampleProgramAtypicalBranch,
151 SampleProgramComplex, 244 SampleProgramComplex,
245 SampleProgramConfusingTails,
246 SampleProgramConfusingTailsBasic,
247 SampleProgramConfusingTailsMergeable,
152 }; 248 };
153 249
154 for (size_t i = 0; i < arraysize(function_table); ++i) { 250 for (size_t i = 0; i < arraysize(function_table); ++i) {
155 CodeGenUnittestHelper codegen; 251 CodeGenUnittestHelper codegen;
156 int flags = NO_FLAGS; 252 int flags = NO_FLAGS;
157 Instruction *prg = function_table[i](&codegen, &flags); 253 Instruction *prg = function_table[i](&codegen, &flags);
158 test(&codegen, prg, flags); 254 test(&codegen, prg, flags);
159 } 255 }
160 } 256 }
161 257
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 assembly.append(reinterpret_cast<char *>(&insn.k), sizeof(insn.k)); 534 assembly.append(reinterpret_cast<char *>(&insn.k), sizeof(insn.k));
439 } 535 }
440 SANDBOX_ASSERT(source == assembly); 536 SANDBOX_ASSERT(source == assembly);
441 } 537 }
442 538
443 SANDBOX_TEST(CodeGen, All) { 539 SANDBOX_TEST(CodeGen, All) {
444 ForAllPrograms(CompileAndCompare); 540 ForAllPrograms(CompileAndCompare);
445 } 541 }
446 542
447 } // namespace sandbox 543 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp-bpf/codegen.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698