New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EVM dynamic array maybe occupy large memory #18289

Open
lcatro opened this Issue Dec 12, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@lcatro
Copy link

lcatro commented Dec 12, 2018

System information

Geth version: 1.8.19
OS & Version: Linux
Commit hash : no found

Expected behaviour

Dynamic array save itself length in memory and this length will restrict index of array .


    function a(uint[] b) {
        b[2]=0x10;
    }

See the assambly ,b[2] = 0x10 implicate index of array check .


----  Address 0x97  Function a() Main Code  ----
151 JUMPDEST
152 PUSH1 10    ;  value : 0x10
154 DUP2
155 PUSH1 02    ;  index of array .0x02
157 DUP2
158 MLOAD       ;  MLOAD 0x80 ,Get the array length
159 DUP2
160 LT          ;  check index of array with array lengtj
161 ISZERO
162 ISZERO  
163 PUSH1 a7
165 JUMPI       ;  jump to write data into array
166 INVALID     ;  exit contract 
----  Address 0xA7  ----
167 JUMPDEST
168 PUSH1 20    ;  /
170 SWAP1       ;  |
171 DUP2        ;  |
172 MUL         ;  |  calculate the data location in array and store the number in it 
173 SWAP1       ;  |
174 SWAP2       ;  |
175 ADD         ;  |
176 ADD         ;  \
177 MSTORE      ;  MSTORE 0xE0,0x10 .

So call function a like this a([1,2,3]) ,b[2]=0x10 will success execute ;but a([1,2]) ,b[2]=0x10 will except.

Actual behaviour

We know Solc will auto insert array index check code in assambly ,so I try still rewrite the dynamic length .


pragma solidity ^0.4.24;

contract test {

    function a(uint[] b) {
        b.length = 0x10;
    }

}

Unfortunately ,it can't pass compile .It mean we rewrite the length of dynamic array .But I try to rewrite the array length on memory that is work .


pragma solidity ^0.4.24;

contract test {

    function a(uint[] b,uint[] c) {
        uint c_length = c.length;
        assembly {
            mstore(add(0x80,mul(3,0x20)),0x5)  //  rewrite the length of dynamic array in memory
        }
        c_length = c.length;   //  array length change to 0x5
    }

}

Lastly ,I try writing a data to offset 0xC800000 in array .EVM will occupy large memory (200 MB)

pragma solidity ^0.4.24;

contract test {

    function a(uint[] b,uint[] c) {
        uint c_length = c.length;
        assembly {
            mstore(add(0x80,mul(3,0x20)),0xAAAAAAAA)
        }
        c_length = c.length;
        c[0xC800000] = 0xFF;
    }

}

Steps to reproduce the behaviour

This is EVM test command (ignore gas-limit ):
./evm --code 608060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806396f40e3d14610046575b600080fd5b34801561005257600080fd5b506100ed60048036038101908080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290803590602001908201803590602001908080602002602001604051908101604052809392919081815260200183836020028082843782019150505050505091929192905050506100ef565b005b60008151905063aaaaaaaa6020600302608001528151905060ff826210000081518110151561011a57fe5b90602001906020020181815250505050505600a165627a7a72305820fe133e12a0270131204b3cc47bb934f4d348bad747ca490adc53d935690806ac0029 --input 96f40e3d000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004 --gas 10000000000000000 --debug run

image

image

Backtrace

Not found ,you can see large memory alloc output on console by --debug flag .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment