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

New opcodes: SANDBOXED_CALL #117

Open
MicahZoltu opened this Issue Jun 19, 2016 · 7 comments

Comments

Projects
None yet
7 participants
@MicahZoltu
Copy link
Contributor

MicahZoltu commented Jun 19, 2016

When a contract wants to call another contract, at the moment there is quite a bit of risk for the developer because they need to make sure that there are no re-entry bugs/exploits (which can exist across contracts). As shown, these bugs are very subtle and can slip by developers and auditors.

To assist developers in solving this problem, I propose adding a SANDBOXED_CALL opcode that would guarantee that the called contract cannot execute any code outside of their own contract. The called contract would be able to do whatever function calls and state changes they want inside of its contract but any attempt to call out of its contract would result in an exception being thrown. This opcode would require a gas amount passed into it, though contract authors should be encouraged to pass a fairly large value to allow for complex contracts to execute on the other end.

SANDBOXED_CALL should be used when you want to safely call an external contract that you depend on, but don't trust. The developer should assume that these are safe from reentry type attacks but still susceptible to DOS style attacks like stack exhaustion and OOG.

@chfast

This comment has been minimized.

Copy link
Contributor

chfast commented Jun 20, 2016

Every call is opportunistic already.

@MicahZoltu

This comment has been minimized.

Copy link
Contributor Author

MicahZoltu commented Jun 20, 2016

Removed opportunistic stuff.

@pipermerriam

This comment has been minimized.

Copy link
Member

pipermerriam commented Jun 22, 2016

@Zoltu do you mind changing the title as well to remove the opportunistic part?

@MicahZoltu MicahZoltu changed the title New opcodes: SANDBOXED_CALL and OPPORTUNISTIC_SANDBOXED_CALL New opcodes: SANDBOXED_CALL Jun 22, 2016

@MicahZoltu

This comment has been minimized.

Copy link
Contributor Author

MicahZoltu commented Jun 22, 2016

Done.

@samlavery

This comment has been minimized.

Copy link

samlavery commented Jun 25, 2016

Rather than imposing constraints on external entities and potentially breaking things like their ability to upgrade contracts or implement various architectural patterns, why not do the inverse of SANDBOX and add a secondary function modifier such as CRITICAL that allows it to only appear on the callstack once. Any executing contract that attempts any form of subsequent .CALL. fails without executing even the function regardless of any gas sent. Callers should already be checking the return values on calls, so this shouldn't require modification to existing contracts.

@MicahZoltu

This comment has been minimized.

Copy link
Contributor Author

MicahZoltu commented Jun 25, 2016

I didn't consider contract upgrades, that is a reasonable argument against this I think.

I don't think preventing contract/function re-entry directly as you propose is enough though as there are subtle and really hard to notice exploits that can occur across contracts in a complex multi-contract system, all without re-entry.

@holiman

This comment has been minimized.

Copy link
Contributor

holiman commented Jun 25, 2016

I think the overall cleanest solution is the one suggested by @samlavery. A self-assigned only-once-on-callstack (or rather only one sequence of 'me' on callstack, since self-calls should be allowed).

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