mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
fix: png_write_iCCP
check on profile length
This is a regression of commit a8242dd9473a8da4d851623cf0b514a8ee4bee34 "PNGv3 colourspace precedence rules conformance". Previously, `png_write_iCCP` used the length from the first four bytes of the profile set by `png_set_iCCP`, rather than the actual data length recorded by `png_set_iCCP`. If the profile data were less than 4 bytes long, it would have caused a read-beyond-end-of-malloc error. This bug was in the libpng code even before the changes introduced in the above-mentioned commit, but it was inaccessible. It became accessible when we removed the pre-PNGv3 colour space checks in `png_set_iCCP`. Reported-by: Bob Friesenhahn <bobjfriesenhahn@gmail.com> Reviewed-by: Cosmin Truta <ctruta@gmail.com> Signed-off-by: John Bowler <jbowler@acm.org> Signed-off-by: Cosmin Truta <ctruta@gmail.com>
This commit is contained in:
parent
8c7ed2e3b2
commit
68e090e700
@ -1276,10 +1276,10 @@ PNG_INTERNAL_FUNCTION(void,png_write_eXIf,(png_structrp png_ptr,
|
|||||||
|
|
||||||
#ifdef PNG_WRITE_iCCP_SUPPORTED
|
#ifdef PNG_WRITE_iCCP_SUPPORTED
|
||||||
PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
|
PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
|
||||||
png_const_charp name, png_const_bytep profile), PNG_EMPTY);
|
png_const_charp name, png_const_bytep profile, png_uint_32 proflen),
|
||||||
/* The profile must have been previously validated for correctness, the
|
PNG_EMPTY);
|
||||||
* length comes from the first four bytes. Only the base, deflate,
|
/* Writes a previously 'set' profile. The profile argument is **not**
|
||||||
* compression is supported.
|
* compressed.
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
|
|||||||
if ((info_ptr->valid & PNG_INFO_iCCP) != 0)
|
if ((info_ptr->valid & PNG_INFO_iCCP) != 0)
|
||||||
{
|
{
|
||||||
png_write_iCCP(png_ptr, info_ptr->iccp_name,
|
png_write_iCCP(png_ptr, info_ptr->iccp_name,
|
||||||
info_ptr->iccp_profile);
|
info_ptr->iccp_profile, info_ptr->iccp_proflen);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@ -1132,10 +1132,9 @@ png_write_sRGB(png_structrp png_ptr, int srgb_intent)
|
|||||||
/* Write an iCCP chunk */
|
/* Write an iCCP chunk */
|
||||||
void /* PRIVATE */
|
void /* PRIVATE */
|
||||||
png_write_iCCP(png_structrp png_ptr, png_const_charp name,
|
png_write_iCCP(png_structrp png_ptr, png_const_charp name,
|
||||||
png_const_bytep profile)
|
png_const_bytep profile, png_uint_32 profile_len)
|
||||||
{
|
{
|
||||||
png_uint_32 name_len;
|
png_uint_32 name_len;
|
||||||
png_uint_32 profile_len;
|
|
||||||
png_byte new_name[81]; /* 1 byte for the compression byte */
|
png_byte new_name[81]; /* 1 byte for the compression byte */
|
||||||
compression_state comp;
|
compression_state comp;
|
||||||
png_uint_32 temp;
|
png_uint_32 temp;
|
||||||
@ -1148,11 +1147,12 @@ png_write_iCCP(png_structrp png_ptr, png_const_charp name,
|
|||||||
if (profile == NULL)
|
if (profile == NULL)
|
||||||
png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
|
png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
|
||||||
|
|
||||||
profile_len = png_get_uint_32(profile);
|
|
||||||
|
|
||||||
if (profile_len < 132)
|
if (profile_len < 132)
|
||||||
png_error(png_ptr, "ICC profile too short");
|
png_error(png_ptr, "ICC profile too short");
|
||||||
|
|
||||||
|
if (png_get_uint_32(profile) != profile_len)
|
||||||
|
png_error(png_ptr, "Incorrect data in iCCP");
|
||||||
|
|
||||||
temp = (png_uint_32) (*(profile+8));
|
temp = (png_uint_32) (*(profile+8));
|
||||||
if (temp > 3 && (profile_len & 0x03))
|
if (temp > 3 && (profile_len & 0x03))
|
||||||
png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
|
png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user