Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2013 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2013 The Native Client Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 # Executable specification of valid instructions and superinstructions (in terms | 6 # Executable specification of valid instructions and superinstructions (in terms |
| 7 # of their disassembler listing). | 7 # of their disassembler listing). |
| 8 # Should serve as formal and up-to-date ABI reference and as baseline for | 8 # Should serve as formal and up-to-date ABI reference and as baseline for |
| 9 # validator exhaustive tests. | 9 # validator exhaustive tests. |
| 10 | 10 |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 '%ebp' : '%rbp', | 210 '%ebp' : '%rbp', |
| 211 '%r8d' : '%r8', | 211 '%r8d' : '%r8', |
| 212 '%r9d' : '%r9', | 212 '%r9d' : '%r9', |
| 213 '%r10d' : '%r10', | 213 '%r10d' : '%r10', |
| 214 '%r11d' : '%r11', | 214 '%r11d' : '%r11', |
| 215 '%r12d' : '%r12', | 215 '%r12d' : '%r12', |
| 216 '%r13d' : '%r13', | 216 '%r13d' : '%r13', |
| 217 '%r14d' : '%r14', | 217 '%r14d' : '%r14', |
| 218 '%r15d' : '%r15'} | 218 '%r15d' : '%r15'} |
| 219 | 219 |
| 220 REGS32 = REG32_TO_REG64.keys() | |
| 220 REGS64 = REG32_TO_REG64.values() | 221 REGS64 = REG32_TO_REG64.values() |
| 221 | 222 |
| 222 | 223 |
| 223 class Condition(object): | 224 class Condition(object): |
| 224 """Represents assertion about the state of 64-bit registers. | 225 """Represents assertion about the state of 64-bit registers. |
| 225 | 226 |
| 226 (used as precondition and postcondition) | 227 (used as precondition and postcondition) |
| 227 | 228 |
| 228 Supported assertions: | 229 Supported assertions: |
| 229 0. %rpb and %rsp are sandboxed (and nothing is known about other registers) | 230 0. %rpb and %rsp are sandboxed (and nothing is known about other registers) |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 for op in write_operands: | 418 for op in write_operands: |
| 418 # TODO(shcherbina): disallow writes to | 419 # TODO(shcherbina): disallow writes to |
| 419 # cs, ds, es, fs, gs | 420 # cs, ds, es, fs, gs |
| 420 if op in ['%r15', '%r15d', '%r15w', '%r15b']: | 421 if op in ['%r15', '%r15d', '%r15w', '%r15b']: |
| 421 raise SandboxingError('changes to r15 are not allowed', instruction) | 422 raise SandboxingError('changes to r15 are not allowed', instruction) |
| 422 if op in ['%bpl', '%bp', '%rbp']: | 423 if op in ['%bpl', '%bp', '%rbp']: |
| 423 raise SandboxingError('changes to rbp are not allowed', instruction) | 424 raise SandboxingError('changes to rbp are not allowed', instruction) |
| 424 if op in ['%spl', '%sp', '%rsp']: | 425 if op in ['%spl', '%sp', '%rsp']: |
| 425 raise SandboxingError('changes to rsp are not allowed', instruction) | 426 raise SandboxingError('changes to rsp are not allowed', instruction) |
| 426 | 427 |
| 427 if op in REG32_TO_REG64 and zero_extending: | 428 if op in REGS32 and zero_extending: |
| 428 if not postcondition.Implies(Condition()): | 429 if not postcondition.Implies(Condition()): |
| 429 raise SandboxingError( | 430 raise SandboxingError( |
| 430 '%s when zero-extending %s' | 431 '%s when zero-extending %s' |
| 431 % (postcondition.WhyNotImplies(Condition()), op), | 432 % (postcondition.WhyNotImplies(Condition()), op), |
| 432 instruction) | 433 instruction) |
| 433 | 434 |
| 434 r = REG32_TO_REG64[op] | 435 r = REG32_TO_REG64[op] |
| 435 if r in ['%rbp', '%rsp']: | 436 if r in ['%rbp', '%rsp']: |
| 436 postcondition = Condition(restricted_instead_of_sandboxed=r) | 437 postcondition = Condition(restricted_instead_of_sandboxed=r) |
| 437 else: | 438 else: |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 raise SandboxingError( | 504 raise SandboxingError( |
| 504 'segments in memory references are not allowed', instruction) | 505 'segments in memory references are not allowed', instruction) |
| 505 | 506 |
| 506 if bitness == 32: | 507 if bitness == 32: |
| 507 if _InstructionNameIn( | 508 if _InstructionNameIn( |
| 508 name, | 509 name, |
| 509 ['mov', 'add', 'sub', 'and', 'or', 'xor', | 510 ['mov', 'add', 'sub', 'and', 'or', 'xor', |
| 510 'xchg', 'xadd', | 511 'xchg', 'xadd', |
| 511 'inc', 'dec', 'neg', 'not', | 512 'inc', 'dec', 'neg', 'not', |
| 512 'lea', | 513 'lea', |
| 514 'adc', 'bsf', 'bsr', 'btc', 'btr', 'bts', | |
| 515 'cmp', | |
| 516 'bt', | |
| 517 'cmc', | |
| 513 ]): | 518 ]): |
| 514 return Condition(), Condition() | 519 return Condition(), Condition() |
| 515 elif re.match(r'mov[sz][bwl][lqw]$', name): # MOVD, MOVSX, MOVSXD, MOVZX | 520 elif re.match(r'mov[sz][bwl][lqw]$', name): # MOVD, MOVSX, MOVSXD, MOVZX |
| 516 return Condition(), Condition() | 521 return Condition(), Condition() |
| 522 elif name == 'bswap': | |
| 523 if ops[0] not in REGS32: | |
| 524 raise SandboxingError( | |
| 525 'bswap is only allowed with 32-bit operands', | |
| 526 instruction) | |
| 527 return Condition(), Condition() | |
| 517 else: | 528 else: |
| 518 raise DoNotMatchError(instruction) | 529 raise DoNotMatchError(instruction) |
| 519 | 530 |
| 520 elif bitness == 64: | 531 elif bitness == 64: |
| 521 precondition = Condition() | 532 precondition = Condition() |
| 522 postcondition = Condition() | 533 postcondition = Condition() |
| 523 zero_extending = False | 534 zero_extending = False |
| 524 touches_memory = True | 535 touches_memory = True |
| 525 | 536 |
| 526 if _InstructionNameIn( | 537 if _InstructionNameIn( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 538 write_ops = ops | 549 write_ops = ops |
| 539 elif _InstructionNameIn(name, ['inc', 'dec', 'neg', 'not']): | 550 elif _InstructionNameIn(name, ['inc', 'dec', 'neg', 'not']): |
| 540 assert len(ops) == 1 | 551 assert len(ops) == 1 |
| 541 zero_extending = True | 552 zero_extending = True |
| 542 write_ops = ops | 553 write_ops = ops |
| 543 elif name == 'lea': | 554 elif name == 'lea': |
| 544 assert len(ops) == 2 | 555 assert len(ops) == 2 |
| 545 write_ops = [ops[1]] | 556 write_ops = [ops[1]] |
| 546 touches_memory = False | 557 touches_memory = False |
| 547 zero_extending = True | 558 zero_extending = True |
| 559 elif _InstructionNameIn( | |
| 560 name, | |
| 561 ['adc', 'bsf', 'bsr', 'btc', 'btr', 'bts']): | |
| 562 # Note: some versions of objdump (including one that is currently used | |
| 563 # in targeted tests) decode 'tzcnt' as 'repz bsf' | |
| 564 # (see validator_ragel/testdata/32/tzcnt.test) | |
| 565 # From sandboxing point of view bsf and tzcnt are the same, so | |
| 566 # we ignore this bug here. | |
| 567 # Same applies to 32-bit version. | |
| 568 assert len(ops) == 2 | |
| 569 write_ops = [ops[1]] | |
| 570 elif _InstructionNameIn(name, ['cmp']): | |
|
halyavin
2013/07/03 10:51:14
I think we can combine cmp and bt. They are simila
Vlad Shcherbina
2013/07/03 11:31:21
Done.
Vlad Shcherbina
2013/07/03 12:05:04
Actually, they are not: bt %rax, (%r15) is not all
| |
| 571 assert len(ops) == 2 | |
| 572 write_ops = [] | |
| 573 elif _InstructionNameIn(name, ['bt']): | |
| 574 assert len(ops) == 2 | |
| 575 write_ops = [] | |
| 576 elif name == 'bswap': | |
| 577 assert len(ops) == 1 | |
| 578 if ops[0] not in REGS32 + REGS64: | |
| 579 raise SandboxingError( | |
| 580 'bswap is only allowed with 32-bit and 64-bit operands', | |
| 581 instruction) | |
| 582 write_ops = ops | |
| 583 elif _InstructionNameIn(name, ['cmc']): | |
| 584 assert len(ops) == 0 | |
| 585 write_ops = [] | |
| 548 else: | 586 else: |
| 549 raise DoNotMatchError(instruction) | 587 raise DoNotMatchError(instruction) |
| 550 | 588 |
| 551 if touches_memory: | 589 if touches_memory: |
| 552 precondition = _ProcessMemoryAccess(instruction, ops) | 590 precondition = _ProcessMemoryAccess(instruction, ops) |
| 553 | 591 |
| 554 postcondition = _ProcessOperandWrites( | 592 postcondition = _ProcessOperandWrites( |
| 555 instruction, write_ops, zero_extending) | 593 instruction, write_ops, zero_extending) |
| 556 | 594 |
| 557 return precondition, postcondition | 595 return precondition, postcondition |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 787 raise DoNotMatchError(superinstruction) | 825 raise DoNotMatchError(superinstruction) |
| 788 if lea_r15_rsi_rsi.match(superinstruction[1].disasm) is None: | 826 if lea_r15_rsi_rsi.match(superinstruction[1].disasm) is None: |
| 789 raise DoNotMatchError(superinstruction) | 827 raise DoNotMatchError(superinstruction) |
| 790 if mov_edi_edi.match(superinstruction[2].disasm) is None: | 828 if mov_edi_edi.match(superinstruction[2].disasm) is None: |
| 791 raise DoNotMatchError(superinstruction) | 829 raise DoNotMatchError(superinstruction) |
| 792 if lea_r15_rdi_rdi.match(superinstruction[3].disasm) is None: | 830 if lea_r15_rdi_rdi.match(superinstruction[3].disasm) is None: |
| 793 raise DoNotMatchError(superinstruction) | 831 raise DoNotMatchError(superinstruction) |
| 794 return | 832 return |
| 795 | 833 |
| 796 raise DoNotMatchError(superinstruction) | 834 raise DoNotMatchError(superinstruction) |
| OLD | NEW |