Skip to content

TypedMemView memory-safety guarantees are broken #11

Description

@nikitastupin

Hey @prestwich @ErinHales!

I've found an interesting bug in the isValid function of the TypedMemView library.

function isValid(bytes29 memView) internal pure returns (bool ret) {
    if (typeOf(memView) == 0xffffffffff) {return false;}
    uint256 _end = end(memView);
    assembly {
        // solium-disable-previous-line security/no-inline-assembly
        ret := not(gt(_end, mload(0x40)))
    }
}

The function is expected to return true when the memView data structure points to an allocated memory and false otherwise.

However, the function always returns true because the not operator does bitwise not and anything greater than zero is converted to the boolean value of true. Thus whatever the result of the gt operator is (zero or one) the functions returns true.

Impact

The isValid function is used in multiple other functions throughout the library and used to ensure the memory-safety guarantees of the library. Since the function always returns true these memory-safety guarantees break.

Unfortunately, I didn't have enough time&energy now to explore the impact on the Nomad project, where the library is used extensively, or other projects affected by the bug (some of which are quite popular: https://github.com/summa-tx/memview-sol/network/dependents).

Recommendation

Use the iszero operator instead of the not operator to invert a boolean value in assembly.

References

Proof of Concept

Here is a toy example to test this (you may copy-paste it to Remix IDE, deploy, and execute there).

pragma solidity 0.8.18;

contract poc {
     function f() external pure returns (bool o0, bool o1, bool o2) {
         assembly {
            o0 := not(0)
            o1 := not(1)
            o2 := not(1337)
         }
         require(o0);
         require(o1);
         require(o2);
     }
}

The f functions returns three true values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions