Skip to content
This repository has been archived by the owner on Nov 18, 2022. It is now read-only.

Commit

Permalink
Merge pull request from GHSA-f9p9-v8rm-4482
Browse files Browse the repository at this point in the history
Fix sudt erc20 proxy delegatecall bug
  • Loading branch information
Flouse authored Jun 7, 2022
2 parents a5dec04 + 8b33be3 commit 2767d2e
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 2 deletions.
10 changes: 10 additions & 0 deletions c/contracts.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef int (*precompiled_contract_gas_fn)(const uint8_t* input_src,
typedef int (*precompiled_contract_fn)(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down Expand Up @@ -72,6 +73,7 @@ int ecrecover_required_gas(const uint8_t* input, const size_t input_size,
int ecrecover(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size, uint8_t** output, size_t* output_size) {
Expand Down Expand Up @@ -151,6 +153,7 @@ int sha256hash_required_gas(const uint8_t* input, const size_t input_size,
int sha256hash(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size, uint8_t** output, size_t* output_size) {
Expand All @@ -176,6 +179,7 @@ int ripemd160hash_required_gas(const uint8_t* input, const size_t input_size,
int ripemd160hash(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size, uint8_t** output,
Expand Down Expand Up @@ -204,6 +208,7 @@ int data_copy_required_gas(const uint8_t* input, const size_t input_size,
int data_copy(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size, uint8_t** output, size_t* output_size) {
Expand Down Expand Up @@ -404,6 +409,7 @@ int big_mod_exp_required_gas(const uint8_t* input, const size_t input_size,
int big_mod_exp(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size, uint8_t** output,
Expand Down Expand Up @@ -699,6 +705,7 @@ void f_generic(uint64_t h[8], uint64_t m[16], uint64_t c0, uint64_t c1,
int blake2f(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size, uint8_t** output, size_t* output_size) {
Expand Down Expand Up @@ -777,6 +784,7 @@ int bn256_add_istanbul_gas(const uint8_t* input_src,
int bn256_add_istanbul(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down Expand Up @@ -825,6 +833,7 @@ int bn256_scalar_mul_istanbul_gas(const uint8_t* input_src,
int bn256_scalar_mul_istanbul(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down Expand Up @@ -866,6 +875,7 @@ int bn256_pairing_istanbul_gas(const uint8_t* input_src,
int bn256_pairing_istanbul(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down
2 changes: 2 additions & 0 deletions c/other_contracts.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ int recover_account_gas(const uint8_t* input_src,
int recover_account(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down Expand Up @@ -96,6 +97,7 @@ int eth_to_godwoken_addr_gas(const uint8_t* input_src,
int eth_to_godwoken_addr(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down
7 changes: 6 additions & 1 deletion c/polyjuice.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,13 @@ struct evmc_host_context {
gw_context_t* gw_ctx;
const uint8_t* code_data;
const size_t code_size;
// parent level call kind
enum evmc_call_kind kind;
uint32_t from_id;
uint32_t to_id;
// parent level sender
evmc_address sender;
// parent level destination
evmc_address destination;
int error_code;
};
Expand Down Expand Up @@ -599,6 +603,7 @@ struct evmc_result call(struct evmc_host_context* context,
res.gas_left = msg->gas - (int64_t)gas_cost;
ret = contract(gw_ctx,
context->code_data, context->code_size,
context->kind,
msg->flags == EVMC_STATIC,
msg->input_data, msg->input_size,
(uint8_t**)&res.output_data, &res.output_size);
Expand Down Expand Up @@ -910,7 +915,7 @@ int execute_in_evmone(gw_context_t* ctx,
int ret = 0;
evmc_address sender = msg->sender;
evmc_address destination = msg->destination;
struct evmc_host_context context {ctx, code_data, code_size, from_id, to_id, sender, destination, 0};
struct evmc_host_context context {ctx, code_data, code_size, msg->kind, from_id, to_id, sender, destination, 0};
struct evmc_vm* vm = evmc_create_evmone();
struct evmc_host_interface interface = {account_exists, get_storage, set_storage, get_balance,
get_code_size, get_code_hash, copy_code, selfdestruct,
Expand Down
6 changes: 6 additions & 0 deletions c/sudt_contracts.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ int balance_of_any_sudt_gas(const uint8_t* input_src,
int balance_of_any_sudt(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down Expand Up @@ -104,6 +105,7 @@ int transfer_to_any_sudt_gas(const uint8_t* input_src,
int transfer_to_any_sudt(gw_context_t* ctx,
const uint8_t* code_data,
const size_t code_size,
const enum evmc_call_kind parent_kind,
bool is_static_call,
const uint8_t* input_src,
const size_t input_size,
Expand Down Expand Up @@ -146,6 +148,10 @@ int transfer_to_any_sudt(gw_context_t* ctx,
ckb_debug("static call to transfer to any sudt is forbidden");
return ERROR_TRANSFER_TO_ANY_SUDT;
}
if (parent_kind == EVMC_CALLCODE || parent_kind == EVMC_DELEGATECALL) {
ckb_debug("delegatecall/callcode to transfer to any sudt is forbidden");
return ERROR_TRANSFER_TO_ANY_SUDT;
}
if (input_size != (32 + 32 + 32 + 32)) {
return ERROR_TRANSFER_TO_ANY_SUDT;
}
Expand Down
2 changes: 1 addition & 1 deletion c/tests/test_contracts.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ int test_contract(const uint8_t n,
ctx.sys_load_data = sys_load_data;
ctx.sys_load = sys_load;
ctx._internal_load_raw = _internal_load_raw;
ret = contract(&ctx, NULL, 0, true, input_src, input_size, &output, &output_size);
ret = contract(&ctx, NULL, 0, EVMC_CALL, true, input_src, input_size, &output, &output_size);
if (ret != 0) {
debug_print_int("run contract failed", ret);
goto test_contract_cleanup;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"str","type":"string"},{"indexed":false,"internalType":"bool","name":"result","type":"bool"}],"name":"Log","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"str","type":"string"},{"indexed":false,"internalType":"uint256","name":"result","type":"uint256"}],"name":"Log2","type":"event"},{"inputs":[{"internalType":"address","name":"logicContractAddr","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"attack1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"b","type":"bytes"}],"name":"bytesToUint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"get_allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
608060405234801561001057600080fd5b50604051610ccf380380610ccf8339818101604052810190610032919061007a565b80600281905550506100a7565b600080fd5b6000819050919050565b61005781610044565b811461006257600080fd5b50565b6000815190506100748161004e565b92915050565b6000602082840312156100905761008f61003f565b5b600061009e84828501610065565b91505092915050565b610c19806100b66000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806302d06d0514610051578063095c91ac146100815780637483118f146100b1578063da46098c146100e1575b600080fd5b61006b60048036038101906100669190610542565b6100fd565b60405161007891906105a4565b60405180910390f35b61009b6004803603810190610096919061061d565b610195565b6040516100a891906105a4565b60405180910390f35b6100cb60048036038101906100c69190610689565b61021b565b6040516100d8919061070b565b60405180910390f35b6100fb60048036038101906100f69190610726565b610363565b005b60008060005b835181101561018b5760018161011991906107a8565b845161012591906107fe565b60086101319190610832565b600261013d91906109bf565b8482815181106101505761014f610a0a565b5b602001015160f81c60f81b60f81c60ff1661016b9190610832565b8261017691906107a8565b9150808061018390610a39565b915050610103565b5080915050919050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60008060608673ffffffffffffffffffffffffffffffffffffffff1686868660405160240161024c93929190610a90565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516102d69190610b41565b600060405180830381855af49150503d8060008114610311576040519150601f19603f3d011682016040523d82523d6000602084013e610316565b606091505b5080925081935050507f52dd9d08c343f72c69027ade2a075f6242dba2eeca3a3c61bfd8d00d32f6bd208260405161034e9190610bb5565b60405180910390a18192505050949350505050565b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61044f82610406565b810181811067ffffffffffffffff8211171561046e5761046d610417565b5b80604052505050565b60006104816103e8565b905061048d8282610446565b919050565b600067ffffffffffffffff8211156104ad576104ac610417565b5b6104b682610406565b9050602081019050919050565b82818337600083830152505050565b60006104e56104e084610492565b610477565b90508281526020810184848401111561050157610500610401565b5b61050c8482856104c3565b509392505050565b600082601f830112610529576105286103fc565b5b81356105398482602086016104d2565b91505092915050565b600060208284031215610558576105576103f2565b5b600082013567ffffffffffffffff811115610576576105756103f7565b5b61058284828501610514565b91505092915050565b6000819050919050565b61059e8161058b565b82525050565b60006020820190506105b96000830184610595565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006105ea826105bf565b9050919050565b6105fa816105df565b811461060557600080fd5b50565b600081359050610617816105f1565b92915050565b60008060408385031215610634576106336103f2565b5b600061064285828601610608565b925050602061065385828601610608565b9150509250929050565b6106668161058b565b811461067157600080fd5b50565b6000813590506106838161065d565b92915050565b600080600080608085870312156106a3576106a26103f2565b5b60006106b187828801610608565b94505060206106c287828801610608565b93505060406106d387828801610608565b92505060606106e487828801610674565b91505092959194509250565b60008115159050919050565b610705816106f0565b82525050565b600060208201905061072060008301846106fc565b92915050565b60008060006060848603121561073f5761073e6103f2565b5b600061074d86828701610608565b935050602061075e86828701610608565b925050604061076f86828701610674565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006107b38261058b565b91506107be8361058b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156107f3576107f2610779565b5b828201905092915050565b60006108098261058b565b91506108148361058b565b92508282101561082757610826610779565b5b828203905092915050565b600061083d8261058b565b91506108488361058b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561088157610880610779565b5b828202905092915050565b60008160011c9050919050565b6000808291508390505b60018511156108e3578086048111156108bf576108be610779565b5b60018516156108ce5780820291505b80810290506108dc8561088c565b94506108a3565b94509492505050565b6000826108fc57600190506109b8565b8161090a57600090506109b8565b8160018114610920576002811461092a57610959565b60019150506109b8565b60ff84111561093c5761093b610779565b5b8360020a91508482111561095357610952610779565b5b506109b8565b5060208310610133831016604e8410600b841016171561098e5782820a90508381111561098957610988610779565b5b6109b8565b61099b8484846001610899565b925090508184048111156109b2576109b1610779565b5b81810290505b9392505050565b60006109ca8261058b565b91506109d58361058b565b9250610a027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846108ec565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000610a448261058b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610a7657610a75610779565b5b600182019050919050565b610a8a816105df565b82525050565b6000606082019050610aa56000830186610a81565b610ab26020830185610a81565b610abf6040830184610595565b949350505050565b600081519050919050565b600081905092915050565b60005b83811015610afb578082015181840152602081019050610ae0565b83811115610b0a576000848401525b50505050565b6000610b1b82610ac7565b610b258185610ad2565b9350610b35818560208601610add565b80840191505092915050565b6000610b4d8284610b10565b915081905092915050565b600082825260208201905092915050565b7f64656c656761746563616c6c2072657475726e20000000000000000000000000600082015250565b6000610b9f601483610b58565b9150610baa82610b69565b602082019050919050565b60006040820190508181036000830152610bce81610b92565b9050610bdd60208301846106fc565b9291505056fea2646970667358221220844eedde78501ff38efd9053f558c5ec05d21c02aae5ba372b281444c0c4330164736f6c634300080e0033
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
pragma solidity ^0.8.0;


contract AttackContract {
mapping (address => mapping (address => uint256)) private _allowances;

uint256 private _totalSupply;
uint256 private _sudtId;

string private _name;
string private _symbol;
uint8 private _decimals;

event Log(string str, bool result);
event Log2(string str, uint256 result);

constructor(uint256 sudtId_) public {
_sudtId = sudtId_;
}
function attack1(address logicContractAddr,address from,address to ,uint256 amount) public returns(bool) {
bool r;
bytes memory s;
(r, s) = logicContractAddr.delegatecall(abi.encodeWithSignature("transferFrom(address,address,uint256)", from,to,amount));
emit Log("delegatecall return ", r); // r为true或false
return r;
/* uint256 result = bytesToUint(s); */
/* emit Log2("return ", result); */
}

function setAllowance(address owner,address spender, uint256 amount) public {
_allowances[owner][spender] = amount;
}

function get_allowances(address from,address to) public view returns( uint256){
return _allowances[from][to];
}

function bytesToUint(bytes memory b) public pure returns (uint256){
uint256 number;
for(uint i= 0; i<b.length; i++){
number = number + uint8(b[i]) * (2**(8 * (b.length-(i+1))));
}
return number;
}
}
1 change: 1 addition & 0 deletions polyjuice-tests/src/test_cases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ pub(crate) mod rlp;
// Special pre-compiled contract to support transfer to any sudt
pub(crate) mod invalid_sudt_erc20_proxy;
pub(crate) mod sudt_erc20_proxy;
pub(crate) mod sudt_erc20_proxy_attack_allowance;
Loading

0 comments on commit 2767d2e

Please sign in to comment.