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

Use size_t for DWA buffersize calculation #901

Merged

Conversation

peterhillman
Copy link
Contributor

Extend #894 to use size_t instead of int for all buffer size calculation in initializeBuffers, and tidy up unnecessary casts
Addresses https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29653

Signed-off-by: Peter Hillman peterh@wetafx.co.nz

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
@meshula
Copy link
Contributor

meshula commented Jan 18, 2021

size_t is one of those scary types due to the way it's defined as being "at least 65535"... Thankfully SIZE_MAX on MSVC/64 is 2 ** 64, which is the platform where I would have expected a silly pitfall. I suggest adding a compile time assert that size_t is at least 64 bits on 64 bit platforms to ensure we don't have problems with files over 2**32 bytes in size. I'm sure that's the first thing a fuzzer is going to try :)

@lgritz
Copy link
Contributor

lgritz commented Jan 18, 2021

@meshula I think that has to be the case, because size_t is guaranteed to be the biggest size of anything with a size() method. It has to be big enough to represent the biggest addressable memory size.

@meshula
Copy link
Contributor

meshula commented Jan 18, 2021

@lgritz That's what I expect as well, and observe with the three compilers I use. This caveat in the spec always makes me worry. It seems like a poison pill to let one compiler do something bonkers:

  • size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.

This caveat bugs me so much, I use the sized types, like uint32_t everywhere in my code now except for when I'm dealing with std routines that explicitly return a size_t.

Note also the caveat of "anything with a size() method"... The code in question here is

size_t rleAmount = 2 * pixelCount * OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type);

I think that the type we want is ptrdiff_t, because that's the type that's guaranteed by spec to represent the biggest addressable memory size

Copy link
Contributor

@meshula meshula left a comment

Choose a reason for hiding this comment

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

I think ptrdiff_t is the more appropriate type here, per the conversation with @lgritz in the main thread.

@meshula
Copy link
Contributor

meshula commented Jan 18, 2021

Please note that I hit Approve before the conversation with Larry, and don't seem to be able to change Approve back to Comment, hence the discrepancy between comments and approval status...

@lgritz
Copy link
Contributor

lgritz commented Jan 18, 2021

When I read that quote, what it appears to say is that size_t is safe for array indexing, but that other types, like regular unsigned int or uint32_t may not be, because they aren't guaranteed to be big enough to index into all possible arrays.

ptrdiff_t is the signed equivalent to size_t -- it's the thing that you know is guaranteed to safely hold the difference between any two addresses on that architecture.

@meshula
Copy link
Contributor

meshula commented Jan 18, 2021

Right --- uintptr_t would be the choice, not ptrdiff_t.

@peterhillman
Copy link
Contributor Author

Well, size_t "can store the maximum size of a theoretically possible object of any type (including array)" and is the type passed to new, which is what it's used for here.

I switched those variables to size_t because they are ultimately copied to member variables which are of type size_t:

size_t _packedAcBufferSize;

It appears those values ultimately get written into the files as Int64, so maybe changing these types to Int64, including in the header, would be safest? That would change the memory layout of the DwaCompressor object on some architectures, which I was trying to avoid.

In the reported fuzz issue, there's a file which caused a signed int overflow in the buffer size calculation. Maybe the answer is to use Int64 for the calculation, then test the value is less than limits<size_t>::max before casting to size_t in the new?

@meshula
Copy link
Contributor

meshula commented Jan 18, 2021

That would work. Going to back to the root issue, I do think we need to use a principled int64 all the way through.

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
Copy link
Contributor

@meshula meshula left a comment

Choose a reason for hiding this comment

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

looks solid

@cary-ilm cary-ilm merged commit 0e08c95 into AcademySoftwareFoundation:master Jan 20, 2021
cary-ilm pushed a commit to cary-ilm/openexr that referenced this pull request Feb 6, 2021
)

* Use size_t for DWA buffersize calculation

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* use Int64 instead of size_t for buffersize calculations

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
Signed-off-by: Cary Phillips <cary@ilm.com>
cary-ilm added a commit that referenced this pull request Feb 12, 2021
* Revert "Disable OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX when building on arm64 macOS"

This reverts commit 67053eb.

Signed-off-by: Harry Mallon <hjmallon@gmail.com>

* Fix Apple Universal 2 (arm64/x86_64) builds

* In these types of builds we want arm64 and x86_64 (with AVX optimisations).
  However the way cmake works (with `CMAKE_OSX_ARCHITECTURES="arm64;x86_64"`
  means that we share one OpenEXRConfigInternal.h between both builds. So
  we have to have OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX mean "AVX GCC asm is
  available if platform is x86", rather than "AVX GCC asm is available".
  Then we decide on AVX optimisations based on that #define and also the
  platform defines.

Signed-off-by: Harry Mallon <hjmallon@gmail.com>

* Include <limits> where required by newer compilers (#893)

* Include <limits> where required by newer compilers

Signed-off-by: Cary Phillips <cary@ilm.com>

* Removed redundant #include <limits>

Signed-off-by: Cary Phillips <cary@ilm.com>

* add buffer size validation to FastHuf decode

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* prevent overflow in RgbaFile cachePadding

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* Use size_t for DWA buffersize calculation (#901)

* Use size_t for DWA buffersize calculation

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* use Int64 instead of size_t for buffersize calculations

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
Signed-off-by: Cary Phillips <cary@ilm.com>

* prevent overflows by using Int64 for all vars in DWA initialize (#903)

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
Signed-off-by: Cary Phillips <cary@ilm.com>

* update tileoffset sanitycheck to handle ripmaps  (#910)

* update tileoffset sanitycheck to handle ripmaps

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* slight reorganization

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* slight reorganization

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* remove extra if statement from validateStreamSize

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
Signed-off-by: Cary Phillips <cary@ilm.com>

* additional verification of DWA data sizes (#914)

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* Release notes for v2.5.5

Signed-off-by: Cary Phillips <cary@ilm.com>

* fix merge of ImfTiledInputFile.cpp

Signed-off-by: Cary Phillips <cary@ilm.com>

* Bump version for 2.5.5

Signed-off-by: Cary Phillips <cary@ilm.com>

* Only wait for and join joinable threads (#921)

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fixed botched merge or IlmThread.cpp/IlmThreadPool.cpp

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix 2.5.5 release date

Signed-off-by: Cary Phillips <cary@ilm.com>

Co-authored-by: Harry Mallon <hjmallon@gmail.com>
Co-authored-by: Peter Hillman <peterh@wetafx.co.nz>
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Mar 17, 2021
## Version 2.5.5 (February 12, 2021)

Patch release with various bug/sanitizer/security fixes, primarily
related to reading corrupted input files, but also a fix for universal
build support on macOS.

Specific OSS-fuzz issues include:

* OSS-fuzz [#30291](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30291)
* OSS-fuzz [#29106](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29106)
* OSS-fuzz [#28971](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=28971)
* OSS-fuzz [#29829](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29829)
* OSS-fuzz [#30121](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=30121)

### Merged Pull Requests

* [#914](AcademySoftwareFoundation/openexr#914) additional verification of DWA data sizes
* [#910](AcademySoftwareFoundation/openexr#910) update tileoffset sanitycheck to handle ripmaps
* [#903](AcademySoftwareFoundation/openexr#903) prevent overflows by using Int64 for all vars in DWA initialize
* [#901](AcademySoftwareFoundation/openexr#901) Use size_t for DWA buffersize calculation
* [#897](AcademySoftwareFoundation/openexr#897) prevent overflow in RgbaFile cachePadding
* [#896](AcademySoftwareFoundation/openexr#896) add buffer size validation to FastHuf decode
* [#893](AcademySoftwareFoundation/openexr#893) Include <limits> where required by newer compilers
* [#889](AcademySoftwareFoundation/openexr#889) Add explicit #include <limits> for numeric_limits
* [#854](AcademySoftwareFoundation/openexr#854) Fix Apple Universal 2 (arm64/x86_64) builds
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants