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

Side by Side Diff: sandbox/linux/seccomp-bpf/codegen.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, 9 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 | « no previous file | sandbox/linux/seccomp-bpf/codegen_unittest.cc » ('j') | 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 <stdio.h> 5 #include <stdio.h>
6 6
7 #include "base/logging.h"
7 #include "sandbox/linux/seccomp-bpf/codegen.h" 8 #include "sandbox/linux/seccomp-bpf/codegen.h"
8 9
9 namespace { 10 namespace {
10 11
11 // Helper function for Traverse(). 12 // Helper function for Traverse().
12 void TraverseRecursively(std::set<sandbox::Instruction*>* visited, 13 void TraverseRecursively(std::set<sandbox::Instruction*>* visited,
13 sandbox::Instruction* instruction) { 14 sandbox::Instruction* instruction) {
14 if (visited->find(instruction) == visited->end()) { 15 if (visited->find(instruction) == visited->end()) {
15 visited->insert(instruction); 16 visited->insert(instruction);
16 switch (BPF_CLASS(instruction->code)) { 17 switch (BPF_CLASS(instruction->code)) {
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 // Return <0, 0, or >0 depending on the ordering of "block1" and "block2". 426 // Return <0, 0, or >0 depending on the ordering of "block1" and "block2".
426 // If we are looking at the exact same block, this is trivial and we don't 427 // If we are looking at the exact same block, this is trivial and we don't
427 // need to do a full comparison. 428 // need to do a full comparison.
428 if (block1 == block2) { 429 if (block1 == block2) {
429 return 0; 430 return 0;
430 } 431 }
431 432
432 // We compare the sequence of instructions in both basic blocks. 433 // We compare the sequence of instructions in both basic blocks.
433 const Instructions& insns1 = block1->instructions; 434 const Instructions& insns1 = block1->instructions;
434 const Instructions& insns2 = block2->instructions; 435 const Instructions& insns2 = block2->instructions;
436 // Basic blocks should never be empty.
437 CHECK(!insns1.empty());
438 CHECK(!insns2.empty());
439
435 Instructions::const_iterator iter1 = insns1.begin(); 440 Instructions::const_iterator iter1 = insns1.begin();
436 Instructions::const_iterator iter2 = insns2.begin(); 441 Instructions::const_iterator iter2 = insns2.begin();
437 for (;; ++iter1, ++iter2) { 442 for (;; ++iter1, ++iter2) {
438 // If we have reached the end of the sequence of instructions in one or 443 // If we have reached the end of the sequence of instructions in one or
439 // both basic blocks, we know the relative ordering between the two blocks 444 // both basic blocks, we know the relative ordering between the two blocks
440 // and can return. 445 // and can return.
441 if (iter1 == insns1.end()) { 446 if (iter1 == insns1.end()) {
442 return iter2 == insns2.end() ? 0 : -1; 447 if (iter2 == insns2.end()) {
448 // If the two blocks are the same length (and have elementwise-equal
449 // code and k fields, which is the only way we can reach this point),
450 // and the last instruction isn't a JMP or a RET, then we must compare
451 // their successors.
452 Instruction* const insns1_last = insns1.back();
453 Instruction* const insns2_last = insns2.back();
454 if (BPF_CLASS(insns1_last->code) != BPF_JMP &&
455 BPF_CLASS(insns1_last->code) != BPF_RET) {
456 // Non jumping instructions will always have a valid next instruction.
457 CHECK(insns1_last->next);
458 CHECK(insns2_last->next);
459 return PointerCompare(blocks.find(insns1_last->next)->second,
460 blocks.find(insns2_last->next)->second,
461 blocks);
462 } else {
463 return 0;
464 }
465 }
466 return -1;
443 } else if (iter2 == insns2.end()) { 467 } else if (iter2 == insns2.end()) {
444 return 1; 468 return 1;
445 } 469 }
446 470
447 // Compare the individual fields for both instructions. 471 // Compare the individual fields for both instructions.
448 const Instruction& insn1 = **iter1; 472 const Instruction& insn1 = **iter1;
449 const Instruction& insn2 = **iter2; 473 const Instruction& insn2 = **iter2;
450 if (insn1.code == insn2.code) { 474 if (insn1.code == insn2.code) {
451 if (insn1.k == insn2.k) { 475 if (insn1.k == insn2.k) {
452 // Only conditional jump instructions use the jt_ptr and jf_ptr 476 // Only conditional jump instructions use the jt_ptr and jf_ptr
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks); 765 CutGraphIntoBasicBlocks(instructions, branch_targets, &all_blocks);
742 MergeTails(&all_blocks); 766 MergeTails(&all_blocks);
743 BasicBlocks basic_blocks; 767 BasicBlocks basic_blocks;
744 TopoSortBasicBlocks(first_block, all_blocks, &basic_blocks); 768 TopoSortBasicBlocks(first_block, all_blocks, &basic_blocks);
745 ComputeRelativeJumps(&basic_blocks, all_blocks); 769 ComputeRelativeJumps(&basic_blocks, all_blocks);
746 ConcatenateBasicBlocks(basic_blocks, program); 770 ConcatenateBasicBlocks(basic_blocks, program);
747 return; 771 return;
748 } 772 }
749 773
750 } // namespace sandbox 774 } // namespace sandbox
OLDNEW
« no previous file with comments | « no previous file | sandbox/linux/seccomp-bpf/codegen_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698