Skip to content
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

Allow a limit to be set on the decompressed buffer size for ZlibDecoders #9924

Merged
merged 8 commits into from Jan 31, 2020

Conversation

rdicroce
Copy link
Contributor

@rdicroce rdicroce commented Jan 7, 2020

Motivation:
It is impossible to know in advance how much memory will be needed to
decompress a stream of bytes that was compressed using the DEFLATE
algorithm. In theory, up to 1032 times the compressed size could be
needed. For untrusted input, an attacker could exploit this to exhaust
the memory pool.

Modifications:
ZlibDecoder and its subclasses now support an optional limit on the size
of the decompressed buffer. By default, if the limit is reached,
decompression stops and a DecompressionException is thrown. Behavior
upon reaching the limit is modifiable by subclasses in case they desire
something else.

Result:
The decompressed buffer can now be limited to a configurable size, thus
mitigating the possibility of memory pool exhaustion.

This fixes #6168 for JZlibDecoder and JdkZlibDecoder.

Motivation:
It is impossible to know in advance how much memory will be needed to
decompress a stream of bytes that was compressed using the DEFLATE
algorithm. In theory, up to 1032 times the compressed size could be
needed. For untrusted input, an attacker could exploit this to exhaust
the memory pool.

Modifications:
ZlibDecoder and its subclasses now support an optional limit on the size
of the decompressed buffer. By default, if the limit is reached,
decompression stops and a DecompressionException is thrown. Behavior
upon reaching the limit is modifiable by subclasses in case they desire
something else.

Result:
The decompressed buffer can now be limited to a configurable size, thus
mitigating the possibility of memory pool exhaustion.
@netty-bot
Copy link

Can one of the admins verify this patch?

@normanmaurer
Copy link
Member

@netty-bot test this please

@rdicroce
Copy link
Contributor Author

rdicroce commented Jan 9, 2020

Failed due to Checkstyle violation. Should be fixed now.

@normanmaurer
Copy link
Member

@netty-bot test this please

@normanmaurer
Copy link
Member

@rdicroce did you sign our ICLA ?

https://netty.io/s/icla ?

@rdicroce
Copy link
Contributor Author

Yes, although it's been 4.5 years. My last contribution was #4338. Does the ICLA expire after a certain amount of time?

@normanmaurer
Copy link
Member

@rdicroce ah found it... :)

Copy link
Member

@carl-mastrangelo carl-mastrangelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good to me, just a few nits.

/**
* Maximum allowed size of the decompression buffer.
*/
protected int maxAllocation;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be private/final?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make it final but leave it as protected in case a subclass wants to read it for any reason.

Copy link
Member

@njhill njhill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rdicroce overall change looks great, just a few more comments on specifics...

@rdicroce
Copy link
Contributor Author

Pushed another commit that addresses reviewers' comments.

@normanmaurer
Copy link
Member

@njhill can you have a look again ?

Copy link
Member

@njhill njhill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM apart from my comment #9924 (comment) re adding a clarifying comment to the logic.

@normanmaurer
Copy link
Member

@netty test this please

@normanmaurer
Copy link
Member

@rdicroce please fix check style:

16:10:38 [ERROR] /code/codec/src/main/java/io/netty/handler/codec/compression/ZlibDecoder.java:89: an empty line before } [RegexpMultiline]
16:10:38 Audit done.

@rdicroce
Copy link
Contributor Author

@normanmaurer Done.

@normanmaurer
Copy link
Member

@netty-bot test this please

@rdicroce
Copy link
Contributor Author

@normanmaurer Build failure is due to constructors on ZlibDecoder being changed from public to protected. Do you want me to undo that?

@normanmaurer
Copy link
Member

@rdicroce yes please

@normanmaurer
Copy link
Member

@netty-bot test this please

@normanmaurer
Copy link
Member

@rdicroce seems to cause some unit tests to fail.. can you check ?

@rdicroce
Copy link
Contributor Author

Somehow none of us noticed that testMaxAllocation() was broken - it was using uncompressed data. I've fixed that along with the test failures.

@normanmaurer
Copy link
Member

@netty-bot test this please

@rdicroce
Copy link
Contributor Author

Test failure looks unrelated.

@normanmaurer
Copy link
Member

@netty-bot test this please

@normanmaurer normanmaurer merged commit 1543218 into netty:4.1 Jan 31, 2020
@normanmaurer
Copy link
Member

@rdicroce thanks a lot!

@normanmaurer normanmaurer added this to the 4.1.46.Final milestone Jan 31, 2020
normanmaurer pushed a commit that referenced this pull request Jan 31, 2020
…ers (#9924)

Motivation:
It is impossible to know in advance how much memory will be needed to
decompress a stream of bytes that was compressed using the DEFLATE
algorithm. In theory, up to 1032 times the compressed size could be
needed. For untrusted input, an attacker could exploit this to exhaust
the memory pool.

Modifications:
ZlibDecoder and its subclasses now support an optional limit on the size
of the decompressed buffer. By default, if the limit is reached,
decompression stops and a DecompressionException is thrown. Behavior
upon reaching the limit is modifiable by subclasses in case they desire
something else.

Result:
The decompressed buffer can now be limited to a configurable size, thus
mitigating the possibility of memory pool exhaustion.
@rdicroce rdicroce deleted the maxAlloc branch January 31, 2020 14:03
ihanyong pushed a commit to ihanyong/netty that referenced this pull request Jul 31, 2020
…ers (netty#9924)

Motivation:
It is impossible to know in advance how much memory will be needed to
decompress a stream of bytes that was compressed using the DEFLATE
algorithm. In theory, up to 1032 times the compressed size could be
needed. For untrusted input, an attacker could exploit this to exhaust
the memory pool.

Modifications:
ZlibDecoder and its subclasses now support an optional limit on the size
of the decompressed buffer. By default, if the limit is reached,
decompression stops and a DecompressionException is thrown. Behavior
upon reaching the limit is modifiable by subclasses in case they desire
something else.

Result:
The decompressed buffer can now be limited to a configurable size, thus
mitigating the possibility of memory pool exhaustion.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Compression/Decompression Codecs should enforce memory allocation size limits
5 participants