-
Notifications
You must be signed in to change notification settings - Fork 7.9k
ext/bz2: bzcompress/bzdecompress check inputs lengths beforehand. #17887
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
Conversation
ext/bz2/bz2.c
Outdated
@@ -450,6 +450,13 @@ PHP_FUNCTION(bzcompress) | |||
RETURN_THROWS(); | |||
} | |||
|
|||
const unsigned int source_len_max = (unsigned int)((UINT_MAX - 600) / 1.01); | |||
|
|||
if (source_len > source_len_max) { |
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.
Something's off, I removed this check and it compressed just fine.
Just because the max output length is expressed in terms of the input length (i.e. (source_len + (0.01 * source_len) + 600)
) doesn't mean that's a limit.
I didn't check decompression but I suppose the same mistake happened there.
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 see, was trying to cater to the type (unsigned int).
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.
Hmmm, surprisingly indeed the theoretical bound would be what you checked on then. However, this is the worst-case and we certainly can make inputs that compress in less bytes. So a lot of inputs would be unrightfully blocked if you did this check.
What probably needs to happen is use of the lower level interfaces to not do compression/decompression in a one-shot manner.
https://sourceware.org/pub/bzip2/docs/v101/manual_3.html states:
Compression in this manner is a one-shot event, done with a single call to this function. The resulting compressed data is a complete bzip2 format data stream. There is no mechanism for making additional calls to provide extra input data. If you want that kind of mechanism, use the low-level interface.
This would allow going beyondunsigned int
.
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.
oh I see, bzCompressInit -> bzCompress/BZ_RUN until we fill all or error -> bzCompressEnd. I ll see about this later :)
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.
Dropping the casts is fine, but if you merge this then make sure to use the commit title instead of the PR title
also removing useless casts for filter ZendMM parts.