diff --git a/contracts/acl/ACL.sol b/contracts/acl/ACL.sol index a87bdb781..500060c9d 100644 --- a/contracts/acl/ACL.sol +++ b/contracts/acl/ACL.sol @@ -242,13 +242,16 @@ contract ACL is IACL, TimeHelpers, AragonApp, ACLHelpers { * @return boolean indicating whether the ACL allows the role or not */ function hasPermission(address _who, address _where, bytes32 _what, bytes memory _how) public view returns (bool) { + // Force cast the bytes array into a uint256[], by overwriting its length + // Note that the uint256[] doesn't need to be initialized as we immediately overwrite it + // with _how and a new length, and _howbecomes invalid from this point forward uint256[] memory how; uint256 intsLength = _how.length / 32; assembly { - how := _how // forced casting + how := _how mstore(how, intsLength) } - // _how is invalid from this point fwd + return hasPermission(_who, _where, _what, how); } diff --git a/contracts/apps/AragonApp.sol b/contracts/apps/AragonApp.sol index b474c3d01..71e7172cc 100644 --- a/contracts/apps/AragonApp.sol +++ b/contracts/apps/AragonApp.sol @@ -47,13 +47,14 @@ contract AragonApp is AppStorage, Autopetrified, VaultRecoverable, EVMScriptRunn return false; } - bytes memory how; // no need to init memory as it is never used - if (_params.length > 0) { - uint256 byteLength = _params.length * 32; - assembly { - how := _params // forced casting - mstore(how, byteLength) - } + // Force cast the uint256[] into a bytes array, by overwriting its length + // Note that the bytes array doesn't need to be initialized as we immediately overwrite it + // with _params and a new length, and _params becomes invalid from this point forward + bytes memory how; + uint256 byteLength = _params.length * 32; + assembly { + how := _params + mstore(how, byteLength) } return linkedKernel.hasPermission(_sender, address(this), _role, how); } diff --git a/contracts/kernel/Kernel.sol b/contracts/kernel/Kernel.sol index 89d11e9af..3698d520b 100644 --- a/contracts/kernel/Kernel.sol +++ b/contracts/kernel/Kernel.sol @@ -228,13 +228,16 @@ contract Kernel is IKernel, KernelStorage, KernelAppIds, KernelNamespaceConstant } modifier auth(bytes32 _role, uint256[] memory params) { + // Force cast the uint256[] into a bytes array, by overwriting its length + // Note that the bytes array doesn't need to be initialized as we immediately overwrite it + // with params and a new length, and params becomes invalid from this point forward bytes memory how; uint256 byteLength = params.length * 32; assembly { - how := params // forced casting + how := params mstore(how, byteLength) } - // Params is invalid from this point fwd + require(hasPermission(msg.sender, address(this), _role, how), ERROR_AUTH_FAILED); _; }