diff --git a/26ec3953d46bb5756b97955661565bcbc6647abf.patch b/26ec3953d46bb5756b97955661565bcbc6647abf.patch new file mode 100644 index 0000000000000000000000000000000000000000..4d2ba07e5388ce5031b0be4eddef785c81bd525d --- /dev/null +++ b/26ec3953d46bb5756b97955661565bcbc6647abf.patch @@ -0,0 +1,25 @@ +From 26ec3953d46bb5756b97955661565bcbc6647abf Mon Sep 17 00:00:00 2001 +From: Dirk Farin +Date: Thu, 14 Dec 2023 13:38:11 +0100 +Subject: [PATCH] fix #1042 (EXIF offset larger than data) + +--- + examples/encoder_jpeg.cc | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/examples/encoder_jpeg.cc b/examples/encoder_jpeg.cc +index bbf24396ba..84f1d7ec9b 100644 +--- a/examples/encoder_jpeg.cc ++++ b/examples/encoder_jpeg.cc +@@ -178,6 +178,11 @@ bool JpegEncoder::Encode(const struct heif_image_handle* handle, + uint32_t skip = (exifdata[0]<<24) | (exifdata[1]<<16) | (exifdata[2]<<8) | exifdata[3]; + skip += 4; + ++ if (skip > exifsize) { ++ fprintf(stderr, "Invalid EXIF data (offset too large)\n"); ++ return false; ++ } ++ + uint8_t* ptr = exifdata + skip; + size_t size = exifsize - skip; + diff --git a/56ef61d8daa55b56d782e5d8ab6f0ed31b98b494.patch b/56ef61d8daa55b56d782e5d8ab6f0ed31b98b494.patch new file mode 100644 index 0000000000000000000000000000000000000000..966b215d3aeebc0450bf36ebe5e17652e3f4d98a --- /dev/null +++ b/56ef61d8daa55b56d782e5d8ab6f0ed31b98b494.patch @@ -0,0 +1,24 @@ +From 2bf226a300951e6897ee7267d0dd379ba5ad7287 Mon Sep 17 00:00:00 2001 +From: Brad Hards +Date: Thu, 30 Nov 2023 19:55:18 +1100 +Subject: [PATCH] uncompressed: protect against broken uncC box component + references + +--- + libheif/uncompressed_image.cc | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/libheif/uncompressed_image.cc b/libheif/uncompressed_image.cc +index 5218165b23..c91e5dba4f 100644 +--- a/libheif/uncompressed_image.cc ++++ b/libheif/uncompressed_image.cc +@@ -534,6 +534,9 @@ int UncompressedImageCodec::get_luma_bits_per_pixel_from_configuration_unci(cons + int alternate_channel_bits = 0; + for (Box_uncC::Component component : uncC_box->get_components()) { + uint16_t component_index = component.component_index; ++ if (component_index >= cmpd_box->get_components().size()) { ++ return -1; ++ } + auto component_type = cmpd_box->get_components()[component_index].component_type; + switch (component_type) { + case component_type_monochrome: diff --git a/730a9d80bea3434f75c79e721878cc67f3889969.patch b/730a9d80bea3434f75c79e721878cc67f3889969.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1464c480b3e488647e098ee65671aed92c8a864 --- /dev/null +++ b/730a9d80bea3434f75c79e721878cc67f3889969.patch @@ -0,0 +1,208 @@ +From 730a9d80bea3434f75c79e721878cc67f3889969 Mon Sep 17 00:00:00 2001 +From: Dirk Farin +Date: Thu, 14 Dec 2023 16:09:05 +0100 +Subject: [PATCH] fix integer overflows when reading EXIF tags (fixes #1043) + (CVE-2023-49462) + +--- + examples/encoder_jpeg.cc | 2 +- + libheif/exif.cc | 78 +++++++++++++++++++++------------------- + libheif/exif.h | 4 +-- + 3 files changed, 44 insertions(+), 40 deletions(-) + +diff --git a/examples/encoder_jpeg.cc b/examples/encoder_jpeg.cc +index 84f1d7ec9b..41a0eefad6 100644 +--- a/examples/encoder_jpeg.cc ++++ b/examples/encoder_jpeg.cc +@@ -187,7 +187,7 @@ bool JpegEncoder::Encode(const struct heif_image_handle* handle, + size_t size = exifsize - skip; + + // libheif by default normalizes the image orientation, so that we have to set the EXIF Orientation to "Horizontal (normal)" +- modify_exif_orientation_tag_if_it_exists(ptr, (int)size, 1); ++ modify_exif_orientation_tag_if_it_exists(ptr, size, 1); + + // We have to limit the size for the memcpy, otherwise GCC warns that we exceed the maximum size. + if (size>0x1000000) { +diff --git a/libheif/exif.cc b/libheif/exif.cc +index ded0a2d29a..82c3cd1328 100644 +--- a/libheif/exif.cc ++++ b/libheif/exif.cc +@@ -25,12 +25,12 @@ + #define DEFAULT_EXIF_ORIENTATION 1 + #define EXIF_TAG_ORIENTATION 0x112 + ++// Note: As far as I can see, it is not defined in the EXIF standard whether the offsets and counts of the IFD is signed or unsigned. ++// We assume that these are all unsigned. + +-static int32_t read32(const uint8_t* data, int size, int pos, bool littleEndian) ++static uint32_t read32(const uint8_t* data, uint32_t size, uint32_t pos, bool littleEndian) + { +- if (pos + 4 > size) { +- return -1; +- } ++ assert(pos <= size - 4); + + const uint8_t* p = data + pos; + +@@ -43,28 +43,24 @@ static int32_t read32(const uint8_t* data, int size, int pos, bool littleEndian) + } + + +-static int32_t read16(const uint8_t* data, int size, int pos, bool littleEndian) ++static uint16_t read16(const uint8_t* data, uint32_t size, uint32_t pos, bool littleEndian) + { +- if (pos + 2 > size) { +- return -1; +- } ++ assert(pos <= size - 2); + + const uint8_t* p = data + pos; + + if (littleEndian) { +- return (p[1] << 8) | p[0]; ++ return static_cast((p[1] << 8) | p[0]); + } + else { +- return (p[0] << 8) | p[1]; ++ return static_cast((p[0] << 8) | p[1]); + } + } + + +-static void write16(uint8_t* data, int size, int pos, uint16_t value, bool littleEndian) ++static void write16(uint8_t* data, uint32_t size, uint32_t pos, uint16_t value, bool littleEndian) + { +- if (pos + 2 > size) { +- return; +- } ++ assert(pos <= size - 2); + + uint8_t* p = data + pos; + +@@ -78,16 +74,16 @@ static void write16(uint8_t* data, int size, int pos, uint16_t value, bool littl + } + } + +- +-static int find_exif_tag(const uint8_t* exif, int size, uint16_t query_tag, bool* out_littleEndian) ++// Returns 0 if the query_tag was not found. ++static uint32_t find_exif_tag(const uint8_t* exif, uint32_t size, uint16_t query_tag, bool* out_littleEndian) + { + if (size < 4) { +- return -1; ++ return 0; + } + + if ((exif[0] != 'I' && exif[0] != 'M') || + (exif[1] != 'I' && exif[1] != 'M')) { +- return -1; ++ return 0; + } + + bool littleEndian = (exif[0] == 'I'); +@@ -95,14 +91,22 @@ static int find_exif_tag(const uint8_t* exif, int size, uint16_t query_tag, boo + assert(out_littleEndian); + *out_littleEndian = littleEndian; + +- int offset = read32(exif, size, 4, littleEndian); +- if (offset < 0) { +- return -1; ++ uint32_t offset = read32(exif, size, 4, littleEndian); ++ ++ if (size - 2 < offset) { ++ return 0; + } + +- int cnt = read16(exif, size, offset, littleEndian); +- if (cnt < 1) { +- return -1; ++ uint16_t cnt = read16(exif, size, offset, littleEndian); ++ ++ // Does the IFD table fit into our memory range? We need this to prevent an underflow in the following statement. ++ if (2U + cnt * 12U > size) { ++ return 0; ++ } ++ ++ // end of IFD table would exceed the end of the EXIF data ++ if (size - 2U - cnt * 12U > offset) { ++ return 0; + } + + for (int i = 0; i < cnt; i++) { +@@ -114,20 +118,20 @@ static int find_exif_tag(const uint8_t* exif, int size, uint16_t query_tag, boo + + // TODO: do we have to also scan the next IFD table ? + +- return -1; ++ return 0; + } + + +-void modify_exif_tag_if_it_exists(uint8_t* exif, int size, uint16_t modify_tag, uint16_t modify_value) ++void modify_exif_tag_if_it_exists(uint8_t* exif, uint32_t size, uint16_t modify_tag, uint16_t modify_value) + { + bool little_endian; +- int pos = find_exif_tag(exif, size, modify_tag, &little_endian); +- if (pos < 0) { ++ uint32_t pos = find_exif_tag(exif, size, modify_tag, &little_endian); ++ if (pos == 0) { + return; + } + +- int type = read16(exif, size, pos + 2, little_endian); +- int count = read32(exif, size, pos + 4, little_endian); ++ uint16_t type = read16(exif, size, pos + 2, little_endian); ++ uint32_t count = read32(exif, size, pos + 4, little_endian); + + if (type == EXIF_TYPE_SHORT && count == 1) { + write16(exif, size, pos + 8, modify_value, little_endian); +@@ -135,26 +139,26 @@ void modify_exif_tag_if_it_exists(uint8_t* exif, int size, uint16_t modify_tag, + } + + +-void modify_exif_orientation_tag_if_it_exists(uint8_t* exifData, int size, uint16_t orientation) ++void modify_exif_orientation_tag_if_it_exists(uint8_t* exifData, uint32_t size, uint16_t orientation) + { + modify_exif_tag_if_it_exists(exifData, size, EXIF_TAG_ORIENTATION, orientation); + } + + +-int read_exif_orientation_tag(const uint8_t* exif, int size) ++int read_exif_orientation_tag(const uint8_t* exif, uint32_t size) + { + bool little_endian; +- int pos = find_exif_tag(exif, size, EXIF_TAG_ORIENTATION, &little_endian); +- if (pos < 0) { ++ uint32_t pos = find_exif_tag(exif, size, EXIF_TAG_ORIENTATION, &little_endian); ++ if (pos == 0) { + return DEFAULT_EXIF_ORIENTATION; + } + +- int type = read16(exif, size, pos + 2, little_endian); +- int count = read32(exif, size, pos + 4, little_endian); ++ uint16_t type = read16(exif, size, pos + 2, little_endian); ++ uint32_t count = read32(exif, size, pos + 4, little_endian); + + if (type == EXIF_TYPE_SHORT && count == 1) { + return read16(exif, size, pos + 8, little_endian); + } + + return DEFAULT_EXIF_ORIENTATION; +-} +\ No newline at end of file ++} +diff --git a/libheif/exif.h b/libheif/exif.h +index e877eaf5b1..7598c65534 100644 +--- a/libheif/exif.h ++++ b/libheif/exif.h +@@ -24,8 +24,8 @@ + #include + #include + +-int read_exif_orientation_tag(const uint8_t* exif, int size); ++int read_exif_orientation_tag(const uint8_t* exif, uint32_t size); + +-void modify_exif_orientation_tag_if_it_exists(uint8_t* exifData, int size, uint16_t orientation); ++void modify_exif_orientation_tag_if_it_exists(uint8_t* exifData, uint32_t size, uint16_t orientation); + + #endif //LIBHEIF_EXIF_H diff --git a/fd5b02aca3e29088bf0a1fc400bd661be4a6ed76.patch b/fd5b02aca3e29088bf0a1fc400bd661be4a6ed76.patch new file mode 100644 index 0000000000000000000000000000000000000000..dc12b430a1f4282c0d247cd41aa36bdac4cf8bf8 --- /dev/null +++ b/fd5b02aca3e29088bf0a1fc400bd661be4a6ed76.patch @@ -0,0 +1,28 @@ +From fd5b02aca3e29088bf0a1fc400bd661be4a6ed76 Mon Sep 17 00:00:00 2001 +From: zhailiangliang +Date: Thu, 14 Dec 2023 16:42:14 +0800 +Subject: [PATCH] fix null pointer dereference in + libheif/uncompressed_image.cc:758 + +--- + libheif/uncompressed_image.cc | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/libheif/uncompressed_image.cc b/libheif/uncompressed_image.cc +index c91e5dba4f..487d4cedbe 100644 +--- a/libheif/uncompressed_image.cc ++++ b/libheif/uncompressed_image.cc +@@ -616,6 +616,13 @@ Error UncompressedImageCodec::decode_uncompressed_image(const std::shared_ptr - 1.17.5-1 +- Init package diff --git a/libheif.yaml b/libheif.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2a337f20c56de2ab689eaa91c2d93af9f51f3e5d --- /dev/null +++ b/libheif.yaml @@ -0,0 +1,4 @@ +version_control: github +src_repo: strukturag/libheif +tag_prefix: "^v" +separator: "."