Skip to content
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

Align data location of interface with implementation #394

Conversation

cameel
Copy link
Contributor

@cameel cameel commented Mar 24, 2022

The reason behind the PR has already been explained well by @chriseth in a similar PR to OpenZeppelin (OpenZeppelin/openzeppelin-contracts#3293) so I'll copy that description here:

First, I would like to apologize. Somehow the issue ethereum/solidity#10900 got lost in our backlog. We are currently fixing it and discovered one instance of this in openzeppelin. This PR fixes it.

More details:

The function hashProposal in the interface is declared with calldata parameters while its implementation in Governor uses memory. This leads to invalid code being generated whenever someone calls the hashProposal function internally on the interface instead of the implementation. This can only happen if you have an (abstract) contract that inherits from the interface, but not from the implementation, but is still part of an inheritance hierarchy that also has the implementation.

Simplified example:

abstract contract I {
        function f(uint[] calldata x)  virtual internal;
}
contract C is I {
        uint public data;
        // The override checker in the compiler does not complain
        // here - this is the bug in the compiler.
        function f(uint[] memory x)  override internal {
                data = x[0];
        }
}
abstract contract D is I {
        function g(uint[] calldata x)  external {
                // Since D only "knows" `I`, the signature of `f` uses calldata,
                // while the virtual lookup ends up with `C.f`, which uses memory.
                // This results in the calldata pointer `x` being passed and interpreted
                // as a memory pointer.
                f(x);
        }
}
contract X is C, D { }

In case of Gnosis, the function in question is isValidSignature from ISignatureValidator.

@rmeissner
Copy link
Member

Totally makes sense to merge this, but I was wondering if this bug is triggered by the Safe code. We do have tests that call this code and it works as expected. (This is important to understand if we have to redeploy this contract and migrate existing Safes).

@rmeissner
Copy link
Member

Note: it seems the repo is not properly setup for external migrations, I will look into this

@cameel
Copy link
Contributor Author

cameel commented Apr 5, 2022

No, I don't think your code is affected (other than you'd get a compilation error once we release a fix). The risk of calldata being reinterpreted as memory exists only for internal calls. You seem to be calling isValidSignature() only externally and in external calls both calldata and memory arrays are encoded the same way.

@cameel
Copy link
Contributor Author

cameel commented Apr 27, 2022

Any chance this will be merged soon?

@rmeissner
Copy link
Member

We are currently in the progress of migrating repositories and organisations. And as this is not security critical we didn't give it any priority. Are there any external dependencies that are related to this?

@cameel
Copy link
Contributor Author

cameel commented Apr 27, 2022

Ok, thanks for the info. It's not critical for us either, it's just pretty trivial and would let us have one less workaround in the testing scripts.

By dependencies, do you mean other PRs that would have to be merged in sync in the compiler or other projects? Not really. It's simply that the form you have now will be disallowed. The form this PR changes it to worked before and will still work.

@rmeissner
Copy link
Member

With dependencies I meant if there is a project that is depending on this PR being merged ;)

I will try to get this done as soon we are are done with the coordination of the org migration.

@cameel
Copy link
Contributor Author

cameel commented Apr 27, 2022

Thanks!

No, I don't think there are any dependencies like that. For us it's just that Gnosis Safe is one of the projects we use to test the compiler binary in CI. We compile it and run its tests on every PR. We can add a workaround, it's just always easier if the problem gets fixed upstream :)

@rmeissner
Copy link
Member

Could you rebase this PR too, then the test will run :)

@cameel cameel force-pushed the align-data-location-in-overrides branch from 3ef871b to dc7f4a5 Compare May 18, 2022 18:45
@cameel
Copy link
Contributor Author

cameel commented May 18, 2022

Sure. Both PRs rebased now.

@mmv08
Copy link
Member

mmv08 commented Dec 24, 2022

@rmeissner Can we merge this? This is relevant for our 1.4.0 release #440

@rmeissner rmeissner merged commit 5abc0bb into safe-global:main Jan 10, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Jan 10, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants