Improve memory allocation and validation #401
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is a general proposal for how the commons-imaging code could better handle allocations to protect against malicious image data causing high memory consumption. The changes do not show any specific exploit or similar.
Even if you don't agree with the exact code changes here, maybe the general concept is still useful? Or feel free to pick what you like, and adjust it.
The general concept here is that allocations go through methods of the
Allocator
class to make it explicit whether allocations are assumed to be trusted (e.g. when writing image data) or untrusted (when reading image data). Of course this is not completely foolproof, but at least it makes the intentions of the developers more clear.The methods for untrusted allocations can perform additional validations then, such as restricting the maximum size or when pre-sizing for example an
ArrayList
to clamp the initial capacity to a reasonable maximum to then see if the (potentially malicious) image data actually provides that many elements.The other part is the new
KnownSizeByteArrayBuilder
class which allows building anbyte[]
with a known size, but without eagerly allocating it to make sure the input data actually contains that many bytes and has not been maliciously crafted. It also avoids the overhead of boxing which aList<Byte>
would have, and also due to starting with a known expected size it avoids creating too large temporary arrays in the process, which general "byte array builder" classes might do.However, possibly that
KnownSizeByteArrayBuilder
class can be replaced with similar Commons IO classes and methods if you prefer that.These changes might not cover every aspect where memory allocation could possibly be exploited for a denial of service, but I think they cover at least some. I have not tested the effect this has on performance though.
Originally I provided these changes privately to the commons-imaging maintainers, but apparently did not got any response at all. So I hope at least this way here this adds some value, even if it just serves as inspiration for other changes.
I know that this merge request has conflicts, but I am not planning to resolve them unless there is actually strong interest in these changes. I was already not very happy about getting no feedback at all (despite being asked to "contribute to the solution of this issue") when I originally invested quite some time into this.