The toString
function in LibStrings.sol
does not adequately manage the memory used for string conversion, leading to potential residual data issues. This can result in incorrect string handling and interpretation by other parts of the contract or external systems.
The presence of residual or "dirty" data in memory after the string data can lead to security vulnerabilities, incorrect data processing, and potential exploitation where memory content is critical. This issue is capable of damaging the integrity of data handling within other contracts and could lead to incorrect outputs or behaviors in systems that rely on this contract.
Take a look at this function. It assumes that the free memory is clean, i.e., does not explicitly zero out used memory
Here is a test Function in TestLibStrings.sol
Let's look at the logs:
First Log Entry:
Event: LogStringData
Args:
0x313233
(Hexadecimal representation of the string data)
This log corresponds to the "Output String Data" emitted by our test function. The hexadecimal 0x313233
translates to the ASCII string "123", which is the correct string representation of the number 123
that was passed to the toString
function.
Second Log Entry:
Event: LogStringData
Args:
0x313233ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
(Hexadecimal representation of the memory after the string)
This log corresponds to the "Memory After String" emitted by our test function. The presence of 0x313233
is expected as it represents the string "123". Albeit, the trailing ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
indicates that the memory immediately following the string contains the "dirty" data that was intentionally written to memory before calling the toString
function.
The key observation here is that the memory after the string still contains the "dirty" data (0xFF...
). This confirms the concern about the toString
function not managing memory cleanly. Specifically, it shows that:
The function does not clear or zero out the memory after the string data, leaving residual data intact.
This residual data could potentially lead to errors or unexpected behavior if the memory is interpreted as part of the string by other parts of the contract or by external systems that interact with the contract.
In some cases, high level solidity will not have issues decoding values as this region in memory is meant to be
empty. However, certain ABI decoders, notably Etherscan, will have trouble decoding them.
Note: It is likely that the use of toString() in Beanstalk will not be impacted by the above issue. However,
the issue can become severe if LibString is used as a generic string library.
Remix
Manual Review
To address this issue, you should modify the toString
function to ensure that all memory used to store the string is initialized to zero before the string data is written. Additionally, after writing the string data, any unused portion of the allocated memory should be explicitly set to zero. This can be done by adjusting the loop that writes the string data to also cover the entire allocated memory space, or by adding a separate loop to zero out the memory after the string data has been written.
Here's a conceptual modification to the toString
function:
This way, we can ensure that the entire buffer is initialized and any unused memory after the string is explicitly cleared, mitigating the risk of residual data affecting the contract's behavior.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.