crytic / slither

Static Analyzer for Solidity and Vyper
https://blog.trailofbits.com/2018/10/19/slither-a-solidity-static-analysis-framework/
GNU Affero General Public License v3.0
5.27k stars 964 forks source link

[Bug]: Issue with last_name function not identifying assignments in inline assembly #2160

Open BradMoonUESTC opened 12 months ago

BradMoonUESTC commented 12 months ago

Describe the issue:

Description

When analyzing the cmp function, which contains inline assembly in Solidity, the last_name function is expected to identify the assignments for the variables e_ and _l. However, the function returns an empty candidates list.

Solidity Function

function cmp(p_, q_, e_) -> _l {
    for { e_ := sub(e_, q_) } lt(_l, e_) { _l := add(_l, 1) } {
        e_ := mul(iszero(byte(0, xor(mload(add(p_, _l)), mload(add(q_, _l))))), e_)
    }
}

Code example to reproduce the issue:

function cmp(p_, q_, e_) -> _l {
    for { e_ := sub(e_, q_) } lt(_l, e_) { _l := add(_l, 1) } {
        e_ := mul(iszero(byte(0, xor(mload(add(p_, _l)), mload(add(q_, _l))))), e_)
    }
}

origin repo: https://github.com/Vectorized/solady/blob/main/src/utils/LibZip.sol

Version:

0.9.6

Relevant log output:

ERROR:SlitherSolcParsing:
Failed to convert IR to SSA for LibZip contract. Please open an issue https://github.com/crytic/slither/issues.

Traceback (most recent call last):
  File "slither/__main__.py", line 814, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "slither/__main__.py", line 102, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
  File "slither/__main__.py", line 80, in process_single
    slither = Slither(target, ast_format=ast, **vars(args))
  File "slither/slither.py", line 135, in __init__
    self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))
  File "slither/slither.py", line 155, in _init_parsing_and_analyses
    raise e
  File "slither/slither.py", line 151, in _init_parsing_and_analyses
    parser.analyze_contracts()
  File "slither/solc_parsing/slither_compilation_unit_solc.py", line 541, in analyze_contracts
    self._convert_to_slithir()
  File "slither/solc_parsing/slither_compilation_unit_solc.py", line 774, in _convert_to_slithir
    raise e
  File "slither/solc_parsing/slither_compilation_unit_solc.py", line 769, in _convert_to_slithir
    contract.convert_expression_to_slithir_ssa()
  File "slither/core/declarations/contract.py", line 1502, in convert_expression_to_slithir_ssa
    func.generate_slithir_ssa(all_ssa_state_variables_instances)
  File "slither/core/declarations/function_contract.py", line 137, in generate_slithir_ssa
    add_ssa_ir(self, all_ssa_state_variables_instances)
  File "slither/slithir/utils/ssa.py", line 206, in add_ssa_ir
    fix_phi_rvalues_and_storage_ref(
  File "slither/slithir/utils/ssa.py", line 526, in fix_phi_rvalues_and_storage_ref
    fix_phi_rvalues_and_storage_ref(
  File "slither/slithir/utils/ssa.py", line 526, in fix_phi_rvalues_and_storage_ref
    fix_phi_rvalues_and_storage_ref(
  File "slither/slithir/utils/ssa.py", line 526, in fix_phi_rvalues_and_storage_ref
    fix_phi_rvalues_and_storage_ref(
  [Previous line repeated 5 more times]
  File "slither/slithir/utils/ssa.py", line 496, in fix_phi_rvalues_and_storage_ref
    variables = [
  File "slither/slithir/utils/ssa.py", line 497, in <listcomp>
    last_name(dst, ir.lvalue, init_local_variables_instances) for dst in ir.nodes
  File "slither/slithir/utils/ssa.py", line 363, in last_name
    assert candidates
AssertionError
ERROR:root:Error in audit_repo/testcmp.sol
ERROR:root:Traceback (most recent call last):
  File "slither/__main__.py", line 814, in main_impl
    ) = process_all(filename, args, detector_classes, printer_classes)
  File "slither/__main__.py", line 102, in process_all
    ) = process_single(compilation, args, detector_classes, printer_classes)
  File "slither/__main__.py", line 80, in process_single
    slither = Slither(target, ast_format=ast, **vars(args))
  File "slither/slither.py", line 135, in __init__
    self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))
  File "slither/slither.py", line 155, in _init_parsing_and_analyses
    raise e
  File "slither/slither.py", line 151, in _init_parsing_and_analyses
    parser.analyze_contracts()
  File "slither/solc_parsing/slither_compilation_unit_solc.py", line 541, in analyze_contracts
    self._convert_to_slithir()
  File "slither/solc_parsing/slither_compilation_unit_solc.py", line 774, in _convert_to_slithir
    raise e
  File "slither/solc_parsing/slither_compilation_unit_solc.py", line 769, in _convert_to_slithir
    contract.convert_expression_to_slithir_ssa()
  File "slither/core/declarations/contract.py", line 1502, in convert_expression_to_slithir_ssa
    func.generate_slithir_ssa(all_ssa_state_variables_instances)
  File "slither/core/declarations/function_contract.py", line 137, in generate_slithir_ssa
    add_ssa_ir(self, all_ssa_state_variables_instances)
  File "slither/slithir/utils/ssa.py", line 206, in add_ssa_ir
    fix_phi_rvalues_and_storage_ref(
  File "slither/slithir/utils/ssa.py", line 526, in fix_phi_rvalues_and_storage_ref
    fix_phi_rvalues_and_storage_ref(
  File "slither/slithir/utils/ssa.py", line 526, in fix_phi_rvalues_and_storage_ref
    fix_phi_rvalues_and_storage_ref(
  File "slither/slithir/utils/ssa.py", line 526, in fix_phi_rvalues_and_storage_ref
    fix_phi_rvalues_and_storage_ref(
  [Previous line repeated 5 more times]
  File "slither/slithir/utils/ssa.py", line 496, in fix_phi_rvalues_and_storage_ref
    variables = [
  File "slither/slithir/utils/ssa.py", line 497, in <listcomp>
    last_name(dst, ir.lvalue, init_local_variables_instances) for dst in ir.nodes
  File "slither/slithir/utils/ssa.py", line 363, in last_name
    assert candidates
AssertionError
0xalpharush commented 11 months ago

This is a bug. You may be able to workaround with by adding the --skip-assembly flag.

SquilliamX commented 5 months ago

This is a bug. You may be able to workaround with by adding the --skip-assembly flag.

thanks, this is a great work around!