-
Notifications
You must be signed in to change notification settings - Fork 529
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
src: fix libssh2_store_*()
for >u32 inputs
#1025
Conversation
`_libssh2_store_str()` and `_libssh2_store_bignum2_bytes()` accept inputs of size_t size, stores the size as 32-bit unsigned integer, then stores the whole input buffer. With inputs larger than `UINT_MAX` this means the size is smaller than the data that follows it. This patch truncates the stored data to the stored size. Closes #xxxx
@MichaelBuckley Would you mind taking a look at this update for |
Looking at this more, should these API just fail if |
I agree they should. Though it would be a substantial update, there are 95 callers for As a first step I've updated them to return non-zero if the stored len matches the input. |
Having them return non-void is a good first step. |
I've only thought about this for a few minutes, so I could be wrong, but would it not make more sense for all of the |
@MichaelBuckley That's also an option. As I understand, we're heading to support |
if(len) { | ||
memcpy(*buf, str, len); | ||
*buf += len; | ||
uint32_t len_stored = (uint32_t)len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should check for len > UINT_MAX
and return a FALSE if so, as then it can't store the string properly. Could possibly also do with an assert() to get caught better in a debug build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added assert()s, and added returning FALSE earlier, though it still stores as much as it can, as no caller checks for the return value. I'm not ready adding these checks as it involves digging into low-level logic and risks adding leaks and worse bugs.
Earlier I added quite a few casts for _libssh2_store_u32()
calls in 02f2700. The potential problem with these is similar, the caller code might continue to assume full length, while the length stored on the wire is u32
.
I've so far added a return value and Any objections for committing this, or suggestions what else to improve before? |
Is this issue fixed? |
No, these functions now correctly return an error in case of an overflow, but callers are not checking for errors yet. |
_libssh2_store_str()
and_libssh2_store_bignum2_bytes()
acceptinputs of
size_t
max, store the size as 32-bit unsigned integer, thenstore the complete input buffer.
With inputs larger than
UINT_MAX
this means the stored size is smallerthan the data that follows it.
This patch truncates the stored data to the stored size, and now returns
a boolean with false if the stored length differs from the requested
one. Also add
assert()
s for this condition.This is still not a correct fix, as we now dump consistent, but still
truncated data which is not what the caller wants. In future steps we'll
need to update all callers that might pass large data to this function
to check the return value and handle an error, or make sure to not call
this function with more than UINT_MAX bytes of data.
Ref: c3bcdd8 (2010-04-17)
Ref: ed439a2 (2022-09-29)
Closes #1025