summaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-multimedia')
-rw-r--r--meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3109.patch41
-rw-r--r--meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3341.patch67
-rw-r--r--meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-48434.patch136
-rw-r--r--meta/recipes-multimedia/ffmpeg/ffmpeg_4.2.2.bb3
-rw-r--r--meta/recipes-multimedia/flac/files/CVE-2020-22219.patch197
-rw-r--r--meta/recipes-multimedia/flac/files/CVE-2021-0561.patch34
-rw-r--r--meta/recipes-multimedia/flac/flac_1.3.3.bb2
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1920.patch59
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1921.patch69
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1922-1923-1924-1925.patch214
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-2122.patch60
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.16.3.bb4
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer1.0_1.16.3.bb9
-rw-r--r--meta/recipes-multimedia/libpng/files/run-ptest29
-rw-r--r--meta/recipes-multimedia/libpng/libpng_1.6.37.bb15
-rw-r--r--meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2021-4156.patch30
-rw-r--r--meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2022-33065.patch46
-rw-r--r--meta/recipes-multimedia/libsndfile/libsndfile1_1.0.28.bb4
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-2867-CVE-2022-2868-CVE-2022-2869.patch159
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-34526.patch29
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-3570_3598.patch659
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-3597_3626_3627.patch123
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch277
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-3970.patch45
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-40090.patch548
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2022-48281.patch26
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-0795_0796_0797_0798_0799.patch157
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-0800_0801_0802_0803_0804.patch135
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-1916.patch91
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-25433.patch173
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-25434-CVE-2023-25435.patch94
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-26965.patch90
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-26966.patch35
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-2908.patch33
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-3316.patch59
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-3576.patch35
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-3618.patch47
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-40745.patch34
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-41175.patch67
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-52356.patch53
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-6228.patch30
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-6277-1.patch191
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-6277-2.patch152
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-6277-3.patch46
-rw-r--r--meta/recipes-multimedia/libtiff/files/CVE-2023-6277-4.patch94
-rw-r--r--meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch212
-rw-r--r--meta/recipes-multimedia/libtiff/tiff/CVE-2022-1355.patch62
-rw-r--r--meta/recipes-multimedia/libtiff/tiff_4.1.0.bb29
-rw-r--r--meta/recipes-multimedia/webp/files/CVE-2023-1999.patch55
-rw-r--r--meta/recipes-multimedia/webp/files/CVE-2023-4863-0001.patch366
-rw-r--r--meta/recipes-multimedia/webp/files/CVE-2023-4863-0002.patch53
-rw-r--r--meta/recipes-multimedia/webp/libwebp_1.1.0.bb6
52 files changed, 5280 insertions, 4 deletions
diff --git a/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3109.patch b/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3109.patch
new file mode 100644
index 0000000000..febf49cff2
--- /dev/null
+++ b/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3109.patch
@@ -0,0 +1,41 @@
+From 656cb0450aeb73b25d7d26980af342b37ac4c568 Mon Sep 17 00:00:00 2001
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Date: Tue, 15 Feb 2022 17:58:08 +0800
+Subject: [PATCH] avcodec/vp3: Add missing check for av_malloc
+
+Since the av_malloc() may fail and return NULL pointer,
+it is needed that the 's->edge_emu_buffer' should be checked
+whether the new allocation is success.
+
+Fixes: d14723861b ("VP3: fix decoding of videos with stride > 2048")
+
+CVE: CVE-2022-3109
+Upstream-Status: Backport [https://github.com/FFmpeg/FFmpeg/commit/656cb0450aeb73b25d7d26980af342b37ac4c568]
+Comments: Refreshed hunk
+
+Reviewed-by: Peter Ross <pross@xvid.org>
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
+---
+ libavcodec/vp3.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c
+index e9ab54d73677..e2418eb6fa04 100644
+--- a/libavcodec/vp3.c
++++ b/libavcodec/vp3.c
+@@ -2740,8 +2740,13 @@
+ if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0)
+ goto error;
+
+- if (!s->edge_emu_buffer)
++ if (!s->edge_emu_buffer) {
+ s->edge_emu_buffer = av_malloc(9 * FFABS(s->current_frame.f->linesize[0]));
++ if (!s->edge_emu_buffer) {
++ ret = AVERROR(ENOMEM);
++ goto error;
++ }
++ }
+
+ if (s->keyframe) {
+ if (!s->theora) {
diff --git a/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3341.patch b/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3341.patch
new file mode 100644
index 0000000000..fcbd9b3e1b
--- /dev/null
+++ b/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-3341.patch
@@ -0,0 +1,67 @@
+From 9cf652cef49d74afe3d454f27d49eb1a1394951e Mon Sep 17 00:00:00 2001
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Date: Wed, 23 Feb 2022 10:31:59 +0800
+Subject: [PATCH] avformat/nutdec: Add check for avformat_new_stream
+
+Check for failure of avformat_new_stream() and propagate
+the error code.
+
+Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
+
+CVE: CVE-2022-3341
+
+Upstream-Status: Backport [https://github.com/FFmpeg/FFmpeg/commit/9cf652cef49d74afe3d454f27d49eb1a1394951e]
+
+Comments: Refreshed Hunk
+Signed-off-by: Narpat Mali <narpat.mali@windriver.com>
+Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
+---
+ libavformat/nutdec.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
+index 0a8a700acf..f9ad2c0af1 100644
+--- a/libavformat/nutdec.c
++++ b/libavformat/nutdec.c
+@@ -351,8 +351,12 @@ static int decode_main_header(NUTContext *nut)
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+- for (i = 0; i < stream_count; i++)
+- avformat_new_stream(s, NULL);
++ for (i = 0; i < stream_count; i++) {
++ if (!avformat_new_stream(s, NULL)) {
++ ret = AVERROR(ENOMEM);
++ goto fail;
++ }
++ }
+
+ return 0;
+ fail:
+@@ -793,19 +793,23 @@
+ NUTContext *nut = s->priv_data;
+ AVIOContext *bc = s->pb;
+ int64_t pos;
+- int initialized_stream_count;
++ int initialized_stream_count, ret;
+
+ nut->avf = s;
+
+ /* main header */
+ pos = 0;
++ ret = 0;
+ do {
++ if (ret == AVERROR(ENOMEM))
++ return ret;
++
+ pos = find_startcode(bc, MAIN_STARTCODE, pos) + 1;
+ if (pos < 0 + 1) {
+ av_log(s, AV_LOG_ERROR, "No main startcode found.\n");
+ goto fail;
+ }
+- } while (decode_main_header(nut) < 0);
++ } while ((ret = decode_main_header(nut)) < 0);
+
+ /* stream headers */
+ pos = 0;
+
diff --git a/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-48434.patch b/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-48434.patch
new file mode 100644
index 0000000000..707073709a
--- /dev/null
+++ b/meta/recipes-multimedia/ffmpeg/ffmpeg/CVE-2022-48434.patch
@@ -0,0 +1,136 @@
+From d4b7b3c03ee2baf0166ce49dff17ec9beff684db Mon Sep 17 00:00:00 2001
+From: Anton Khirnov <anton@khirnov.net>
+Date: Fri, 2 Sep 2022 22:21:27 +0200
+Subject: [PATCH] lavc/pthread_frame: avoid leaving stale hwaccel state in
+ worker threads
+
+This state is not refcounted, so make sure it always has a well-defined
+owner.
+
+Remove the block added in 091341f2ab5bd35ca1a2aae90503adc74f8d3523, as
+this commit also solves that issue in a more general way.
+
+(cherry picked from commit cc867f2c09d2b69cee8a0eccd62aff002cbbfe11)
+Signed-off-by: Anton Khirnov <anton@khirnov.net>
+(cherry picked from commit 35aa7e70e7ec350319e7634a30d8d8aa1e6ecdda)
+Signed-off-by: Anton Khirnov <anton@khirnov.net>
+(cherry picked from commit 3bc28e9d1ab33627cea3c632dd6b0c33e22e93ba)
+Signed-off-by: Anton Khirnov <anton@khirnov.net>
+
+CVE: CVE-2022-48434
+Upstream-Status: Backport [https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/d4b7b3c03ee2baf0166ce49dff17ec9beff684db]
+Signed-off-by: Ranjitsinh Rathod ranjitsinh.rathod@kpit.com
+Comment: Hunk#6 refreshed to backport changes and other to remove patch-fuzz warnings
+---
+ libavcodec/pthread_frame.c | 46 +++++++++++++++++++++++++++++---------
+ 1 file changed, 35 insertions(+), 11 deletions(-)
+
+diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
+index 36ac0ac..bbc5ba6 100644
+--- a/libavcodec/pthread_frame.c
++++ b/libavcodec/pthread_frame.c
+@@ -135,6 +135,12 @@ typedef struct FrameThreadContext {
+ * Set for the first N packets, where N is the number of threads.
+ * While it is set, ff_thread_en/decode_frame won't return any results.
+ */
++
++ /* hwaccel state is temporarily stored here in order to transfer its ownership
++ * to the next decoding thread without the need for extra synchronization */
++ const AVHWAccel *stash_hwaccel;
++ void *stash_hwaccel_context;
++ void *stash_hwaccel_priv;
+ } FrameThreadContext;
+
+ #define THREAD_SAFE_CALLBACKS(avctx) \
+@@ -211,9 +217,17 @@ static attribute_align_arg void *frame_worker_thread(void *arg)
+ ff_thread_finish_setup(avctx);
+
+ if (p->hwaccel_serializing) {
++ /* wipe hwaccel state to avoid stale pointers lying around;
++ * the state was transferred to FrameThreadContext in
++ * ff_thread_finish_setup(), so nothing is leaked */
++ avctx->hwaccel = NULL;
++ avctx->hwaccel_context = NULL;
++ avctx->internal->hwaccel_priv_data = NULL;
++
+ p->hwaccel_serializing = 0;
+ pthread_mutex_unlock(&p->parent->hwaccel_mutex);
+ }
++ av_assert0(!avctx->hwaccel);
+
+ if (p->async_serializing) {
+ p->async_serializing = 0;
+@@ -275,14 +289,10 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src,
+ dst->color_range = src->color_range;
+ dst->chroma_sample_location = src->chroma_sample_location;
+
+- dst->hwaccel = src->hwaccel;
+- dst->hwaccel_context = src->hwaccel_context;
+-
+ dst->channels = src->channels;
+ dst->sample_rate = src->sample_rate;
+ dst->sample_fmt = src->sample_fmt;
+ dst->channel_layout = src->channel_layout;
+- dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data;
+
+ if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx ||
+ (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) {
+@@ -415,6 +425,12 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
+ pthread_mutex_unlock(&p->mutex);
+ return err;
+ }
++
++ /* transfer hwaccel state stashed from previous thread, if any */
++ av_assert0(!p->avctx->hwaccel);
++ FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel);
++ FFSWAP(void*, p->avctx->hwaccel_context, fctx->stash_hwaccel_context);
++ FFSWAP(void*, p->avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
+ }
+
+ av_packet_unref(&p->avpkt);
+@@ -616,6 +632,14 @@ void ff_thread_finish_setup(AVCodecContext *avctx) {
+ async_lock(p->parent);
+ }
+
++ /* save hwaccel state for passing to the next thread;
++ * this is done here so that this worker thread can wipe its own hwaccel
++ * state after decoding, without requiring synchronization */
++ av_assert0(!p->parent->stash_hwaccel);
++ p->parent->stash_hwaccel = avctx->hwaccel;
++ p->parent->stash_hwaccel_context = avctx->hwaccel_context;
++ p->parent->stash_hwaccel_priv = avctx->internal->hwaccel_priv_data;
++
+ pthread_mutex_lock(&p->progress_mutex);
+ if(atomic_load(&p->state) == STATE_SETUP_FINISHED){
+ av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n");
+@@ -657,13 +681,6 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
+
+ park_frame_worker_threads(fctx, thread_count);
+
+- if (fctx->prev_thread && fctx->prev_thread != fctx->threads)
+- if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) {
+- av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n");
+- fctx->prev_thread->avctx->internal->is_copy = fctx->threads->avctx->internal->is_copy;
+- fctx->threads->avctx->internal->is_copy = 1;
+- }
+-
+ for (i = 0; i < thread_count; i++) {
+ PerThreadContext *p = &fctx->threads[i];
+
+@@ -713,6 +730,13 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count)
+ pthread_mutex_destroy(&fctx->async_mutex);
+ pthread_cond_destroy(&fctx->async_cond);
+
++ /* if we have stashed hwaccel state, move it to the user-facing context,
++ * so it will be freed in avcodec_close() */
++ av_assert0(!avctx->hwaccel);
++ FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel);
++ FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context);
++ FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv);
++
+ av_freep(&avctx->internal->thread_ctx);
+
+ if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/ffmpeg/ffmpeg_4.2.2.bb b/meta/recipes-multimedia/ffmpeg/ffmpeg_4.2.2.bb
index cbfdbf0563..f12052548f 100644
--- a/meta/recipes-multimedia/ffmpeg/ffmpeg_4.2.2.bb
+++ b/meta/recipes-multimedia/ffmpeg/ffmpeg_4.2.2.bb
@@ -30,6 +30,9 @@ SRC_URI = "https://www.ffmpeg.org/releases/${BP}.tar.xz \
file://CVE-2021-3566.patch \
file://CVE-2021-38291.patch \
file://CVE-2022-1475.patch \
+ file://CVE-2022-3109.patch \
+ file://CVE-2022-3341.patch \
+ file://CVE-2022-48434.patch \
"
SRC_URI[md5sum] = "348956fc2faa57a2f79bbb84ded9fbc3"
SRC_URI[sha256sum] = "cb754255ab0ee2ea5f66f8850e1bd6ad5cac1cd855d0a2f4990fb8c668b0d29c"
diff --git a/meta/recipes-multimedia/flac/files/CVE-2020-22219.patch b/meta/recipes-multimedia/flac/files/CVE-2020-22219.patch
new file mode 100644
index 0000000000..e042872dc0
--- /dev/null
+++ b/meta/recipes-multimedia/flac/files/CVE-2020-22219.patch
@@ -0,0 +1,197 @@
+From 579ff6922089cbbbd179619e40e622e279bd719f Mon Sep 17 00:00:00 2001
+From: Martijn van Beurden <mvanb1@gmail.com>
+Date: Wed, 3 Aug 2022 13:52:19 +0200
+Subject: [PATCH] flac: Add and use _nofree variants of safe_realloc functions
+
+Parts of the code use realloc like
+
+x = safe_realloc(x, somesize);
+
+when this is the case, the safe_realloc variant used must free the
+old memory block in case it fails, otherwise it will leak. However,
+there are also instances in the code where handling is different:
+
+if (0 == (x = safe_realloc(y, somesize)))
+ return false
+
+in this case, y should not be freed, as y is not set to NULL we
+could encounter double frees. Here the safe_realloc_nofree
+functions are used.
+
+Upstream-Status: Backport [https://github.com/xiph/flac/commit/21fe95ee828b0b9b944f6aa0bb02d24fbb981815]
+CVE: CVE-2020-22219
+
+Signed-off-by: Meenali Gupta <meenali.gupta@windriver.com>
+---
+ include/share/alloc.h | 41 +++++++++++++++++++++++++++++++----
+ src/flac/encode.c | 4 ++--
+ src/flac/foreign_metadata.c | 2 +-
+ src/libFLAC/bitwriter.c | 2 +-
+ src/libFLAC/metadata_object.c | 2 +-
+ src/plugin_common/tags.c | 2 +-
+ src/share/utf8/iconvert.c | 2 +-
+ 7 files changed, 44 insertions(+), 11 deletions(-)
+
+diff --git a/include/share/alloc.h b/include/share/alloc.h
+index 914de9b..55bdd1d 100644
+--- a/include/share/alloc.h
++++ b/include/share/alloc.h
+@@ -161,17 +161,30 @@ static inline void *safe_realloc_(void *ptr, size_t size)
+ free(oldptr);
+ return newptr;
+ }
+-static inline void *safe_realloc_add_2op_(void *ptr, size_t size1, size_t size2)
++static inline void *safe_realloc_nofree_add_2op_(void *ptr, size_t size1, size_t size2)
++{
++ size2 += size1;
++ if(size2 < size1)
++ return 0;
++ return realloc(ptr, size2);
++}
++
++static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
+ {
+ size2 += size1;
+ if(size2 < size1) {
+ free(ptr);
+ return 0;
+ }
+- return realloc(ptr, size2);
++ size3 += size2;
++ if(size3 < size2) {
++ free(ptr);
++ return 0;
++ }
++ return safe_realloc_(ptr, size3);
+ }
+
+-static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
++static inline void *safe_realloc_nofree_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3)
+ {
+ size2 += size1;
+ if(size2 < size1)
+@@ -182,7 +195,7 @@ static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2,
+ return realloc(ptr, size3);
+ }
+
+-static inline void *safe_realloc_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
++static inline void *safe_realloc_nofree_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4)
+ {
+ size2 += size1;
+ if(size2 < size1)
+@@ -205,6 +218,15 @@ static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2)
+ return safe_realloc_(ptr, size1*size2);
+ }
+
++static inline void *safe_realloc_nofree_mul_2op_(void *ptr, size_t size1, size_t size2)
++{
++ if(!size1 || !size2)
++ return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
++ if(size1 > SIZE_MAX / size2)
++ return 0;
++ return realloc(ptr, size1*size2);
++}
++
+ /* size1 * (size2 + size3) */
+ static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
+ {
+@@ -216,4 +238,15 @@ static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2,
+ return safe_realloc_mul_2op_(ptr, size1, size2);
+ }
+
++/* size1 * (size2 + size3) */
++static inline void *safe_realloc_nofree_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3)
++{
++ if(!size1 || (!size2 && !size3))
++ return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */
++ size2 += size3;
++ if(size2 < size3)
++ return 0;
++ return safe_realloc_nofree_mul_2op_(ptr, size1, size2);
++}
++
+ #endif
+diff --git a/src/flac/encode.c b/src/flac/encode.c
+index a9b907f..f87250c 100644
+--- a/src/flac/encode.c
++++ b/src/flac/encode.c
+@@ -1743,10 +1743,10 @@ static void static_metadata_clear(static_metadata_t *m)
+ static FLAC__bool static_metadata_append(static_metadata_t *m, FLAC__StreamMetadata *d, FLAC__bool needs_delete)
+ {
+ void *x;
+- if(0 == (x = safe_realloc_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/)))
++ if(0 == (x = safe_realloc_nofree_muladd2_(m->metadata, sizeof(*m->metadata), /*times (*/m->num_metadata, /*+*/1/*)*/)))
+ return false;
+ m->metadata = (FLAC__StreamMetadata**)x;
+- if(0 == (x = safe_realloc_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/)))
++ if(0 == (x = safe_realloc_nofree_muladd2_(m->needs_delete, sizeof(*m->needs_delete), /*times (*/m->num_metadata, /*+*/1/*)*/)))
+ return false;
+ m->needs_delete = (FLAC__bool*)x;
+ m->metadata[m->num_metadata] = d;
+diff --git a/src/flac/foreign_metadata.c b/src/flac/foreign_metadata.c
+index 9ad9c18..fdfb3cf 100644
+--- a/src/flac/foreign_metadata.c
++++ b/src/flac/foreign_metadata.c
+@@ -75,7 +75,7 @@ static FLAC__bool copy_data_(FILE *fin, FILE *fout, size_t size, const char **er
+
+ static FLAC__bool append_block_(foreign_metadata_t *fm, FLAC__off_t offset, FLAC__uint32 size, const char **error)
+ {
+- foreign_block_t *fb = safe_realloc_muladd2_(fm->blocks, sizeof(foreign_block_t), /*times (*/fm->num_blocks, /*+*/1/*)*/);
++ foreign_block_t *fb = safe_realloc_nofree_muladd2_(fm->blocks, sizeof(foreign_block_t), /*times (*/fm->num_blocks, /*+*/1/*)*/);
+ if(fb) {
+ fb[fm->num_blocks].offset = offset;
+ fb[fm->num_blocks].size = size;
+diff --git a/src/libFLAC/bitwriter.c b/src/libFLAC/bitwriter.c
+index 6e86585..a510b0d 100644
+--- a/src/libFLAC/bitwriter.c
++++ b/src/libFLAC/bitwriter.c
+@@ -124,7 +124,7 @@ FLAC__bool bitwriter_grow_(FLAC__BitWriter *bw, uint32_t bits_to_add)
+ FLAC__ASSERT(new_capacity > bw->capacity);
+ FLAC__ASSERT(new_capacity >= bw->words + ((bw->bits + bits_to_add + FLAC__BITS_PER_WORD - 1) / FLAC__BITS_PER_WORD));
+
+- new_buffer = safe_realloc_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity);
++ new_buffer = safe_realloc_nofree_mul_2op_(bw->buffer, sizeof(bwword), /*times*/new_capacity);
+ if(new_buffer == 0)
+ return false;
+ bw->buffer = new_buffer;
+diff --git a/src/libFLAC/metadata_object.c b/src/libFLAC/metadata_object.c
+index de8e513..aef65be 100644
+--- a/src/libFLAC/metadata_object.c
++++ b/src/libFLAC/metadata_object.c
+@@ -98,7 +98,7 @@ static FLAC__bool free_copy_bytes_(FLAC__byte **to, const FLAC__byte *from, uint
+ /* realloc() failure leaves entry unchanged */
+ static FLAC__bool ensure_null_terminated_(FLAC__byte **entry, uint32_t length)
+ {
+- FLAC__byte *x = safe_realloc_add_2op_(*entry, length, /*+*/1);
++ FLAC__byte *x = safe_realloc_nofree_add_2op_(*entry, length, /*+*/1);
+ if (x != NULL) {
+ x[length] = '\0';
+ *entry = x;
+diff --git a/src/plugin_common/tags.c b/src/plugin_common/tags.c
+index ae440c5..dfa10d3 100644
+--- a/src/plugin_common/tags.c
++++ b/src/plugin_common/tags.c
+@@ -317,7 +317,7 @@ FLAC__bool FLAC_plugin__tags_add_tag_utf8(FLAC__StreamMetadata *tags, const char
+ const size_t value_len = strlen(value);
+ const size_t separator_len = strlen(separator);
+ FLAC__byte *new_entry;
+- if(0 == (new_entry = safe_realloc_add_4op_(entry->entry, entry->length, /*+*/value_len, /*+*/separator_len, /*+*/1)))
++ if(0 == (new_entry = safe_realloc_nofree_add_4op_(entry->entry, entry->length, /*+*/value_len, /*+*/separator_len, /*+*/1)))
+ return false;
+ memcpy(new_entry+entry->length, separator, separator_len);
+ entry->length += separator_len;
+diff --git a/src/share/utf8/iconvert.c b/src/share/utf8/iconvert.c
+index 8ab53c1..876c06e 100644
+--- a/src/share/utf8/iconvert.c
++++ b/src/share/utf8/iconvert.c
+@@ -149,7 +149,7 @@ int iconvert(const char *fromcode, const char *tocode,
+ iconv_close(cd1);
+ return ret;
+ }
+- newbuf = safe_realloc_add_2op_(utfbuf, (ob - utfbuf), /*+*/1);
++ newbuf = safe_realloc_nofree_add_2op_(utfbuf, (ob - utfbuf), /*+*/1);
+ if (!newbuf)
+ goto fail;
+ ob = (ob - utfbuf) + newbuf;
+--
+2.40.0
diff --git a/meta/recipes-multimedia/flac/files/CVE-2021-0561.patch b/meta/recipes-multimedia/flac/files/CVE-2021-0561.patch
new file mode 100644
index 0000000000..e19833a5ad
--- /dev/null
+++ b/meta/recipes-multimedia/flac/files/CVE-2021-0561.patch
@@ -0,0 +1,34 @@
+From e1575e4a7c5157cbf4e4a16dbd39b74f7174c7be Mon Sep 17 00:00:00 2001
+From: Neelkamal Semwal <neelkamal.semwal@ittiam.com>
+Date: Fri, 18 Dec 2020 22:28:36 +0530
+Subject: [PATCH] libFlac: Exit at EOS in verify mode
+
+When verify mode is enabled, once decoder flags end of stream,
+encode processing is considered complete.
+
+CVE-2021-0561
+
+Signed-off-by: Ralph Giles <giles@thaumas.net>
+
+Upstream-Status: Backport [https://github.com/xiph/flac/commit/e1575e4a7c5157cbf4e4a16dbd39b74f7174c7be]
+CVE: CVE-2021-0561
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ src/libFLAC/stream_encoder.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/libFLAC/stream_encoder.c b/src/libFLAC/stream_encoder.c
+index 4c91247fe8..7109802c27 100644
+--- a/src/libFLAC/stream_encoder.c
++++ b/src/libFLAC/stream_encoder.c
+@@ -2610,7 +2610,9 @@ FLAC__bool write_bitbuffer_(FLAC__StreamEncoder *encoder, uint32_t samples, FLAC
+ encoder->private_->verify.needs_magic_hack = true;
+ }
+ else {
+- if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder)) {
++ if(!FLAC__stream_decoder_process_single(encoder->private_->verify.decoder)
++ || (!is_last_block
++ && (FLAC__stream_encoder_get_verify_decoder_state(encoder) == FLAC__STREAM_DECODER_END_OF_STREAM))) {
+ FLAC__bitwriter_release_buffer(encoder->private_->frame);
+ FLAC__bitwriter_clear(encoder->private_->frame);
+ if(encoder->protected_->state != FLAC__STREAM_ENCODER_VERIFY_MISMATCH_IN_AUDIO_DATA)
diff --git a/meta/recipes-multimedia/flac/flac_1.3.3.bb b/meta/recipes-multimedia/flac/flac_1.3.3.bb
index cb6692aedf..e593727ac8 100644
--- a/meta/recipes-multimedia/flac/flac_1.3.3.bb
+++ b/meta/recipes-multimedia/flac/flac_1.3.3.bb
@@ -15,6 +15,8 @@ LIC_FILES_CHKSUM = "file://COPYING.FDL;md5=ad1419ecc56e060eccf8184a87c4285f \
DEPENDS = "libogg"
SRC_URI = "http://downloads.xiph.org/releases/flac/${BP}.tar.xz \
+ file://CVE-2020-22219.patch \
+ file://CVE-2021-0561.patch \
"
SRC_URI[md5sum] = "26703ed2858c1fc9ffc05136d13daa69"
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1920.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1920.patch
new file mode 100644
index 0000000000..ee33c5564d
--- /dev/null
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1920.patch
@@ -0,0 +1,59 @@
+From cf887f1b8e228bff6e19829e6d03995d70ad739d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
+Date: Wed, 18 May 2022 10:23:15 +0300
+Subject: [PATCH] matroskademux: Avoid integer-overflow resulting in heap
+ corruption in WavPack header handling code
+
+blocksize + WAVPACK4_HEADER_SIZE might overflow gsize, which then
+results in allocating a very small buffer. Into that buffer blocksize
+data is memcpy'd later which then causes out of bound writes and can
+potentially lead to anything from crashes to remote code execution.
+
+Thanks to Adam Doupe for analyzing and reporting the issue.
+
+CVE: CVE-2022-1920
+
+https://gstreamer.freedesktop.org/security/sa-2022-0004.html
+
+Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1226
+
+Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2612>
+
+https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/0df0dd7fe388174e4835eda4526b47f470a56370
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ .../gst/matroska/matroska-demux.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
+index 64cc6be60be..01d754c3eb9 100644
+--- a/gst/matroska/matroska-demux.c
++++ b/gst/matroska/matroska-demux.c
+@@ -3933,7 +3933,8 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
+ } else {
+ guint8 *outdata = NULL;
+ gsize buf_size, size;
+- guint32 block_samples, flags, crc, blocksize;
++ guint32 block_samples, flags, crc;
++ gsize blocksize;
+ GstAdapter *adapter;
+
+ adapter = gst_adapter_new ();
+@@ -3974,6 +3975,13 @@ gst_matroska_demux_add_wvpk_header (GstElement * element,
+ return GST_FLOW_ERROR;
+ }
+
++ if (blocksize > G_MAXSIZE - WAVPACK4_HEADER_SIZE) {
++ GST_ERROR_OBJECT (element, "Too big wavpack buffer");
++ gst_buffer_unmap (*buf, &map);
++ g_object_unref (adapter);
++ return GST_FLOW_ERROR;
++ }
++
+ g_assert (newbuf == NULL);
+
+ newbuf =
+--
+GitLab
+
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1921.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1921.patch
new file mode 100644
index 0000000000..99dbb2b1b0
--- /dev/null
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1921.patch
@@ -0,0 +1,69 @@
+From f503caad676971933dc0b52c4b313e5ef0d6dbb0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
+Date: Wed, 18 May 2022 12:00:48 +0300
+Subject: [PATCH] avidemux: Fix integer overflow resulting in heap corruption
+ in DIB buffer inversion code
+
+Check that width*bpp/8 doesn't overflow a guint and also that
+height*stride fits into the provided buffer without overflowing.
+
+Thanks to Adam Doupe for analyzing and reporting the issue.
+
+CVE: CVE-2022-1921
+
+See https://gstreamer.freedesktop.org/security/sa-2022-0001.html
+
+Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1224
+
+Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2608>
+
+https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/f503caad676971933dc0b52c4b313e5ef0d6dbb0
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ .../gst/avi/gstavidemux.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
+index eafe865494c..0d18a6495c7 100644
+--- a/gst/avi/gstavidemux.c
++++ b/gst/avi/gstavidemux.c
+@@ -4973,8 +4973,8 @@ swap_line (guint8 * d1, guint8 * d2, guint8 * tmp, gint bytes)
+ static GstBuffer *
+ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
+ {
+- gint y, w, h;
+- gint bpp, stride;
++ guint y, w, h;
++ guint bpp, stride;
+ guint8 *tmp = NULL;
+ GstMapInfo map;
+ guint32 fourcc;
+@@ -5001,12 +5001,23 @@ gst_avi_demux_invert (GstAviStream * stream, GstBuffer * buf)
+ h = stream->strf.vids->height;
+ w = stream->strf.vids->width;
+ bpp = stream->strf.vids->bit_cnt ? stream->strf.vids->bit_cnt : 8;
++
++ if ((guint64) w * ((guint64) bpp / 8) > G_MAXUINT - 4) {
++ GST_WARNING ("Width x stride overflows");
++ return buf;
++ }
++
++ if (w == 0 || h == 0) {
++ GST_WARNING ("Zero width or height");
++ return buf;
++ }
++
+ stride = GST_ROUND_UP_4 (w * (bpp / 8));
+
+ buf = gst_buffer_make_writable (buf);
+
+ gst_buffer_map (buf, &map, GST_MAP_READWRITE);
+- if (map.size < (stride * h)) {
++ if (map.size < ((guint64) stride * (guint64) h)) {
+ GST_WARNING ("Buffer is smaller than reported Width x Height x Depth");
+ gst_buffer_unmap (buf, &map);
+ return buf;
+--
+GitLab
+
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1922-1923-1924-1925.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1922-1923-1924-1925.patch
new file mode 100644
index 0000000000..ebffbc473d
--- /dev/null
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-1922-1923-1924-1925.patch
@@ -0,0 +1,214 @@
+From ad6012159acf18c6b5c0f4edf037e8c9a2dbc966 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
+Date: Wed, 18 May 2022 11:24:37 +0300
+Subject: [PATCH] matroskademux: Fix integer overflows in zlib/bz2/etc
+ decompression code
+
+Various variables were of smaller types than needed and there were no
+checks for any overflows when doing additions on the sizes. This is all
+checked now.
+
+In addition the size of the decompressed data is limited to 120MB now as
+any larger sizes are likely pathological and we can avoid out of memory
+situations in many cases like this.
+
+Also fix a bug where the available output size on the next iteration in
+the zlib/bz2 decompression code was provided too large and could
+potentially lead to out of bound writes.
+
+Thanks to Adam Doupe for analyzing and reporting the issue.
+
+CVE: CVE-2022-1922, CVE-2022-1923, CVE-2022-1924, CVE-2022-1925
+
+https://gstreamer.freedesktop.org/security/sa-2022-0002.html
+
+Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1225
+
+Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2610>
+
+CVE: CVE-2022-1922 CVE-2022-1923 CVE-2022-1924 CVE-2022-1925
+https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/ad6012159acf18c6b5c0f4edf037e8c9a2dbc966
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ .../gst/matroska/matroska-read-common.c | 76 +++++++++++++++----
+ 1 file changed, 61 insertions(+), 15 deletions(-)
+
+diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c
+index eb317644cc5..6fadbba9567 100644
+--- a/gst/matroska/matroska-read-common.c
++++ b/gst/matroska/matroska-read-common.c
+@@ -70,6 +70,10 @@ typedef struct
+ gboolean audio_only;
+ } TargetTypeContext;
+
++/* 120MB as maximum decompressed data size. Anything bigger is likely
++ * pathological, and like this we avoid out of memory situations in many cases
++ */
++#define MAX_DECOMPRESS_SIZE (120 * 1024 * 1024)
+
+ static gboolean
+ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+@@ -77,19 +81,23 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ GstMatroskaTrackCompressionAlgorithm algo)
+ {
+ guint8 *new_data = NULL;
+- guint new_size = 0;
++ gsize new_size = 0;
+ guint8 *data = *data_out;
+- guint size = *size_out;
++ const gsize size = *size_out;
+ gboolean ret = TRUE;
+
++ if (size > G_MAXUINT32) {
++ GST_WARNING ("too large compressed data buffer.");
++ ret = FALSE;
++ goto out;
++ }
++
+ if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_ZLIB) {
+ #ifdef HAVE_ZLIB
+ /* zlib encoded data */
+ z_stream zstream;
+- guint orig_size;
+ int result;
+
+- orig_size = size;
+ zstream.zalloc = (alloc_func) 0;
+ zstream.zfree = (free_func) 0;
+ zstream.opaque = (voidpf) 0;
+@@ -99,8 +107,8 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ goto out;
+ }
+ zstream.next_in = (Bytef *) data;
+- zstream.avail_in = orig_size;
+- new_size = orig_size;
++ zstream.avail_in = size;
++ new_size = size;
+ new_data = g_malloc (new_size);
+ zstream.avail_out = new_size;
+ zstream.next_out = (Bytef *) new_data;
+@@ -114,10 +122,18 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ break;
+ }
+
++ if (new_size > G_MAXSIZE - 4096 || new_size + 4096 > MAX_DECOMPRESS_SIZE) {
++ GST_WARNING ("too big decompressed data");
++ result = Z_MEM_ERROR;
++ break;
++ }
++
+ new_size += 4096;
+ new_data = g_realloc (new_data, new_size);
+ zstream.next_out = (Bytef *) (new_data + zstream.total_out);
+- zstream.avail_out += 4096;
++ /* avail_out is an unsigned int */
++ g_assert (new_size - zstream.total_out <= G_MAXUINT);
++ zstream.avail_out = new_size - zstream.total_out;
+ } while (zstream.avail_in > 0);
+
+ if (result != Z_STREAM_END) {
+@@ -137,13 +153,11 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ #ifdef HAVE_BZ2
+ /* bzip2 encoded data */
+ bz_stream bzstream;
+- guint orig_size;
+ int result;
+
+ bzstream.bzalloc = NULL;
+ bzstream.bzfree = NULL;
+ bzstream.opaque = NULL;
+- orig_size = size;
+
+ if (BZ2_bzDecompressInit (&bzstream, 0, 0) != BZ_OK) {
+ GST_WARNING ("bzip2 initialization failed.");
+@@ -152,8 +166,8 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ }
+
+ bzstream.next_in = (char *) data;
+- bzstream.avail_in = orig_size;
+- new_size = orig_size;
++ bzstream.avail_in = size;
++ new_size = size;
+ new_data = g_malloc (new_size);
+ bzstream.avail_out = new_size;
+ bzstream.next_out = (char *) new_data;
+@@ -167,17 +181,31 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ break;
+ }
+
++ if (new_size > G_MAXSIZE - 4096 || new_size + 4096 > MAX_DECOMPRESS_SIZE) {
++ GST_WARNING ("too big decompressed data");
++ result = BZ_MEM_ERROR;
++ break;
++ }
++
+ new_size += 4096;
+ new_data = g_realloc (new_data, new_size);
+- bzstream.next_out = (char *) (new_data + bzstream.total_out_lo32);
+- bzstream.avail_out += 4096;
++ bzstream.next_out =
++ (char *) (new_data + ((guint64) bzstream.total_out_hi32 << 32) +
++ bzstream.total_out_lo32);
++ /* avail_out is an unsigned int */
++ g_assert (new_size - ((guint64) bzstream.total_out_hi32 << 32) +
++ bzstream.total_out_lo32 <= G_MAXUINT);
++ bzstream.avail_out =
++ new_size - ((guint64) bzstream.total_out_hi32 << 32) +
++ bzstream.total_out_lo32;
+ } while (bzstream.avail_in > 0);
+
+ if (result != BZ_STREAM_END) {
+ ret = FALSE;
+ g_free (new_data);
+ } else {
+- new_size = bzstream.total_out_lo32;
++ new_size =
++ ((guint64) bzstream.total_out_hi32 << 32) + bzstream.total_out_lo32;
+ }
+ BZ2_bzDecompressEnd (&bzstream);
+
+@@ -189,7 +217,13 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_LZO1X) {
+ /* lzo encoded data */
+ int result;
+- int orig_size, out_size;
++ gint orig_size, out_size;
++
++ if (size > G_MAXINT) {
++ GST_WARNING ("too large compressed data buffer.");
++ ret = FALSE;
++ goto out;
++ }
+
+ orig_size = size;
+ out_size = size;
+@@ -203,6 +237,11 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ result = lzo1x_decode (new_data, &out_size, data, &orig_size);
+
+ if (orig_size > 0) {
++ if (new_size > G_MAXINT - 4096 || new_size + 4096 > MAX_DECOMPRESS_SIZE) {
++ GST_WARNING ("too big decompressed data");
++ result = LZO_ERROR;
++ break;
++ }
+ new_size += 4096;
+ new_data = g_realloc (new_data, new_size);
+ }
+@@ -221,6 +260,13 @@ gst_matroska_decompress_data (GstMatroskaTrackEncoding * enc,
+ } else if (algo == GST_MATROSKA_TRACK_COMPRESSION_ALGORITHM_HEADERSTRIP) {
+ /* header stripped encoded data */
+ if (enc->comp_settings_length > 0) {
++ if (size > G_MAXSIZE - enc->comp_settings_length
++ || size + enc->comp_settings_length > MAX_DECOMPRESS_SIZE) {
++ GST_WARNING ("too big decompressed data");
++ ret = FALSE;
++ goto out;
++ }
++
+ new_data = g_malloc (size + enc->comp_settings_length);
+ new_size = size + enc->comp_settings_length;
+
+--
+GitLab
+
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-2122.patch b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-2122.patch
new file mode 100644
index 0000000000..f4d38c270e
--- /dev/null
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good/CVE-2022-2122.patch
@@ -0,0 +1,60 @@
+From 14d306da6da51a762c4dc701d161bb52ab66d774 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
+Date: Mon, 30 May 2022 10:15:37 +0300
+Subject: [PATCH] qtdemux: Fix integer overflows in zlib decompression code
+
+Various variables were of smaller types than needed and there were no
+checks for any overflows when doing additions on the sizes. This is all
+checked now.
+
+In addition the size of the decompressed data is limited to 200MB now as
+any larger sizes are likely pathological and we can avoid out of memory
+situations in many cases like this.
+
+Also fix a bug where the available output size on the next iteration in
+the zlib decompression code was provided too large and could
+potentially lead to out of bound writes.
+
+Thanks to Adam Doupe for analyzing and reporting the issue.
+
+CVE: tbd
+
+https://gstreamer.freedesktop.org/security/sa-2022-0003.html
+
+Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/1225
+
+Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2610>
+
+https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/14d306da6da51a762c4dc701d161bb52ab66d774
+CVE: CVE-2022-2122
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ gst/isomp4/qtdemux.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 7cc346b1e63..97ba0799a8d 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -7905,10 +7905,16 @@ qtdemux_inflate (void *z_buffer, guint z_length, guint * length)
+ break;
+ }
+
++ if (*length > G_MAXUINT - 4096 || *length > QTDEMUX_MAX_SAMPLE_INDEX_SIZE) {
++ GST_WARNING ("too big decompressed data");
++ ret = Z_MEM_ERROR;
++ break;
++ }
++
+ *length += 4096;
+ buffer = (guint8 *) g_realloc (buffer, *length);
+ z.next_out = (Bytef *) (buffer + z.total_out);
+- z.avail_out += 4096;
++ z.avail_out += *length - z.total_out;
+ } while (z.avail_in > 0);
+
+ if (ret != Z_STREAM_END) {
+--
+GitLab
+
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.16.3.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.16.3.bb
index 1038cbf224..831a317a82 100644
--- a/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.16.3.bb
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.16.3.bb
@@ -10,6 +10,10 @@ SRC_URI = " \
file://0001-qt-include-ext-qt-gstqtgl.h-instead-of-gst-gl-gstglf.patch \
file://CVE-2021-3497.patch \
file://CVE-2021-3498.patch \
+ file://CVE-2022-1920.patch \
+ file://CVE-2022-1921.patch \
+ file://CVE-2022-1922-1923-1924-1925.patch \
+ file://CVE-2022-2122.patch \
"
SRC_URI[md5sum] = "c79b6c2f8eaadb2bb66615b694db399e"
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer1.0_1.16.3.bb b/meta/recipes-multimedia/gstreamer/gstreamer1.0_1.16.3.bb
index 236d6034d6..14793b7fdf 100644
--- a/meta/recipes-multimedia/gstreamer/gstreamer1.0_1.16.3.bb
+++ b/meta/recipes-multimedia/gstreamer/gstreamer1.0_1.16.3.bb
@@ -41,7 +41,7 @@ PACKAGECONFIG[unwind] = "-Dlibunwind=enabled,-Dlibunwind=disabled,libunwind"
PACKAGECONFIG[dw] = "-Dlibdw=enabled,-Dlibdw=disabled,elfutils"
PACKAGECONFIG[bash-completion] = "-Dbash-completion=enabled,-Dbash-completion=disabled,bash-completion"
PACKAGECONFIG[tools] = "-Dtools=enabled,-Dtools=disabled"
-PACKAGECONFIG[setcap] = ",,libcap libcap-native"
+PACKAGECONFIG[setcap] = "-Dptp-helper-permissions=capabilities,,libcap libcap-native"
# TODO: put this in a gettext.bbclass patch
def gettext_oemeson(d):
@@ -83,5 +83,12 @@ CVE_CHECK_WHITELIST += "CVE-2021-3522"
# so we need to ignore the false hits
CVE_CHECK_WHITELIST += "CVE-2021-3497"
CVE_CHECK_WHITELIST += "CVE-2021-3498"
+CVE_CHECK_WHITELIST += "CVE-2022-1920"
+CVE_CHECK_WHITELIST += "CVE-2022-1921"
+CVE_CHECK_WHITELIST += "CVE-2022-1922"
+CVE_CHECK_WHITELIST += "CVE-2022-1923"
+CVE_CHECK_WHITELIST += "CVE-2022-1924"
+CVE_CHECK_WHITELIST += "CVE-2022-1925"
+CVE_CHECK_WHITELIST += "CVE-2022-2122"
require gstreamer1.0-ptest.inc
diff --git a/meta/recipes-multimedia/libpng/files/run-ptest b/meta/recipes-multimedia/libpng/files/run-ptest
new file mode 100644
index 0000000000..9ab5d0c1f4
--- /dev/null
+++ b/meta/recipes-multimedia/libpng/files/run-ptest
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+set -eux
+
+./pngfix pngtest.png &> log.txt 2>&1
+
+if grep -i "OK" log.txt 2>&1 ; then
+ echo "PASS: pngfix passed"
+else
+ echo "FAIL: pngfix failed"
+fi
+rm -f log.txt
+
+./pngtest pngtest.png &> log.txt 2>&1
+
+if grep -i "PASS" log.txt 2>&1 ; then
+ echo "PASS: pngtest passed"
+else
+ echo "FAIL: pngtest failed"
+fi
+rm -f log.txt
+
+for i in pngstest timepng; do
+ if "./${i}" pngtest.png 2>&1; then
+ echo "PASS: $i"
+ else
+ echo "FAIL: $i"
+ fi
+done
diff --git a/meta/recipes-multimedia/libpng/libpng_1.6.37.bb b/meta/recipes-multimedia/libpng/libpng_1.6.37.bb
index 3c46fa3302..9387fc8e2e 100644
--- a/meta/recipes-multimedia/libpng/libpng_1.6.37.bb
+++ b/meta/recipes-multimedia/libpng/libpng_1.6.37.bb
@@ -10,7 +10,10 @@ DEPENDS = "zlib"
LIBV = "16"
-SRC_URI = "${SOURCEFORGE_MIRROR}/${BPN}/${BPN}${LIBV}/${BP}.tar.xz"
+SRC_URI = "\
+ ${SOURCEFORGE_MIRROR}/${BPN}/${BPN}${LIBV}/${BP}.tar.xz \
+ file://run-ptest \
+ "
SRC_URI[md5sum] = "015e8e15db1eecde5f2eb9eb5b6e59e9"
SRC_URI[sha256sum] = "505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca"
@@ -20,7 +23,7 @@ UPSTREAM_CHECK_URI = "http://libpng.org/pub/png/libpng.html"
BINCONFIG = "${bindir}/libpng-config ${bindir}/libpng16-config"
-inherit autotools binconfig-disabled pkgconfig
+inherit autotools binconfig-disabled pkgconfig ptest
# Work around missing symbols
EXTRA_OECONF_append_class-target = " ${@bb.utils.contains("TUNE_FEATURES", "neon", "--enable-arm-neon=on", "--enable-arm-neon=off" ,d)}"
@@ -33,3 +36,11 @@ BBCLASSEXTEND = "native nativesdk"
# CVE-2019-17371 is actually a memory leak in gif2png 2.x
CVE_CHECK_WHITELIST += "CVE-2019-17371"
+
+do_install_ptest() {
+ install -m644 "${S}/pngtest.png" "${D}${PTEST_PATH}"
+ install -m755 "${B}/.libs/pngfix" "${D}${PTEST_PATH}"
+ install -m755 "${B}/.libs/pngtest" "${D}${PTEST_PATH}"
+ install -m755 "${B}/.libs/pngstest" "${D}${PTEST_PATH}"
+ install -m755 "${B}/.libs/timepng" "${D}${PTEST_PATH}"
+}
diff --git a/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2021-4156.patch b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2021-4156.patch
new file mode 100644
index 0000000000..f7ae82588f
--- /dev/null
+++ b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2021-4156.patch
@@ -0,0 +1,30 @@
+From ced91d7b971be6173b604154c39279ce90ad87cc Mon Sep 17 00:00:00 2001
+From: yuan <ssspeed00@gmail.com>
+Date: Tue, 20 Apr 2021 16:16:32 +0800
+Subject: [PATCH] flac: Fix improper buffer reusing (#732)
+
+Upstream-Status: Backport [https://github.com/libsndfile/libsndfile/commit/ced91d7b971be6173b604154c39279ce90ad87cc]
+CVE: CVE-2021-4156
+Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
+---
+ src/flac.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/flac.c b/src/flac.c
+index 0be82ac..4fa5cfa 100644
+--- a/src/flac.c
++++ b/src/flac.c
+@@ -952,7 +952,11 @@ flac_read_loop (SF_PRIVATE *psf, unsigned len)
+ /* Decode some more. */
+ while (pflac->pos < pflac->len)
+ { if (FLAC__stream_decoder_process_single (pflac->fsd) == 0)
++ { psf_log_printf (psf, "FLAC__stream_decoder_process_single returned false\n") ;
++ /* Current frame is busted, so NULL the pointer. */
++ pflac->frame = NULL ;
+ break ;
++ } ;
+ state = FLAC__stream_decoder_get_state (pflac->fsd) ;
+ if (state >= FLAC__STREAM_DECODER_END_OF_STREAM)
+ { psf_log_printf (psf, "FLAC__stream_decoder_get_state returned %s\n", FLAC__StreamDecoderStateString [state]) ;
+--
+2.40.1
diff --git a/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2022-33065.patch b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2022-33065.patch
new file mode 100644
index 0000000000..e22b4e9389
--- /dev/null
+++ b/meta/recipes-multimedia/libsndfile/libsndfile1/CVE-2022-33065.patch
@@ -0,0 +1,46 @@
+From 0754562e13d2e63a248a1c82f90b30bc0ffe307c Mon Sep 17 00:00:00 2001
+From: Alex Stewart <alex.stewart@ni.com>
+Date: Tue, 10 Oct 2023 16:10:34 -0400
+Subject: [PATCH] mat4/mat5: fix int overflow in dataend calculation
+
+The clang sanitizer warns of a possible signed integer overflow when
+calculating the `dataend` value in `mat4_read_header()`.
+
+```
+src/mat4.c:323:41: runtime error: signed integer overflow: 205 * -100663296 cannot be represented in type 'int'
+SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/mat4.c:323:41 in
+src/mat4.c:323:48: runtime error: signed integer overflow: 838860800 * 4 cannot be represented in type 'int'
+SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/mat4.c:323:48 in
+```
+
+Cast the offending `rows` and `cols` ints to `sf_count_t` (the type of
+`dataend` before performing the calculation, to avoid the issue.
+
+CVE: CVE-2022-33065
+Fixes: https://github.com/libsndfile/libsndfile/issues/789
+Fixes: https://github.com/libsndfile/libsndfile/issues/833
+
+Signed-off-by: Alex Stewart <alex.stewart@ni.com>
+
+Upstream-Status: Backport [https://github.com/libsndfile/libsndfile/commit/0754562e13d2e63a248a1c82f90b30bc0ffe307c]
+CVE: CVE-2022-33065
+Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
+---
+ src/mat4.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/mat4.c b/src/mat4.c
+index 3c73680..e2f98b7 100644
+--- a/src/mat4.c
++++ b/src/mat4.c
+@@ -320,7 +320,7 @@ mat4_read_header (SF_PRIVATE *psf)
+ psf->filelength - psf->dataoffset, psf->sf.channels * psf->sf.frames * psf->bytewidth) ;
+ }
+ else if ((psf->filelength - psf->dataoffset) > psf->sf.channels * psf->sf.frames * psf->bytewidth)
+- psf->dataend = psf->dataoffset + rows * cols * psf->bytewidth ;
++ psf->dataend = psf->dataoffset + (sf_count_t) rows * (sf_count_t) cols * psf->bytewidth ;
+
+ psf->datalength = psf->filelength - psf->dataoffset - psf->dataend ;
+
+--
+2.40.1
diff --git a/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.28.bb b/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.28.bb
index 2525af8fe0..fb7d94ab75 100644
--- a/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.28.bb
+++ b/meta/recipes-multimedia/libsndfile/libsndfile1_1.0.28.bb
@@ -22,7 +22,9 @@ SRC_URI = "http://www.mega-nerd.com/libsndfile/files/libsndfile-${PV}.tar.gz \
file://CVE-2019-3832.patch \
file://CVE-2021-3246_1.patch \
file://CVE-2021-3246_2.patch \
- "
+ file://CVE-2022-33065.patch \
+ file://CVE-2021-4156.patch \
+ "
SRC_URI[md5sum] = "646b5f98ce89ac60cdb060fcd398247c"
SRC_URI[sha256sum] = "1ff33929f042fa333aed1e8923aa628c3ee9e1eb85512686c55092d1e5a9dfa9"
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-2867-CVE-2022-2868-CVE-2022-2869.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-2867-CVE-2022-2868-CVE-2022-2869.patch
new file mode 100644
index 0000000000..131ff94119
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-2867-CVE-2022-2868-CVE-2022-2869.patch
@@ -0,0 +1,159 @@
+From 07d79fcac2ead271b60e32aeb80f7b4f3be9ac8c Mon Sep 17 00:00:00 2001
+From: Su Laus <sulau@freenet.de>
+Date: Wed, 9 Feb 2022 21:31:29 +0000
+Subject: [PATCH] tiffcrop.c: Fix issue #352 heap-buffer-overflow by correcting
+ uint32_t underflow.
+
+CVE: CVE-2022-2867 CVE-2022-2868 CVE-2022-2869
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/07d79fcac2ead271b60e32aeb80f7b4f3be9ac8c]
+Signed-off-by: Virendra Thakur <virendrak@kpit.com>
+---
+Index: tiff-4.1.0/tools/tiffcrop.c
+===================================================================
+--- tiff-4.1.0.orig/tools/tiffcrop.c
++++ tiff-4.1.0/tools/tiffcrop.c
+@@ -5153,29 +5153,45 @@ computeInputPixelOffsets(struct crop_mas
+ y1 = _TIFFClampDoubleToUInt32(crop->corners[i].Y1);
+ y2 = _TIFFClampDoubleToUInt32(crop->corners[i].Y2);
+ }
+- if (x1 < 1)
+- crop->regionlist[i].x1 = 0;
+- else
+- crop->regionlist[i].x1 = (uint32) (x1 - 1);
++ /* a) Region needs to be within image sizes 0.. width-1; 0..length-1
++ * b) Corners are expected to be submitted as top-left to bottom-right.
++ * Therefore, check that and reorder input.
++ * (be aware x,y are already casted to (uint32_t) and avoid (0 - 1) )
++ */
++ uint32_t aux;
++ if (x1 > x2) {
++ aux = x1;
++ x1 = x2;
++ x2 = aux;
++ }
++ if (y1 > y2) {
++ aux = y1;
++ y1 = y2;
++ y2 = aux;
++ }
++ if (x1 > image->width - 1)
++ crop->regionlist[i].x1 = image->width - 1;
++ else if (x1 > 0)
++ crop->regionlist[i].x1 = (uint32_t)(x1 - 1);
+
+ if (x2 > image->width - 1)
+ crop->regionlist[i].x2 = image->width - 1;
+- else
+- crop->regionlist[i].x2 = (uint32) (x2 - 1);
+- zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
+-
+- if (y1 < 1)
+- crop->regionlist[i].y1 = 0;
+- else
+- crop->regionlist[i].y1 = (uint32) (y1 - 1);
++ else if (x2 > 0)
++ crop->regionlist[i].x2 = (uint32_t)(x2 - 1);
++
++ zwidth = crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
++
++ if (y1 > image->length - 1)
++ crop->regionlist[i].y1 = image->length - 1;
++ else if (y1 > 0)
++ crop->regionlist[i].y1 = (uint32_t)(y1 - 1);
+
+ if (y2 > image->length - 1)
+ crop->regionlist[i].y2 = image->length - 1;
+- else
+- crop->regionlist[i].y2 = (uint32) (y2 - 1);
+-
+- zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
++ else if (y2 > 0)
++ crop->regionlist[i].y2 = (uint32_t)(y2 - 1);
+
++ zlength = crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
+ if (zwidth > max_width)
+ max_width = zwidth;
+ if (zlength > max_length)
+@@ -5205,7 +5221,7 @@ computeInputPixelOffsets(struct crop_mas
+ }
+ }
+ return (0);
+- }
++ } /* crop_mode == CROP_REGIONS */
+
+ /* Convert crop margins into offsets into image
+ * Margins are expressed as pixel rows and columns, not bytes
+@@ -5241,7 +5257,7 @@ computeInputPixelOffsets(struct crop_mas
+ bmargin = (uint32) 0;
+ return (-1);
+ }
+- }
++ } /* crop_mode == CROP_MARGINS */
+ else
+ { /* no margins requested */
+ tmargin = (uint32) 0;
+@@ -5332,24 +5348,23 @@ computeInputPixelOffsets(struct crop_mas
+ off->endx = endx;
+ off->endy = endy;
+
+- crop_width = endx - startx + 1;
+- crop_length = endy - starty + 1;
+-
+- if (crop_width <= 0)
++ if (endx + 1 <= startx)
+ {
+ TIFFError("computeInputPixelOffsets",
+ "Invalid left/right margins and /or image crop width requested");
+ return (-1);
+ }
++ crop_width = endx - startx + 1;
+ if (crop_width > image->width)
+ crop_width = image->width;
+
+- if (crop_length <= 0)
++ if (endy + 1 <= starty)
+ {
+ TIFFError("computeInputPixelOffsets",
+ "Invalid top/bottom margins and /or image crop length requested");
+ return (-1);
+ }
++ crop_length = endy - starty + 1;
+ if (crop_length > image->length)
+ crop_length = image->length;
+
+@@ -5449,10 +5464,17 @@ getCropOffsets(struct image_data *image,
+ else
+ crop->selections = crop->zones;
+
+- for (i = 0; i < crop->zones; i++)
++ /* Initialize regions iterator i */
++ i = 0;
++ for (int j = 0; j < crop->zones; j++)
+ {
+- seg = crop->zonelist[i].position;
+- total = crop->zonelist[i].total;
++ seg = crop->zonelist[j].position;
++ total = crop->zonelist[j].total;
++
++ /* check for not allowed zone cases like 0:0; 4:3; etc. and skip that input */
++ if (seg == 0 || total == 0 || seg > total) {
++ continue;
++ }
+
+ switch (crop->edge_ref)
+ {
+@@ -5581,8 +5603,11 @@ getCropOffsets(struct image_data *image,
+ i + 1, (uint32)zwidth, (uint32)zlength,
+ crop->regionlist[i].x1, crop->regionlist[i].x2,
+ crop->regionlist[i].y1, crop->regionlist[i].y2);
++ /* increment regions iterator */
++ i++;
+ }
+-
++ /* set number of generated regions out of given zones */
++ crop->selections = i;
+ return (0);
+ } /* end getCropOffsets */
+
+--
+GitLab
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-34526.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-34526.patch
new file mode 100644
index 0000000000..cf440ce55f
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-34526.patch
@@ -0,0 +1,29 @@
+From 06386cc9dff5dc162006abe11fd4d1a6fad616cc Mon Sep 17 00:00:00 2001
+From: Hitendra Prajapati <hprajapati@mvista.com>
+Date: Thu, 18 Aug 2022 09:40:50 +0530
+Subject: [PATCH] CVE-2022-34526
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/275735d0354e39c0ac1dc3c0db2120d6f31d1990]
+CVE: CVE-2022-34526
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ libtiff/tif_dirinfo.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
+index 52d53d4..4a1ca00 100644
+--- a/libtiff/tif_dirinfo.c
++++ b/libtiff/tif_dirinfo.c
+@@ -983,6 +983,9 @@ _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag)
+ default:
+ return 1;
+ }
++ if( !TIFFIsCODECConfigured(tif->tif_dir.td_compression) ) {
++ return 0;
++ }
+ /* Check if codec specific tags are allowed for the current
+ * compression scheme (codec) */
+ switch (tif->tif_dir.td_compression) {
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-3570_3598.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-3570_3598.patch
new file mode 100644
index 0000000000..760e20dd2b
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-3570_3598.patch
@@ -0,0 +1,659 @@
+From 226e336cdceec933da2e9f72b6578c7a1bea450b Mon Sep 17 00:00:00 2001
+From: Su Laus <sulau@freenet.de>
+Date: Thu, 13 Oct 2022 14:33:27 +0000
+Subject: [PATCH] tiffcrop subroutines require a larger buffer (fixes #271,
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz ]
+CVE: CVE-2022-3570 CVE-2022-3598
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/cfbb883bf6ea7bedcb04177cc4e52d304522fdff
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/24d3b2425af24432e0e4e2fd58b33f3b04c4bfa4
+Reviewed-by: Sylvain Beucler <beuc@debian.org>
+Last-Update: 2023-01-17
+
+ #381, #386, #388, #389, #435)
+
+---
+ tools/tiffcrop.c | 209 ++++++++++++++++++++++++++---------------------
+ 1 file changed, 117 insertions(+), 92 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index c7877aa..c923920 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -126,6 +126,7 @@ static char tiffcrop_rev_date[] = "03-03-2010";
+
+ #ifdef HAVE_STDINT_H
+ # include <stdint.h>
++# include <inttypes.h>
+ #endif
+
+ #ifndef HAVE_GETOPT
+@@ -212,6 +213,10 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
+
+ #define TIFF_DIR_MAX 65534
+
++/* Some conversion subroutines require image buffers, which are at least 3 bytes
++ * larger than the necessary size for the image itself. */
++#define NUM_BUFF_OVERSIZE_BYTES 3
++
+ /* Offsets into buffer for margins and fixed width and length segments */
+ struct offset {
+ uint32 tmargin;
+@@ -233,7 +238,7 @@ struct offset {
+ */
+
+ struct buffinfo {
+- uint32 size; /* size of this buffer */
++ size_t size; /* size of this buffer */
+ unsigned char *buffer; /* address of the allocated buffer */
+ };
+
+@@ -771,8 +776,8 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8* buf,
+ uint32 dst_rowsize, shift_width;
+ uint32 bytes_per_sample, bytes_per_pixel;
+ uint32 trailing_bits, prev_trailing_bits;
+- uint32 tile_rowsize = TIFFTileRowSize(in);
+- uint32 src_offset, dst_offset;
++ tmsize_t tile_rowsize = TIFFTileRowSize(in);
++ tmsize_t src_offset, dst_offset;
+ uint32 row_offset, col_offset;
+ uint8 *bufp = (uint8*) buf;
+ unsigned char *src = NULL;
+@@ -822,7 +827,7 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8* buf,
+ TIFFError("readContigTilesIntoBuffer", "Integer overflow when calculating buffer size.");
+ exit(-1);
+ }
+- tilebuf = _TIFFmalloc(tile_buffsize + 3);
++ tilebuf = _TIFFmalloc(tile_buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (tilebuf == 0)
+ return 0;
+ tilebuf[tile_buffsize] = 0;
+@@ -986,7 +991,7 @@ static int readSeparateTilesIntoBuffer (TIFF* in, uint8 *obuf,
+ for (sample = 0; (sample < spp) && (sample < MAX_SAMPLES); sample++)
+ {
+ srcbuffs[sample] = NULL;
+- tbuff = (unsigned char *)_TIFFmalloc(tilesize + 8);
++ tbuff = (unsigned char *)_TIFFmalloc(tilesize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!tbuff)
+ {
+ TIFFError ("readSeparateTilesIntoBuffer",
+@@ -1181,7 +1186,8 @@ writeBufferToSeparateStrips (TIFF* out, uint8* buf,
+ }
+ rowstripsize = rowsperstrip * bytes_per_sample * (width + 1);
+
+- obuf = _TIFFmalloc (rowstripsize);
++ /* Add 3 padding bytes for extractContigSamples32bits */
++ obuf = _TIFFmalloc (rowstripsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (obuf == NULL)
+ return 1;
+
+@@ -1194,7 +1200,7 @@ writeBufferToSeparateStrips (TIFF* out, uint8* buf,
+ stripsize = TIFFVStripSize(out, nrows);
+ src = buf + (row * rowsize);
+ total_bytes += stripsize;
+- memset (obuf, '\0', rowstripsize);
++ memset (obuf, '\0',rowstripsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (extractContigSamplesToBuffer(obuf, src, nrows, width, s, spp, bps, dump))
+ {
+ _TIFFfree(obuf);
+@@ -1202,10 +1208,15 @@ writeBufferToSeparateStrips (TIFF* out, uint8* buf,
+ }
+ if ((dump->outfile != NULL) && (dump->level == 1))
+ {
+- dump_info(dump->outfile, dump->format,"",
++ if ((uint64_t)scanlinesize > 0x0ffffffffULL) {
++ dump_info(dump->infile, dump->format, "loadImage",
++ "Attention: scanlinesize %"PRIu64" is larger than UINT32_MAX.\nFollowing dump might be wrong.",
++ (uint64_t)scanlinesize);
++ }
++ dump_info(dump->outfile, dump->format,"",
+ "Sample %2d, Strip: %2d, bytes: %4d, Row %4d, bytes: %4d, Input offset: %6d",
+- s + 1, strip + 1, stripsize, row + 1, scanlinesize, src - buf);
+- dump_buffer(dump->outfile, dump->format, nrows, scanlinesize, row, obuf);
++ s + 1, strip + 1, stripsize, row + 1, (uint32)scanlinesize, src - buf);
++ dump_buffer(dump->outfile, dump->format, nrows, (uint32)scanlinesize, row, obuf);
+ }
+
+ if (TIFFWriteEncodedStrip(out, strip++, obuf, stripsize) < 0)
+@@ -1232,7 +1243,7 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
+ uint32 tl, tw;
+ uint32 row, col, nrow, ncol;
+ uint32 src_rowsize, col_offset;
+- uint32 tile_rowsize = TIFFTileRowSize(out);
++ tmsize_t tile_rowsize = TIFFTileRowSize(out);
+ uint8* bufp = (uint8*) buf;
+ tsize_t tile_buffsize = 0;
+ tsize_t tilesize = TIFFTileSize(out);
+@@ -1275,9 +1286,11 @@ static int writeBufferToContigTiles (TIFF* out, uint8* buf, uint32 imagelength,
+ }
+ src_rowsize = ((imagewidth * spp * bps) + 7U) / 8;
+
+- tilebuf = _TIFFmalloc(tile_buffsize);
++ /* Add 3 padding bytes for extractContigSamples32bits */
++ tilebuf = _TIFFmalloc(tile_buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (tilebuf == 0)
+ return 1;
++ memset(tilebuf, 0, tile_buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ for (row = 0; row < imagelength; row += tl)
+ {
+ nrow = (row + tl > imagelength) ? imagelength - row : tl;
+@@ -1323,7 +1336,8 @@ static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength
+ uint32 imagewidth, tsample_t spp,
+ struct dump_opts * dump)
+ {
+- tdata_t obuf = _TIFFmalloc(TIFFTileSize(out));
++ /* Add 3 padding bytes for extractContigSamples32bits */
++ tdata_t obuf = _TIFFmalloc(TIFFTileSize(out) + NUM_BUFF_OVERSIZE_BYTES);
+ uint32 tl, tw;
+ uint32 row, col, nrow, ncol;
+ uint32 src_rowsize, col_offset;
+@@ -1333,6 +1347,7 @@ static int writeBufferToSeparateTiles (TIFF* out, uint8* buf, uint32 imagelength
+
+ if (obuf == NULL)
+ return 1;
++ memset(obuf, 0, TIFFTileSize(out) + NUM_BUFF_OVERSIZE_BYTES);
+
+ TIFFGetField(out, TIFFTAG_TILELENGTH, &tl);
+ TIFFGetField(out, TIFFTAG_TILEWIDTH, &tw);
+@@ -1754,14 +1769,14 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32
+
+ *opt_offset = '\0';
+ /* convert option to lowercase */
+- end = strlen (opt_ptr);
++ end = (unsigned int)strlen (opt_ptr);
+ for (i = 0; i < end; i++)
+ *(opt_ptr + i) = tolower((int) *(opt_ptr + i));
+ /* Look for dump format specification */
+ if (strncmp(opt_ptr, "for", 3) == 0)
+ {
+ /* convert value to lowercase */
+- end = strlen (opt_offset + 1);
++ end = (unsigned int)strlen (opt_offset + 1);
+ for (i = 1; i <= end; i++)
+ *(opt_offset + i) = tolower((int) *(opt_offset + i));
+ /* check dump format value */
+@@ -2213,6 +2228,8 @@ main(int argc, char* argv[])
+ size_t length;
+ char temp_filename[PATH_MAX + 16]; /* Extra space keeps the compiler from complaining */
+
++ assert(NUM_BUFF_OVERSIZE_BYTES >= 3);
++
+ little_endian = *((unsigned char *)&little_endian) & '1';
+
+ initImageData(&image);
+@@ -3114,13 +3131,13 @@ extractContigSamples32bits (uint8 *in, uint8 *out, uint32 cols,
+ /* If we have a full buffer's worth, write it out */
+ if (ready_bits >= 32)
+ {
+- bytebuff1 = (buff2 >> 56);
++ bytebuff1 = (uint8)(buff2 >> 56);
+ *dst++ = bytebuff1;
+- bytebuff2 = (buff2 >> 48);
++ bytebuff2 = (uint8)(buff2 >> 48);
+ *dst++ = bytebuff2;
+- bytebuff3 = (buff2 >> 40);
++ bytebuff3 = (uint8)(buff2 >> 40);
+ *dst++ = bytebuff3;
+- bytebuff4 = (buff2 >> 32);
++ bytebuff4 = (uint8)(buff2 >> 32);
+ *dst++ = bytebuff4;
+ ready_bits -= 32;
+
+@@ -3495,13 +3512,13 @@ extractContigSamplesShifted32bits (uint8 *in, uint8 *out, uint32 cols,
+ }
+ else /* If we have a full buffer's worth, write it out */
+ {
+- bytebuff1 = (buff2 >> 56);
++ bytebuff1 = (uint8)(buff2 >> 56);
+ *dst++ = bytebuff1;
+- bytebuff2 = (buff2 >> 48);
++ bytebuff2 = (uint8)(buff2 >> 48);
+ *dst++ = bytebuff2;
+- bytebuff3 = (buff2 >> 40);
++ bytebuff3 = (uint8)(buff2 >> 40);
+ *dst++ = bytebuff3;
+- bytebuff4 = (buff2 >> 32);
++ bytebuff4 = (uint8)(buff2 >> 32);
+ *dst++ = bytebuff4;
+ ready_bits -= 32;
+
+@@ -3678,10 +3695,10 @@ extractContigSamplesToTileBuffer(uint8 *out, uint8 *in, uint32 rows, uint32 cols
+ static int readContigStripsIntoBuffer (TIFF* in, uint8* buf)
+ {
+ uint8* bufp = buf;
+- int32 bytes_read = 0;
++ tmsize_t bytes_read = 0;
+ uint32 strip, nstrips = TIFFNumberOfStrips(in);
+- uint32 stripsize = TIFFStripSize(in);
+- uint32 rows = 0;
++ tmsize_t stripsize = TIFFStripSize(in);
++ tmsize_t rows = 0;
+ uint32 rps = TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &rps);
+ tsize_t scanline_size = TIFFScanlineSize(in);
+
+@@ -3694,13 +3711,12 @@ static int readContigStripsIntoBuffer (TIFF* in, uint8* buf)
+ bytes_read = TIFFReadEncodedStrip (in, strip, bufp, -1);
+ rows = bytes_read / scanline_size;
+ if ((strip < (nstrips - 1)) && (bytes_read != (int32)stripsize))
+- TIFFError("", "Strip %d: read %lu bytes, strip size %lu",
+- (int)strip + 1, (unsigned long) bytes_read,
+- (unsigned long)stripsize);
++ TIFFError("", "Strip %"PRIu32": read %"PRId64" bytes, strip size %"PRIu64,
++ strip + 1, bytes_read, stripsize);
+
+ if (bytes_read < 0 && !ignore) {
+- TIFFError("", "Error reading strip %lu after %lu rows",
+- (unsigned long) strip, (unsigned long)rows);
++ TIFFError("", "Error reading strip %"PRIu32" after %"PRIu64" rows",
++ strip, rows);
+ return 0;
+ }
+ bufp += stripsize;
+@@ -4164,13 +4180,13 @@ combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
+ /* If we have a full buffer's worth, write it out */
+ if (ready_bits >= 32)
+ {
+- bytebuff1 = (buff2 >> 56);
++ bytebuff1 = (uint8)(buff2 >> 56);
+ *dst++ = bytebuff1;
+- bytebuff2 = (buff2 >> 48);
++ bytebuff2 = (uint8)(buff2 >> 48);
+ *dst++ = bytebuff2;
+- bytebuff3 = (buff2 >> 40);
++ bytebuff3 = (uint8)(buff2 >> 40);
+ *dst++ = bytebuff3;
+- bytebuff4 = (buff2 >> 32);
++ bytebuff4 = (uint8)(buff2 >> 32);
+ *dst++ = bytebuff4;
+ ready_bits -= 32;
+
+@@ -4213,10 +4229,10 @@ combineSeparateSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
+ "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
+ row + 1, col + 1, src_byte, src_bit, dst - out);
+
+- dump_long (dumpfile, format, "Match bits ", matchbits);
++ dump_wide (dumpfile, format, "Match bits ", matchbits);
+ dump_data (dumpfile, format, "Src bits ", src, 4);
+- dump_long (dumpfile, format, "Buff1 bits ", buff1);
+- dump_long (dumpfile, format, "Buff2 bits ", buff2);
++ dump_wide (dumpfile, format, "Buff1 bits ", buff1);
++ dump_wide (dumpfile, format, "Buff2 bits ", buff2);
+ dump_byte (dumpfile, format, "Write bits1", bytebuff1);
+ dump_byte (dumpfile, format, "Write bits2", bytebuff2);
+ dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
+@@ -4689,13 +4705,13 @@ combineSeparateTileSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
+ /* If we have a full buffer's worth, write it out */
+ if (ready_bits >= 32)
+ {
+- bytebuff1 = (buff2 >> 56);
++ bytebuff1 = (uint8)(buff2 >> 56);
+ *dst++ = bytebuff1;
+- bytebuff2 = (buff2 >> 48);
++ bytebuff2 = (uint8)(buff2 >> 48);
+ *dst++ = bytebuff2;
+- bytebuff3 = (buff2 >> 40);
++ bytebuff3 = (uint8)(buff2 >> 40);
+ *dst++ = bytebuff3;
+- bytebuff4 = (buff2 >> 32);
++ bytebuff4 = (uint8)(buff2 >> 32);
+ *dst++ = bytebuff4;
+ ready_bits -= 32;
+
+@@ -4738,10 +4754,10 @@ combineSeparateTileSamples32bits (uint8 *in[], uint8 *out, uint32 cols,
+ "Row %3d, Col %3d, Src byte offset %3d bit offset %2d Dst offset %3d",
+ row + 1, col + 1, src_byte, src_bit, dst - out);
+
+- dump_long (dumpfile, format, "Match bits ", matchbits);
++ dump_wide (dumpfile, format, "Match bits ", matchbits);
+ dump_data (dumpfile, format, "Src bits ", src, 4);
+- dump_long (dumpfile, format, "Buff1 bits ", buff1);
+- dump_long (dumpfile, format, "Buff2 bits ", buff2);
++ dump_wide (dumpfile, format, "Buff1 bits ", buff1);
++ dump_wide (dumpfile, format, "Buff2 bits ", buff2);
+ dump_byte (dumpfile, format, "Write bits1", bytebuff1);
+ dump_byte (dumpfile, format, "Write bits2", bytebuff2);
+ dump_info (dumpfile, format, "", "Ready bits: %2d", ready_bits);
+@@ -4764,7 +4780,7 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length,
+ {
+ int i, bytes_per_sample, bytes_per_pixel, shift_width, result = 1;
+ uint32 j;
+- int32 bytes_read = 0;
++ tmsize_t bytes_read = 0;
+ uint16 bps = 0, planar;
+ uint32 nstrips;
+ uint32 strips_per_sample;
+@@ -4830,7 +4846,7 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length,
+ for (s = 0; (s < spp) && (s < MAX_SAMPLES); s++)
+ {
+ srcbuffs[s] = NULL;
+- buff = _TIFFmalloc(stripsize + 3);
++ buff = _TIFFmalloc(stripsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!buff)
+ {
+ TIFFError ("readSeparateStripsIntoBuffer",
+@@ -4853,7 +4869,7 @@ static int readSeparateStripsIntoBuffer (TIFF *in, uint8 *obuf, uint32 length,
+ buff = srcbuffs[s];
+ strip = (s * strips_per_sample) + j;
+ bytes_read = TIFFReadEncodedStrip (in, strip, buff, stripsize);
+- rows_this_strip = bytes_read / src_rowsize;
++ rows_this_strip = (uint32)(bytes_read / src_rowsize);
+ if (bytes_read < 0 && !ignore)
+ {
+ TIFFError(TIFFFileName(in),
+@@ -5860,13 +5876,14 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
+ uint16 input_compression = 0, input_photometric = 0;
+ uint16 subsampling_horiz, subsampling_vert;
+ uint32 width = 0, length = 0;
+- uint32 stsize = 0, tlsize = 0, buffsize = 0, scanlinesize = 0;
++ tmsize_t stsize = 0, tlsize = 0, buffsize = 0;
++ tmsize_t scanlinesize = 0;
+ uint32 tw = 0, tl = 0; /* Tile width and length */
+- uint32 tile_rowsize = 0;
++ tmsize_t tile_rowsize = 0;
+ unsigned char *read_buff = NULL;
+ unsigned char *new_buff = NULL;
+ int readunit = 0;
+- static uint32 prev_readsize = 0;
++ static tmsize_t prev_readsize = 0;
+
+ TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
+ TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
+@@ -6168,7 +6185,7 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
+ TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
+ return (-1);
+ }
+- read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
++ read_buff = (unsigned char *)_TIFFmalloc(buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ else
+ {
+@@ -6179,11 +6196,11 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
+ TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
+ return (-1);
+ }
+- new_buff = _TIFFrealloc(read_buff, buffsize+3);
++ new_buff = _TIFFrealloc(read_buff, buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!new_buff)
+ {
+ free (read_buff);
+- read_buff = (unsigned char *)_TIFFmalloc(buffsize+3);
++ read_buff = (unsigned char *)_TIFFmalloc(buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ else
+ read_buff = new_buff;
+@@ -6256,8 +6273,13 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
+ dump_info (dump->infile, dump->format, "",
+ "Bits per sample %d, Samples per pixel %d", bps, spp);
+
++ if ((uint64_t)scanlinesize > 0x0ffffffffULL) {
++ dump_info(dump->infile, dump->format, "loadImage",
++ "Attention: scanlinesize %"PRIu64" is larger than UINT32_MAX.\nFollowing dump might be wrong.",
++ (uint64_t)scanlinesize);
++ }
+ for (i = 0; i < length; i++)
+- dump_buffer(dump->infile, dump->format, 1, scanlinesize,
++ dump_buffer(dump->infile, dump->format, 1, (uint32)scanlinesize,
+ i, read_buff + (i * scanlinesize));
+ }
+ return (0);
+@@ -7277,13 +7299,13 @@ writeSingleSection(TIFF *in, TIFF *out, struct image_data *image,
+ if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
+ TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
+ if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
+- int inknameslen = strlen(inknames) + 1;
++ int inknameslen = (int)strlen(inknames) + 1;
+ const char* cp = inknames;
+ while (ninks > 1) {
+ cp = strchr(cp, '\0');
+ if (cp) {
+ cp++;
+- inknameslen += (strlen(cp) + 1);
++ inknameslen += ((int)strlen(cp) + 1);
+ }
+ ninks--;
+ }
+@@ -7346,23 +7368,23 @@ createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
+
+ if (!sect_buff)
+ {
+- sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
++ sect_buff = (unsigned char *)_TIFFmalloc(sectsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!sect_buff)
+ {
+ TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
+ return (-1);
+ }
+- _TIFFmemset(sect_buff, 0, sectsize);
++ _TIFFmemset(sect_buff, 0, sectsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ else
+ {
+ if (prev_sectsize < sectsize)
+ {
+- new_buff = _TIFFrealloc(sect_buff, sectsize);
++ new_buff = _TIFFrealloc(sect_buff, sectsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!new_buff)
+ {
+ free (sect_buff);
+- sect_buff = (unsigned char *)_TIFFmalloc(sectsize);
++ sect_buff = (unsigned char *)_TIFFmalloc(sectsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ else
+ sect_buff = new_buff;
+@@ -7372,7 +7394,7 @@ createImageSection(uint32 sectsize, unsigned char **sect_buff_ptr)
+ TIFFError("createImageSection", "Unable to allocate/reallocate section buffer");
+ return (-1);
+ }
+- _TIFFmemset(sect_buff, 0, sectsize);
++ _TIFFmemset(sect_buff, 0, sectsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ }
+
+@@ -7403,17 +7425,17 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ cropsize = crop->bufftotal;
+ crop_buff = seg_buffs[0].buffer;
+ if (!crop_buff)
+- crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
++ crop_buff = (unsigned char *)_TIFFmalloc(cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ else
+ {
+ prev_cropsize = seg_buffs[0].size;
+ if (prev_cropsize < cropsize)
+ {
+- next_buff = _TIFFrealloc(crop_buff, cropsize);
++ next_buff = _TIFFrealloc(crop_buff, cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (! next_buff)
+ {
+ _TIFFfree (crop_buff);
+- crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
++ crop_buff = (unsigned char *)_TIFFmalloc(cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ else
+ crop_buff = next_buff;
+@@ -7426,7 +7448,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ return (-1);
+ }
+
+- _TIFFmemset(crop_buff, 0, cropsize);
++ _TIFFmemset(crop_buff, 0, cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ seg_buffs[0].buffer = crop_buff;
+ seg_buffs[0].size = cropsize;
+
+@@ -7505,17 +7527,17 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ cropsize = crop->bufftotal;
+ crop_buff = seg_buffs[i].buffer;
+ if (!crop_buff)
+- crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
++ crop_buff = (unsigned char *)_TIFFmalloc(cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ else
+ {
+ prev_cropsize = seg_buffs[0].size;
+ if (prev_cropsize < cropsize)
+ {
+- next_buff = _TIFFrealloc(crop_buff, cropsize);
++ next_buff = _TIFFrealloc(crop_buff, cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (! next_buff)
+ {
+ _TIFFfree (crop_buff);
+- crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
++ crop_buff = (unsigned char *)_TIFFmalloc(cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ else
+ crop_buff = next_buff;
+@@ -7528,7 +7550,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ return (-1);
+ }
+
+- _TIFFmemset(crop_buff, 0, cropsize);
++ _TIFFmemset(crop_buff, 0, cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ seg_buffs[i].buffer = crop_buff;
+ seg_buffs[i].size = cropsize;
+
+@@ -7641,24 +7663,24 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop,
+ crop_buff = *crop_buff_ptr;
+ if (!crop_buff)
+ {
+- crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
++ crop_buff = (unsigned char *)_TIFFmalloc(cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!crop_buff)
+ {
+ TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
+ return (-1);
+ }
+- _TIFFmemset(crop_buff, 0, cropsize);
++ _TIFFmemset(crop_buff, 0, cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ prev_cropsize = cropsize;
+ }
+ else
+ {
+ if (prev_cropsize < cropsize)
+ {
+- new_buff = _TIFFrealloc(crop_buff, cropsize);
++ new_buff = _TIFFrealloc(crop_buff, cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!new_buff)
+ {
+ free (crop_buff);
+- crop_buff = (unsigned char *)_TIFFmalloc(cropsize);
++ crop_buff = (unsigned char *)_TIFFmalloc(cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ else
+ crop_buff = new_buff;
+@@ -7667,7 +7689,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop,
+ TIFFError("createCroppedImage", "Unable to allocate/reallocate crop buffer");
+ return (-1);
+ }
+- _TIFFmemset(crop_buff, 0, cropsize);
++ _TIFFmemset(crop_buff, 0, cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ }
+ }
+
+@@ -7965,13 +7987,13 @@ writeCroppedImage(TIFF *in, TIFF *out, struct image_data *image,
+ if (TIFFGetField(in, TIFFTAG_NUMBEROFINKS, &ninks)) {
+ TIFFSetField(out, TIFFTAG_NUMBEROFINKS, ninks);
+ if (TIFFGetField(in, TIFFTAG_INKNAMES, &inknames)) {
+- int inknameslen = strlen(inknames) + 1;
++ int inknameslen = (int)strlen(inknames) + 1;
+ const char* cp = inknames;
+ while (ninks > 1) {
+ cp = strchr(cp, '\0');
+ if (cp) {
+ cp++;
+- inknameslen += (strlen(cp) + 1);
++ inknameslen += ((int)strlen(cp) + 1);
+ }
+ ninks--;
+ }
+@@ -8356,13 +8378,13 @@ rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
+ }
+ else /* If we have a full buffer's worth, write it out */
+ {
+- bytebuff1 = (buff2 >> 56);
++ bytebuff1 = (uint8)(buff2 >> 56);
+ *dst++ = bytebuff1;
+- bytebuff2 = (buff2 >> 48);
++ bytebuff2 = (uint8)(buff2 >> 48);
+ *dst++ = bytebuff2;
+- bytebuff3 = (buff2 >> 40);
++ bytebuff3 = (uint8)(buff2 >> 40);
+ *dst++ = bytebuff3;
+- bytebuff4 = (buff2 >> 32);
++ bytebuff4 = (uint8)(buff2 >> 32);
+ *dst++ = bytebuff4;
+ ready_bits -= 32;
+
+@@ -8431,12 +8453,13 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+ return (-1);
+ }
+
+- if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize)))
++ /* Add 3 padding bytes for extractContigSamplesShifted32bits */
++ if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize + NUM_BUFF_OVERSIZE_BYTES)))
+ {
+- TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize);
++ TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ return (-1);
+ }
+- _TIFFmemset(rbuff, '\0', buffsize);
++ _TIFFmemset(rbuff, '\0', buffsize + NUM_BUFF_OVERSIZE_BYTES);
+
+ ibuff = *ibuff_ptr;
+ switch (rotation)
+@@ -8964,13 +8987,13 @@ reverseSamples32bits (uint16 spp, uint16 bps, uint32 width,
+ }
+ else /* If we have a full buffer's worth, write it out */
+ {
+- bytebuff1 = (buff2 >> 56);
++ bytebuff1 = (uint8)(buff2 >> 56);
+ *dst++ = bytebuff1;
+- bytebuff2 = (buff2 >> 48);
++ bytebuff2 = (uint8)(buff2 >> 48);
+ *dst++ = bytebuff2;
+- bytebuff3 = (buff2 >> 40);
++ bytebuff3 = (uint8)(buff2 >> 40);
+ *dst++ = bytebuff3;
+- bytebuff4 = (buff2 >> 32);
++ bytebuff4 = (uint8)(buff2 >> 32);
+ *dst++ = bytebuff4;
+ ready_bits -= 32;
+
+@@ -9061,12 +9084,13 @@ mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length,
+ {
+ case MIRROR_BOTH:
+ case MIRROR_VERT:
+- line_buff = (unsigned char *)_TIFFmalloc(rowsize);
++ line_buff = (unsigned char *)_TIFFmalloc(rowsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (line_buff == NULL)
+ {
+- TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize);
++ TIFFError ("mirrorImage", "Unable to allocate mirror line buffer of %1u bytes", rowsize + NUM_BUFF_OVERSIZE_BYTES);
+ return (-1);
+ }
++ _TIFFmemset(line_buff, '\0', rowsize + NUM_BUFF_OVERSIZE_BYTES);
+
+ dst = ibuff + (rowsize * (length - 1));
+ for (row = 0; row < length / 2; row++)
+@@ -9098,11 +9122,12 @@ mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length,
+ }
+ else
+ { /* non 8 bit per sample data */
+- if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + 1)))
++ if (!(line_buff = (unsigned char *)_TIFFmalloc(rowsize + NUM_BUFF_OVERSIZE_BYTES)))
+ {
+ TIFFError("mirrorImage", "Unable to allocate mirror line buffer");
+ return (-1);
+ }
++ _TIFFmemset(line_buff, '\0', rowsize + NUM_BUFF_OVERSIZE_BYTES);
+ bytes_per_sample = (bps + 7) / 8;
+ bytes_per_pixel = ((bps * spp) + 7) / 8;
+ if (bytes_per_pixel < (bytes_per_sample + 1))
+@@ -9114,7 +9139,7 @@ mirrorImage(uint16 spp, uint16 bps, uint16 mirror, uint32 width, uint32 length,
+ {
+ row_offset = row * rowsize;
+ src = ibuff + row_offset;
+- _TIFFmemset (line_buff, '\0', rowsize);
++ _TIFFmemset (line_buff, '\0', rowsize + NUM_BUFF_OVERSIZE_BYTES);
+ switch (shift_width)
+ {
+ case 1: if (reverseSamples16bits(spp, bps, width, src, line_buff))
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-3597_3626_3627.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-3597_3626_3627.patch
new file mode 100644
index 0000000000..18a4b4e0ff
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-3597_3626_3627.patch
@@ -0,0 +1,123 @@
+From f7c06c395daf1b2c52ab431e00db2d9fc2ac993e Mon Sep 17 00:00:00 2001
+From: Su Laus <sulau@freenet.de>
+Date: Tue, 10 May 2022 20:03:17 +0000
+Subject: [PATCH] tiffcrop: Fix issue #330 and some more from 320 to 349
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz ]
+CVE: CVE-2022-3597 CVE-2022-3626 CVE-2022-3627
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/e319508023580e2f70e6e626f745b5b2a1707313
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/8fe3735942ea1d90d8cef843b55b3efe8ab6feaf
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/bad48e90b410df32172006c7876da449ba62cdba
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/236b7191f04c60d09ee836ae13b50f812c841047
+Reviewed-by: Sylvain Beucler <beuc@debian.org>
+Last-Update: 2023-01-17
+
+---
+ tools/tiffcrop.c | 50 ++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 42 insertions(+), 8 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index c923920..a0789a3 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -103,7 +103,12 @@
+ * selects which functions dump data, with higher numbers selecting
+ * lower level, scanline level routines. Debug reports a limited set
+ * of messages to monitor progess without enabling dump logs.
+- */
++ *
++ * Note 1: The (-X|-Y), -Z, -z and -S options are mutually exclusive.
++ * In no case should the options be applied to a given selection successively.
++ * Note 2: Any of the -X, -Y, -Z and -z options together with other PAGE_MODE_x options
++ * such as -H, -V, -P, -J or -K are not supported and may cause buffer overflows.
++ */
+
+ static char tiffcrop_version_id[] = "2.4.1";
+ static char tiffcrop_rev_date[] = "03-03-2010";
+@@ -176,12 +181,12 @@ extern int getopt(int argc, char * const argv[], const char *optstring);
+ #define ROTATECW_270 32
+ #define ROTATE_ANY (ROTATECW_90 | ROTATECW_180 | ROTATECW_270)
+
+-#define CROP_NONE 0
+-#define CROP_MARGINS 1
+-#define CROP_WIDTH 2
+-#define CROP_LENGTH 4
+-#define CROP_ZONES 8
+-#define CROP_REGIONS 16
++#define CROP_NONE 0 /* "-S" -> Page_MODE_ROWSCOLS and page->rows/->cols != 0 */
++#define CROP_MARGINS 1 /* "-m" */
++#define CROP_WIDTH 2 /* "-X" */
++#define CROP_LENGTH 4 /* "-Y" */
++#define CROP_ZONES 8 /* "-Z" */
++#define CROP_REGIONS 16 /* "-z" */
+ #define CROP_ROTATE 32
+ #define CROP_MIRROR 64
+ #define CROP_INVERT 128
+@@ -323,7 +328,7 @@ struct crop_mask {
+ #define PAGE_MODE_RESOLUTION 1
+ #define PAGE_MODE_PAPERSIZE 2
+ #define PAGE_MODE_MARGINS 4
+-#define PAGE_MODE_ROWSCOLS 8
++#define PAGE_MODE_ROWSCOLS 8 /* for -S option */
+
+ #define INVERT_DATA_ONLY 10
+ #define INVERT_DATA_AND_TAG 11
+@@ -754,6 +759,12 @@ static char* usage_info[] = {
+ " The four debug/dump options are independent, though it makes little sense to",
+ " specify a dump file without specifying a detail level.",
+ " ",
++"Note 1: The (-X|-Y), -Z, -z and -S options are mutually exclusive.",
++" In no case should the options be applied to a given selection successively.",
++" ",
++"Note 2: Any of the -X, -Y, -Z and -z options together with other PAGE_MODE_x options",
++" such as - H, -V, -P, -J or -K are not supported and may cause buffer overflows.",
++" ",
+ NULL
+ };
+
+@@ -2112,6 +2123,27 @@ void process_command_opts (int argc, char *argv[], char *mp, char *mode, uint32
+ /*NOTREACHED*/
+ }
+ }
++ /*-- Check for not allowed combinations (e.g. -X, -Y and -Z, -z and -S are mutually exclusive) --*/
++ char XY, Z, R, S;
++ XY = ((crop_data->crop_mode & CROP_WIDTH) || (crop_data->crop_mode & CROP_LENGTH)) ? 1 : 0;
++ Z = (crop_data->crop_mode & CROP_ZONES) ? 1 : 0;
++ R = (crop_data->crop_mode & CROP_REGIONS) ? 1 : 0;
++ S = (page->mode & PAGE_MODE_ROWSCOLS) ? 1 : 0;
++ if (XY + Z + R + S > 1) {
++ TIFFError("tiffcrop input error", "The crop options(-X|-Y), -Z, -z and -S are mutually exclusive.->exit");
++ exit(EXIT_FAILURE);
++ }
++
++ /* Check for not allowed combination:
++ * Any of the -X, -Y, -Z and -z options together with other PAGE_MODE_x options
++ * such as -H, -V, -P, -J or -K are not supported and may cause buffer overflows.
++. */
++ if ((XY + Z + R > 0) && page->mode != PAGE_MODE_NONE) {
++ TIFFError("tiffcrop input error",
++ "Any of the crop options -X, -Y, -Z and -z together with other PAGE_MODE_x options such as - H, -V, -P, -J or -K is not supported and may cause buffer overflows..->exit");
++ exit(EXIT_FAILURE);
++ }
++
+ } /* end process_command_opts */
+
+ /* Start a new output file if one has not been previously opened or
+@@ -2384,6 +2416,7 @@ main(int argc, char* argv[])
+ exit (-1);
+ }
+
++ /* Crop input image and copy zones and regions from input image into seg_buffs or crop_buff. */
+ if (crop.selections > 0)
+ {
+ if (processCropSelections(&image, &crop, &read_buff, seg_buffs))
+@@ -2400,6 +2433,7 @@ main(int argc, char* argv[])
+ exit (-1);
+ }
+ }
++ /* Format and write selected image parts to output file(s). */
+ if (page.mode == PAGE_MODE_NONE)
+ { /* Whole image or sections not based on output page size */
+ if (crop.selections > 0)
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch
new file mode 100644
index 0000000000..b3232d9002
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-3599.patch
@@ -0,0 +1,277 @@
+From 01bca7e6f608da7696949fca6acda78b9935ba19 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Tue, 30 Aug 2022 16:56:48 +0200
+Subject: [PATCH] Revised handling of TIFFTAG_INKNAMES and related
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz ]
+CVE: CVE-2022-3599 CVE-2022-4645 CVE-2023-30774
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/e813112545942107551433d61afd16ac094ff246
+Reviewed-by: Sylvain Beucler <beuc@debian.org>
+Last-Update: 2023-01-17
+
+ TIFFTAG_NUMBEROFINKS value
+
+In order to solve the buffer overflow issues related to TIFFTAG_INKNAMES and related TIFFTAG_NUMBEROFINKS value, a revised handling of those tags within LibTiff is proposed:
+
+Behaviour for writing:
+ `NumberOfInks` MUST fit to the number of inks in the `InkNames` string.
+ `NumberOfInks` is automatically set when `InkNames` is set.
+ If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued.
+ If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued.
+
+Behaviour for reading:
+ When reading `InkNames` from a TIFF file, the `NumberOfInks` will be set automatically to the number of inks in `InkNames` string.
+ If `NumberOfInks` is different to the number of inks within `InkNames` string, that will be corrected and a warning is issued.
+ If `NumberOfInks` is not equal to samplesperpixel only a warning will be issued.
+
+This allows the safe use of the NumberOfInks value to read out the InkNames without buffer overflow
+
+This MR will close the following issues: #149, #150, #152, #168 (to be checked), #250, #269, #398 and #456.
+
+It also fixes the old bug at http://bugzilla.maptools.org/show_bug.cgi?id=2599, for which the limitation of `NumberOfInks = SPP` was introduced, which is in my opinion not necessary and does not solve the general issue.
+
+---
+ libtiff/tif_dir.c | 120 ++++++++++++++++++++++++-----------------
+ libtiff/tif_dir.h | 2 +
+ libtiff/tif_dirinfo.c | 2 +-
+ libtiff/tif_dirwrite.c | 5 ++
+ libtiff/tif_print.c | 4 ++
+ 5 files changed, 83 insertions(+), 50 deletions(-)
+
+diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
+index 39aeeb4..9d8267a 100644
+--- a/libtiff/tif_dir.c
++++ b/libtiff/tif_dir.c
+@@ -29,6 +29,7 @@
+ * (and also some miscellaneous stuff)
+ */
+ #include "tiffiop.h"
++# include <inttypes.h>
+
+ /*
+ * These are used in the backwards compatibility code...
+@@ -137,32 +138,30 @@ setExtraSamples(TIFF* tif, va_list ap, uint32* v)
+ }
+
+ /*
+- * Confirm we have "samplesperpixel" ink names separated by \0. Returns
++ * Count ink names separated by \0. Returns
+ * zero if the ink names are not as expected.
+ */
+-static uint32
+-checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
++static uint16
++countInkNamesString(TIFF *tif, uint32 slen, const char *s)
+ {
+- TIFFDirectory* td = &tif->tif_dir;
+- uint16 i = td->td_samplesperpixel;
++ uint16 i = 0;
++ const char *ep = s + slen;
++ const char *cp = s;
+
+ if (slen > 0) {
+- const char* ep = s+slen;
+- const char* cp = s;
+- for (; i > 0; i--) {
++ do {
+ for (; cp < ep && *cp != '\0'; cp++) {}
+ if (cp >= ep)
+ goto bad;
+ cp++; /* skip \0 */
+- }
+- return ((uint32)(cp-s));
++ i++;
++ } while (cp < ep);
++ return (i);
+ }
+ bad:
+ TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
+- "%s: Invalid InkNames value; expecting %d names, found %d",
+- tif->tif_name,
+- td->td_samplesperpixel,
+- td->td_samplesperpixel-i);
++ "%s: Invalid InkNames value; no NUL at given buffer end location %"PRIu32", after %"PRIu16" ink",
++ tif->tif_name, slen, i);
+ return (0);
+ }
+
+@@ -476,13 +475,61 @@ _TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
+ _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
+ break;
+ case TIFFTAG_INKNAMES:
+- v = (uint16) va_arg(ap, uint16_vap);
+- s = va_arg(ap, char*);
+- v = checkInkNamesString(tif, v, s);
+- status = v > 0;
+- if( v > 0 ) {
+- _TIFFsetNString(&td->td_inknames, s, v);
+- td->td_inknameslen = v;
++ {
++ v = (uint16) va_arg(ap, uint16_vap);
++ s = va_arg(ap, char*);
++ uint16 ninksinstring;
++ ninksinstring = countInkNamesString(tif, v, s);
++ status = ninksinstring > 0;
++ if(ninksinstring > 0 ) {
++ _TIFFsetNString(&td->td_inknames, s, v);
++ td->td_inknameslen = v;
++ /* Set NumberOfInks to the value ninksinstring */
++ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
++ {
++ if (td->td_numberofinks != ninksinstring) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "Warning %s; Tag %s:\n Value %"PRIu16" of NumberOfInks is different from the number of inks %"PRIu16".\n -> NumberOfInks value adapted to %"PRIu16"",
++ tif->tif_name, fip->field_name, td->td_numberofinks, ninksinstring, ninksinstring);
++ td->td_numberofinks = ninksinstring;
++ }
++ } else {
++ td->td_numberofinks = ninksinstring;
++ TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
++ }
++ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
++ {
++ if (td->td_numberofinks != td->td_samplesperpixel) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "Warning %s; Tag %s:\n Value %"PRIu16" of NumberOfInks is different from the SamplesPerPixel value %"PRIu16"",
++ tif->tif_name, fip->field_name, td->td_numberofinks, td->td_samplesperpixel);
++ }
++ }
++ }
++ }
++ break;
++ case TIFFTAG_NUMBEROFINKS:
++ v = (uint16)va_arg(ap, uint16_vap);
++ /* If InkNames already set also NumberOfInks is set accordingly and should be equal */
++ if (TIFFFieldSet(tif, FIELD_INKNAMES))
++ {
++ if (v != td->td_numberofinks) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "Error %s; Tag %s:\n It is not possible to set the value %"PRIu32" for NumberOfInks\n which is different from the number of inks in the InkNames tag (%"PRIu16")",
++ tif->tif_name, fip->field_name, v, td->td_numberofinks);
++ /* Do not set / overwrite number of inks already set by InkNames case accordingly. */
++ status = 0;
++ }
++ } else {
++ td->td_numberofinks = (uint16)v;
++ if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
++ {
++ if (td->td_numberofinks != td->td_samplesperpixel) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "Warning %s; Tag %s:\n Value %"PRIu32" of NumberOfInks is different from the SamplesPerPixel value %"PRIu16"",
++ tif->tif_name, fip->field_name, v, td->td_samplesperpixel);
++ }
++ }
+ }
+ break;
+ case TIFFTAG_PERSAMPLE:
+@@ -887,34 +934,6 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
+ if (fip->field_bit == FIELD_CUSTOM) {
+ standard_tag = 0;
+ }
+-
+- if( standard_tag == TIFFTAG_NUMBEROFINKS )
+- {
+- int i;
+- for (i = 0; i < td->td_customValueCount; i++) {
+- uint16 val;
+- TIFFTagValue *tv = td->td_customValues + i;
+- if (tv->info->field_tag != standard_tag)
+- continue;
+- if( tv->value == NULL )
+- return 0;
+- val = *(uint16 *)tv->value;
+- /* Truncate to SamplesPerPixel, since the */
+- /* setting code for INKNAMES assume that there are SamplesPerPixel */
+- /* inknames. */
+- /* Fixes http://bugzilla.maptools.org/show_bug.cgi?id=2599 */
+- if( val > td->td_samplesperpixel )
+- {
+- TIFFWarningExt(tif->tif_clientdata,"_TIFFVGetField",
+- "Truncating NumberOfInks from %u to %u",
+- val, td->td_samplesperpixel);
+- val = td->td_samplesperpixel;
+- }
+- *va_arg(ap, uint16*) = val;
+- return 1;
+- }
+- return 0;
+- }
+
+ switch (standard_tag) {
+ case TIFFTAG_SUBFILETYPE:
+@@ -1092,6 +1111,9 @@ _TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
+ case TIFFTAG_INKNAMES:
+ *va_arg(ap, char**) = td->td_inknames;
+ break;
++ case TIFFTAG_NUMBEROFINKS:
++ *va_arg(ap, uint16 *) = td->td_numberofinks;
++ break;
+ default:
+ {
+ int i;
+diff --git a/libtiff/tif_dir.h b/libtiff/tif_dir.h
+index e7f0667..7cad679 100644
+--- a/libtiff/tif_dir.h
++++ b/libtiff/tif_dir.h
+@@ -117,6 +117,7 @@ typedef struct {
+ /* CMYK parameters */
+ int td_inknameslen;
+ char* td_inknames;
++ uint16 td_numberofinks; /* number of inks in InkNames string */
+
+ int td_customValueCount;
+ TIFFTagValue *td_customValues;
+@@ -174,6 +175,7 @@ typedef struct {
+ #define FIELD_TRANSFERFUNCTION 44
+ #define FIELD_INKNAMES 46
+ #define FIELD_SUBIFD 49
++#define FIELD_NUMBEROFINKS 50
+ /* FIELD_CUSTOM (see tiffio.h) 65 */
+ /* end of support for well-known tags; codec-private tags follow */
+ #define FIELD_CODEC 66 /* base of codec-private tags */
+diff --git a/libtiff/tif_dirinfo.c b/libtiff/tif_dirinfo.c
+index fbfaaf0..bf7de70 100644
+--- a/libtiff/tif_dirinfo.c
++++ b/libtiff/tif_dirinfo.c
+@@ -104,7 +104,7 @@ tiffFields[] = {
+ { TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", (TIFFFieldArray*) &tiffFieldArray },
+ { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL },
+ { TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL },
+- { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL },
++ { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_NUMBEROFINKS, 1, 0, "NumberOfInks", NULL },
+ { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL },
+ { TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL },
+ { TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL },
+diff --git a/libtiff/tif_dirwrite.c b/libtiff/tif_dirwrite.c
+index 9e4d306..a2dbc3b 100644
+--- a/libtiff/tif_dirwrite.c
++++ b/libtiff/tif_dirwrite.c
+@@ -677,6 +677,11 @@ TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
+ if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
+ goto bad;
+ }
++ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
++ {
++ if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, TIFFTAG_NUMBEROFINKS, tif->tif_dir.td_numberofinks))
++ goto bad;
++ }
+ if (TIFFFieldSet(tif,FIELD_SUBIFD))
+ {
+ if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
+diff --git a/libtiff/tif_print.c b/libtiff/tif_print.c
+index a073794..a9f05a7 100644
+--- a/libtiff/tif_print.c
++++ b/libtiff/tif_print.c
+@@ -402,6 +402,10 @@ TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
+ }
+ fputs("\n", fd);
+ }
++ if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS)) {
++ fprintf(fd, " NumberOfInks: %d\n",
++ td->td_numberofinks);
++ }
+ if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
+ fprintf(fd, " Thresholding: ");
+ switch (td->td_threshholding) {
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-3970.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-3970.patch
new file mode 100644
index 0000000000..ea70827cbe
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-3970.patch
@@ -0,0 +1,45 @@
+From 7e87352217d1f0c77eee7033ac59e3aab08532bb Mon Sep 17 00:00:00 2001
+From: Even Rouault <even.rouault@spatialys.com>
+Date: Tue, 8 Nov 2022 15:16:58 +0100
+Subject: [PATCH] TIFFReadRGBATileExt(): fix (unsigned) integer overflow on
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz ]
+CVE: CVE-2022-3970
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/227500897dfb07fb7d27f7aa570050e62617e3be
+Reviewed-by: Sylvain Beucler <beuc@debian.org>
+Last-Update: 2023-01-17
+
+ strips/tiles > 2 GB
+
+Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=53137
+
+---
+ libtiff/tif_getimage.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
+index 96ab146..0b90dcc 100644
+--- a/libtiff/tif_getimage.c
++++ b/libtiff/tif_getimage.c
+@@ -3042,15 +3042,15 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop
+ return( ok );
+
+ for( i_row = 0; i_row < read_ysize; i_row++ ) {
+- memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
+- raster + (read_ysize - i_row - 1) * read_xsize,
++ memmove( raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize,
++ raster + (size_t)(read_ysize - i_row - 1) * read_xsize,
+ read_xsize * sizeof(uint32) );
+- _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
++ _TIFFmemset( raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize+read_xsize,
+ 0, sizeof(uint32) * (tile_xsize - read_xsize) );
+ }
+
+ for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
+- _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
++ _TIFFmemset( raster + (size_t)(tile_ysize - i_row - 1) * tile_xsize,
+ 0, sizeof(uint32) * tile_xsize );
+ }
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-40090.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-40090.patch
new file mode 100644
index 0000000000..0a88f59553
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-40090.patch
@@ -0,0 +1,548 @@
+From d385738335deb0c4bb70449f12e411f2203c0d01 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Fri, 2 Sep 2022 21:20:28 +0200
+Subject: [PATCH 1/4] Improved IFD-Loop Handling (fixes #455)
+
+Basic approach:
+- The order in the entire chain must be checked, and not only whether an offset has already been read once.
+- To do this, pairs of directory number and offset are stored and checked.
+- The offset of a directory number can change.
+- TIFFAdvanceDirectory() must also perform an IFD loop check.
+- TIFFCheckDirOffset() is replaced by _TIFFCheckDirNumberAndOffset().
+
+Rules for the check:
+- If an offset is already in the list, it must have the same IFD number. Otherwise it is an IDF loop.
+- If the offset is not in the list and the IFD number is greater than there are list entries, a new list entry is added.
+- Otherwise, the offset of the IFD number is updated.
+
+Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/tiff/tree/debian/patches/CVE-2022-40090.patch?h=ubuntu/focal-security
+Upstream commit
+https://gitlab.com/libtiff/libtiff/-/commit/c7caec9a4d8f24c17e667480d2c7d0d51c9fae41]
+CVE: CVE-2022-40090
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ libtiff/tif_close.c | 6 ++-
+ libtiff/tif_dir.c | 91 +++++++++++++++++++++++++----------------
+ libtiff/tif_dir.h | 1 +
+ libtiff/tif_dirread.c | 94 ++++++++++++++++++++++++++++++-------------
+ libtiff/tif_open.c | 3 +-
+ libtiff/tiffiop.h | 3 +-
+ 6 files changed, 131 insertions(+), 67 deletions(-)
+
+--- tiff-4.1.0+git191117.orig/libtiff/tif_close.c
++++ tiff-4.1.0+git191117/libtiff/tif_close.c
+@@ -52,8 +52,10 @@ TIFFCleanup(TIFF* tif)
+ (*tif->tif_cleanup)(tif);
+ TIFFFreeDirectory(tif);
+
+- if (tif->tif_dirlist)
+- _TIFFfree(tif->tif_dirlist);
++ if (tif->tif_dirlistoff)
++ _TIFFfree(tif->tif_dirlistoff);
++ if (tif->tif_dirlistdirn)
++ _TIFFfree(tif->tif_dirlistdirn);
+
+ /*
+ * Clean up client info links.
+--- tiff-4.1.0+git191117.orig/libtiff/tif_dir.c
++++ tiff-4.1.0+git191117/libtiff/tif_dir.c
+@@ -1463,12 +1463,22 @@ TIFFDefaultDirectory(TIFF* tif)
+ }
+
+ static int
+-TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
++TIFFAdvanceDirectory(TIFF* tif, uint64* nextdiroff, uint64* off, uint16* nextdirnum)
+ {
+ static const char module[] = "TIFFAdvanceDirectory";
++
++ /* Add this directory to the directory list, if not already in. */
++ if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) {
++ TIFFErrorExt(tif->tif_clientdata, module, "Starting directory %hu at offset 0x%lx (%lu) might cause an IFD loop",
++ *nextdirnum, *nextdiroff, *nextdiroff);
++ *nextdiroff = 0;
++ *nextdirnum = 0;
++ return(0);
++ }
++
+ if (isMapped(tif))
+ {
+- uint64 poff=*nextdir;
++ uint64 poff=*nextdiroff;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ tmsize_t poffa,poffb,poffc,poffd;
+@@ -1479,7 +1489,7 @@ TIFFAdvanceDirectory(TIFF* tif, uint64*
+ if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
+- *nextdir=0;
++ *nextdiroff=0;
+ return(0);
+ }
+ _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
+@@ -1497,7 +1507,7 @@ TIFFAdvanceDirectory(TIFF* tif, uint64*
+ _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+- *nextdir=nextdir32;
++ *nextdiroff=nextdir32;
+ }
+ else
+ {
+@@ -1529,11 +1539,10 @@ TIFFAdvanceDirectory(TIFF* tif, uint64*
+ }
+ if (off!=NULL)
+ *off=(uint64)poffc;
+- _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
++ _TIFFmemcpy(nextdiroff,tif->tif_base+poffc,sizeof(uint64));
+ if (tif->tif_flags&TIFF_SWAB)
+- TIFFSwabLong8(nextdir);
++ TIFFSwabLong8(nextdiroff);
+ }
+- return(1);
+ }
+ else
+ {
+@@ -1541,7 +1550,7 @@ TIFFAdvanceDirectory(TIFF* tif, uint64*
+ {
+ uint16 dircount;
+ uint32 nextdir32;
+- if (!SeekOK(tif, *nextdir) ||
++ if (!SeekOK(tif, *nextdiroff) ||
+ !ReadOK(tif, &dircount, sizeof (uint16))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
+ tif->tif_name);
+@@ -1562,13 +1571,13 @@ TIFFAdvanceDirectory(TIFF* tif, uint64*
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+- *nextdir=nextdir32;
++ *nextdiroff=nextdir32;
+ }
+ else
+ {
+ uint64 dircount64;
+ uint16 dircount16;
+- if (!SeekOK(tif, *nextdir) ||
++ if (!SeekOK(tif, *nextdiroff) ||
+ !ReadOK(tif, &dircount64, sizeof (uint64))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
+ tif->tif_name);
+@@ -1588,17 +1597,27 @@ TIFFAdvanceDirectory(TIFF* tif, uint64*
+ else
+ (void) TIFFSeekFile(tif,
+ dircount16*20, SEEK_CUR);
+- if (!ReadOK(tif, nextdir, sizeof (uint64))) {
++ if (!ReadOK(tif, nextdiroff, sizeof (uint64))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Error fetching directory link",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+- TIFFSwabLong8(nextdir);
++ TIFFSwabLong8(nextdiroff);
+ }
+- return (1);
+ }
++ if (*nextdiroff != 0) {
++ (*nextdirnum)++;
++ /* Check next directory for IFD looping and if so, set it as last directory. */
++ if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff)) {
++ TIFFWarningExt(tif->tif_clientdata, module, "the next directory %hu at offset 0x%lx (%lu) might be an IFD loop. Treating directory %hu as last directory",
++ *nextdirnum, *nextdiroff, *nextdiroff, *nextdirnum-1);
++ *nextdiroff = 0;
++ (*nextdirnum)--;
++ }
++ }
++ return (1);
+ }
+
+ /*
+@@ -1608,14 +1627,16 @@ uint16
+ TIFFNumberOfDirectories(TIFF* tif)
+ {
+ static const char module[] = "TIFFNumberOfDirectories";
+- uint64 nextdir;
++ uint64 nextdiroff;
++ uint16 nextdirnum;
+ uint16 n;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+- nextdir = tif->tif_header.classic.tiff_diroff;
++ nextdiroff = tif->tif_header.classic.tiff_diroff;
+ else
+- nextdir = tif->tif_header.big.tiff_diroff;
++ nextdiroff = tif->tif_header.big.tiff_diroff;
++ nextdirnum = 0;
+ n = 0;
+- while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
++ while (nextdiroff != 0 && TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
+ {
+ if (n != 65535) {
+ ++n;
+@@ -1638,28 +1659,30 @@ TIFFNumberOfDirectories(TIFF* tif)
+ int
+ TIFFSetDirectory(TIFF* tif, uint16 dirn)
+ {
+- uint64 nextdir;
++ uint64 nextdiroff;
++ uint16 nextdirnum;
+ uint16 n;
+
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+- nextdir = tif->tif_header.classic.tiff_diroff;
++ nextdiroff = tif->tif_header.classic.tiff_diroff;
+ else
+- nextdir = tif->tif_header.big.tiff_diroff;
+- for (n = dirn; n > 0 && nextdir != 0; n--)
+- if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
++ nextdiroff = tif->tif_header.big.tiff_diroff;
++ nextdirnum = 0;
++ for (n = dirn; n > 0 && nextdiroff != 0; n--)
++ if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
+ return (0);
+- tif->tif_nextdiroff = nextdir;
++ /* If the n-th directory could not be reached (does not exist),
++ * return here without touching anything further. */
++ if (nextdiroff == 0 || n > 0)
++ return (0);
++
++ tif->tif_nextdiroff = nextdiroff;
+ /*
+ * Set curdir to the actual directory index. The
+ * -1 is because TIFFReadDirectory will increment
+ * tif_curdir after successfully reading the directory.
+ */
+ tif->tif_curdir = (dirn - n) - 1;
+- /*
+- * Reset tif_dirnumber counter and start new list of seen directories.
+- * We need this to prevent IFD loops.
+- */
+- tif->tif_dirnumber = 0;
+ return (TIFFReadDirectory(tif));
+ }
+
+@@ -1672,13 +1695,42 @@ TIFFSetDirectory(TIFF* tif, uint16 dirn)
+ int
+ TIFFSetSubDirectory(TIFF* tif, uint64 diroff)
+ {
+- tif->tif_nextdiroff = diroff;
+- /*
+- * Reset tif_dirnumber counter and start new list of seen directories.
+- * We need this to prevent IFD loops.
++ /* Match nextdiroff and curdir for consistent IFD-loop checking.
++ * Only with TIFFSetSubDirectory() the IFD list can be corrupted with invalid offsets
++ * within the main IFD tree.
++ * In the case of several subIFDs of a main image,
++ * there are two possibilities that are not even mutually exclusive.
++ * a.) The subIFD tag contains an array with all offsets of the subIFDs.
++ * b.) The SubIFDs are concatenated with their NextIFD parameters.
++ * (refer to https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
+ */
+- tif->tif_dirnumber = 0;
+- return (TIFFReadDirectory(tif));
++ int retval;
++ uint16 curdir = 0;
++ int8 probablySubIFD = 0;
++ if (diroff == 0) {
++ /* Special case to invalidate the tif_lastdiroff member. */
++ tif->tif_curdir = 65535;
++ } else {
++ if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir)) {
++ /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
++ probablySubIFD = 1;
++ }
++ /* -1 because TIFFReadDirectory() will increment tif_curdir. */
++ tif->tif_curdir = curdir - 1;
++ }
++
++ tif->tif_nextdiroff = diroff;
++ retval = TIFFReadDirectory(tif);
++ /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it back. */
++ if (!retval )tif->tif_curdir++;
++ if (retval && probablySubIFD) {
++ /* Reset IFD list to start new one for SubIFD chain and also start SubIFD chain with tif_curdir=0. */
++ tif->tif_dirnumber = 0;
++ tif->tif_curdir = 0; /* first directory of new chain */
++ /* add this offset to new IFD list */
++ _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
++ }
++ return (retval);
+ }
+
+ /*
+@@ -1702,12 +1754,15 @@ TIFFLastDirectory(TIFF* tif)
+
+ /*
+ * Unlink the specified directory from the directory chain.
++ * Note: First directory starts with number dirn=1.
++ * This is different to TIFFSetDirectory() where the first directory starts with zero.
+ */
+ int
+ TIFFUnlinkDirectory(TIFF* tif, uint16 dirn)
+ {
+ static const char module[] = "TIFFUnlinkDirectory";
+ uint64 nextdir;
++ uint16 nextdirnum;
+ uint64 off;
+ uint16 n;
+
+@@ -1731,19 +1786,21 @@ TIFFUnlinkDirectory(TIFF* tif, uint16 di
+ nextdir = tif->tif_header.big.tiff_diroff;
+ off = 8;
+ }
++ nextdirnum = 0; /* First directory is dirn=0 */
++
+ for (n = dirn-1; n > 0; n--) {
+ if (nextdir == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
+ return (0);
+ }
+- if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
++ if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
+ return (0);
+ }
+ /*
+ * Advance to the directory to be unlinked and fetch
+ * the offset of the directory that follows.
+ */
+- if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
++ if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
+ return (0);
+ /*
+ * Go back and patch the link field of the preceding
+--- tiff-4.1.0+git191117.orig/libtiff/tif_dir.h
++++ tiff-4.1.0+git191117/libtiff/tif_dir.h
+@@ -300,6 +300,8 @@ extern int _TIFFMergeFields(TIFF*, const
+ extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType);
+ extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType);
+ extern int _TIFFCheckFieldIsValidForCodec(TIFF *tif, ttag_t tag);
++extern int _TIFFCheckDirNumberAndOffset(TIFF *tif, uint16 dirn, uint64 diroff);
++extern int _TIFFGetDirNumberFromOffset(TIFF *tif, uint64 diroff, uint16 *dirn);
+
+ #if defined(__cplusplus)
+ }
+--- tiff-4.1.0+git191117.orig/libtiff/tif_dirread.c
++++ tiff-4.1.0+git191117/libtiff/tif_dirread.c
+@@ -158,7 +158,6 @@ static void TIFFReadDirectoryFindFieldIn
+
+ static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
+ static void MissingRequired(TIFF*, const char*);
+-static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
+ static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
+ static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff);
+ static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
+@@ -3584,12 +3583,19 @@ TIFFReadDirectory(TIFF* tif)
+ int bitspersample_read = FALSE;
+ int color_channels;
+
+- tif->tif_diroff=tif->tif_nextdiroff;
+- if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
+- return 0; /* last offset or bad offset (IFD looping) */
+- (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
+- tif->tif_curdir++;
+- nextdiroff = tif->tif_nextdiroff;
++ if (tif->tif_nextdiroff == 0) {
++ /* In this special case, tif_diroff needs also to be set to 0. */
++ tif->tif_diroff = tif->tif_nextdiroff;
++ return 0; /* last offset, thus no checking necessary */
++ }
++
++ nextdiroff = tif->tif_nextdiroff;
++ /* tif_curdir++ and tif_nextdiroff should only be updated after SUCCESSFUL reading of the directory. Otherwise, invalid IFD offsets could corrupt the IFD list. */
++ if (!_TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir + 1, nextdiroff)) {
++ TIFFWarningExt(tif->tif_clientdata, module,
++ "Didn't read next directory due to IFD looping at offset 0x%lx (%lu) to offset 0x%lx (%lu)", tif->tif_diroff, tif->tif_diroff, nextdiroff, nextdiroff);
++ return 0; /* bad offset (IFD looping) */
++ }
+ dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff);
+ if (!dircount)
+ {
+@@ -3597,6 +3603,11 @@ TIFFReadDirectory(TIFF* tif)
+ "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff);
+ return 0;
+ }
++ /* Set global values after a valid directory has been fetched.
++ * tif_diroff is already set to nextdiroff in TIFFFetchDirectory() in the beginning. */
++ tif->tif_curdir++;
++ (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
++
+ TIFFReadDirectoryCheckOrder(tif,dir,dircount);
+
+ /*
+@@ -4628,13 +4639,17 @@ MissingRequired(TIFF* tif, const char* t
+ }
+
+ /*
+- * Check the directory offset against the list of already seen directory
+- * offsets. This is a trick to prevent IFD looping. The one can create TIFF
+- * file with looped directory pointers. We will maintain a list of already
+- * seen directories and check every IFD offset against that list.
++ * Check the directory number and offset against the list of already seen
++ * directory numbers and offsets. This is a trick to prevent IFD looping.
++ * The one can create TIFF file with looped directory pointers. We will
++ * maintain a list of already seen directories and check every IFD offset
++ * and its IFD number against that list. However, the offset of an IFD number
++ * can change - e.g. when writing updates to file.
++ * Returns 1 if all is ok; 0 if last directory or IFD loop is encountered,
++ * or an error has occured.
+ */
+-static int
+-TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
++int
++_TIFFCheckDirNumberAndOffset(TIFF* tif, uint16 dirn, uint64 diroff)
+ {
+ uint16 n;
+
+@@ -4646,35 +4661,64 @@ TIFFCheckDirOffset(TIFF* tif, uint64 dir
+ return 0;
+ }
+
+- for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
+- if (tif->tif_dirlist[n] == diroff)
+- return 0;
++ /* Check if offset is already in the list:
++ * - yes: check, if offset is at the same IFD number - if not, it is an IFD loop
++ * - no: add to list or update offset at that IFD number
++ */
++ for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlistdirn && tif->tif_dirlistoff; n++) {
++ if (tif->tif_dirlistoff[n] == diroff) {
++ if (tif->tif_dirlistdirn[n] == dirn) {
++ return 1;
++ } else {
++ TIFFWarningExt(tif->tif_clientdata, "_TIFFCheckDirNumberAndOffset",
++ "TIFF directory %hu has IFD looping to directory %hu at offset 0x%lx (%lu)",
++ dirn-1, tif->tif_dirlistdirn[n], diroff, diroff);
++ return 0;
++ }
++ }
++ }
++ /* Check if offset of an IFD has been changed and update offset of that IFD number. */
++ if (dirn < tif->tif_dirnumber && tif->tif_dirlistdirn && tif->tif_dirlistoff) {
++ /* tif_dirlistdirn can have IFD numbers dirn in random order */
++ for (n = 0; n < tif->tif_dirnumber; n++) {
++ if (tif->tif_dirlistdirn[n] == dirn) {
++ tif->tif_dirlistoff[n] = diroff;
++ return 1;
++ }
++ }
+ }
+
++ /* Add IFD offset and dirn to IFD directory list */
+ tif->tif_dirnumber++;
+
+- if (tif->tif_dirlist == NULL || tif->tif_dirnumber > tif->tif_dirlistsize) {
+- uint64* new_dirlist;
+-
++ if (tif->tif_dirlistoff == NULL || tif->tif_dirlistdirn == NULL || tif->tif_dirnumber > tif->tif_dirlistsize) {
++ uint64 *new_dirlist;
+ /*
+ * XXX: Reduce memory allocation granularity of the dirlist
+ * array.
+ */
+- new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist,
+- tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
++ if (tif->tif_dirnumber >= 32768)
++ tif->tif_dirlistsize = 65535;
++ else
++ tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
++
++ new_dirlist = (uint64 *)_TIFFCheckRealloc(tif, tif->tif_dirlistoff,
++ tif->tif_dirlistsize, sizeof(uint64), "for IFD offset list");
+ if (!new_dirlist)
+ return 0;
+- if( tif->tif_dirnumber >= 32768 )
+- tif->tif_dirlistsize = 65535;
+- else
+- tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
+- tif->tif_dirlist = new_dirlist;
++ tif->tif_dirlistoff = new_dirlist;
++ new_dirlist = (uint64 *)_TIFFCheckRealloc(tif, tif->tif_dirlistdirn,
++ tif->tif_dirlistsize, sizeof(uint16), "for IFD dirnumber list");
++ if (!new_dirlist)
++ return 0;
++ tif->tif_dirlistdirn = (uint16 *)new_dirlist;
+ }
+
+- tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
++ tif->tif_dirlistoff[tif->tif_dirnumber - 1] = diroff;
++ tif->tif_dirlistdirn[tif->tif_dirnumber - 1] = dirn;
+
+ return 1;
+-}
++} /* --- _TIFFCheckDirNumberAndOffset() ---*/
+
+ /*
+ * Check the count field of a directory entry against a known value. The
+@@ -4703,6 +4747,47 @@ CheckDirCount(TIFF* tif, TIFFDirEntry* d
+ }
+
+ /*
++ * Retrieve the matching IFD directory number of a given IFD offset
++ * from the list of directories already seen.
++ * Returns 1 if the offset was in the list and the directory number
++ * can be returned.
++ * Otherwise returns 0 or if an error occured.
++ */
++int
++_TIFFGetDirNumberFromOffset(TIFF *tif, uint64 diroff, uint16* dirn)
++{
++ uint16 n;
++
++ if (diroff == 0) /* no more directories */
++ return 0;
++ if (tif->tif_dirnumber == 65535) {
++ TIFFErrorExt(tif->tif_clientdata, "_TIFFGetDirNumberFromOffset",
++ "Cannot handle more than 65535 TIFF directories");
++ return 0;
++ }
++
++ /* Check if offset is already in the list and return matching directory number.
++ * Otherwise update IFD list using TIFFNumberOfDirectories()
++ * and search again in IFD list.
++ */
++ for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlistoff && tif->tif_dirlistdirn; n++) {
++ if (tif->tif_dirlistoff[n] == diroff) {
++ *dirn = tif->tif_dirlistdirn[n];
++ return 1;
++ }
++ }
++ TIFFNumberOfDirectories(tif);
++ for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlistoff && tif->tif_dirlistdirn; n++) {
++ if (tif->tif_dirlistoff[n] == diroff) {
++ *dirn = tif->tif_dirlistdirn[n];
++ return 1;
++ }
++ }
++ return 0;
++} /*--- _TIFFGetDirNumberFromOffset() ---*/
++
++
++/*
+ * Read IFD structure from the specified offset. If the pointer to
+ * nextdiroff variable has been specified, read it too. Function returns a
+ * number of fields in the directory or 0 if failed.
+--- tiff-4.1.0+git191117.orig/libtiff/tif_open.c
++++ tiff-4.1.0+git191117/libtiff/tif_open.c
+@@ -353,7 +353,8 @@ TIFFClientOpen(
+ if (!TIFFDefaultDirectory(tif))
+ goto bad;
+ tif->tif_diroff = 0;
+- tif->tif_dirlist = NULL;
++ tif->tif_dirlistoff = NULL;
++ tif->tif_dirlistdirn = NULL;
+ tif->tif_dirlistsize = 0;
+ tif->tif_dirnumber = 0;
+ return (tif);
+--- tiff-4.1.0+git191117.orig/libtiff/tiffiop.h
++++ tiff-4.1.0+git191117/libtiff/tiffiop.h
+@@ -145,7 +145,8 @@ struct tiff {
+ #define TIFF_CHOPPEDUPARRAYS 0x4000000U /* set when allocChoppedUpStripArrays() has modified strip array */
+ uint64 tif_diroff; /* file offset of current directory */
+ uint64 tif_nextdiroff; /* file offset of following directory */
+- uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */
++ uint64* tif_dirlistoff; /* list of offsets to already seen directories to prevent IFD looping */
++ uint16* tif_dirlistdirn; /* list of directory numbers to already seen directories to prevent IFD looping */
+ uint16 tif_dirlistsize; /* number of entries in offset list */
+ uint16 tif_dirnumber; /* number of already seen directories */
+ TIFFDirectory tif_dir; /* internal rep of current directory */
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2022-48281.patch b/meta/recipes-multimedia/libtiff/files/CVE-2022-48281.patch
new file mode 100644
index 0000000000..5747202bd9
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2022-48281.patch
@@ -0,0 +1,26 @@
+From 424c82b5b33256e7f03faace51dc8010f3ded9ff Mon Sep 17 00:00:00 2001
+From: Su Laus <sulau@freenet.de>
+Date: Sat, 21 Jan 2023 15:58:10 +0000
+Subject: [PATCH] tiffcrop: Correct simple copy paste error. Fix #488.
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz]
+CVE: CVE-2022-48281
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+
+---
+ tools/tiffcrop.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index a0789a3..8aed9cd 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -7564,7 +7564,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ crop_buff = (unsigned char *)_TIFFmalloc(cropsize + NUM_BUFF_OVERSIZE_BYTES);
+ else
+ {
+- prev_cropsize = seg_buffs[0].size;
++ prev_cropsize = seg_buffs[i].size;
+ if (prev_cropsize < cropsize)
+ {
+ next_buff = _TIFFrealloc(crop_buff, cropsize + NUM_BUFF_OVERSIZE_BYTES);
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-0795_0796_0797_0798_0799.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-0795_0796_0797_0798_0799.patch
new file mode 100644
index 0000000000..253018525a
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-0795_0796_0797_0798_0799.patch
@@ -0,0 +1,157 @@
+From 7808740e100ba30ffb791044f3b14dec3e85ed6f Mon Sep 17 00:00:00 2001
+From: Markus Koschany <apo@debian.org>
+Date: Tue, 21 Feb 2023 14:26:43 +0100
+Subject: [PATCH] CVE-2023-0795
+
+This is also the fix for CVE-2023-0796, CVE-2023-0797, CVE-2023-0798,
+CVE-2023-0799.
+
+Bug-Debian: https://bugs.debian.org/1031632
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/afaabc3e50d4e5d80a94143f7e3c997e7e410f68
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz ]
+CVE: CVE-2023-0795 CVE-2023-0796 CVE-2023-0797 CVE-2023-0798 CVE-2023-0799
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ tools/tiffcrop.c | 51 ++++++++++++++++++++++++++++--------------------
+ 1 file changed, 30 insertions(+), 21 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index 8aed9cd..f21a7d7 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -277,7 +277,6 @@ struct region {
+ uint32 width; /* width in pixels */
+ uint32 length; /* length in pixels */
+ uint32 buffsize; /* size of buffer needed to hold the cropped region */
+- unsigned char *buffptr; /* address of start of the region */
+ };
+
+ /* Cropping parameters from command line and image data
+@@ -532,7 +531,7 @@ static int rotateContigSamples24bits(uint16, uint16, uint16, uint32,
+ static int rotateContigSamples32bits(uint16, uint16, uint16, uint32,
+ uint32, uint32, uint8 *, uint8 *);
+ static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
+- unsigned char **);
++ unsigned char **, int);
+ static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
+ unsigned char *);
+ static int invertImage(uint16, uint16, uint16, uint32, uint32,
+@@ -5112,7 +5111,6 @@ initCropMasks (struct crop_mask *cps)
+ cps->regionlist[i].width = 0;
+ cps->regionlist[i].length = 0;
+ cps->regionlist[i].buffsize = 0;
+- cps->regionlist[i].buffptr = NULL;
+ cps->zonelist[i].position = 0;
+ cps->zonelist[i].total = 0;
+ }
+@@ -6358,8 +6356,13 @@ static int correct_orientation(struct image_data *image, unsigned char **work_b
+ image->adjustments & ROTATE_ANY);
+ return (-1);
+ }
+-
+- if (rotateImage(rotation, image, &image->width, &image->length, work_buff_ptr))
++
++ /* Dummy variable in order not to switch two times the
++ * image->width,->length within rotateImage(),
++ * but switch xres, yres there. */
++ uint32_t width = image->width;
++ uint32_t length = image->length;
++ if (rotateImage(rotation, image, &width, &length, work_buff_ptr, TRUE))
+ {
+ TIFFError ("correct_orientation", "Unable to rotate image");
+ return (-1);
+@@ -6427,7 +6430,6 @@ extractCompositeRegions(struct image_data *image, struct crop_mask *crop,
+ /* These should not be needed for composite images */
+ crop->regionlist[i].width = crop_width;
+ crop->regionlist[i].length = crop_length;
+- crop->regionlist[i].buffptr = crop_buff;
+
+ src_rowsize = ((img_width * bps * spp) + 7) / 8;
+ dst_rowsize = (((crop_width * bps * count) + 7) / 8);
+@@ -6664,7 +6666,6 @@ extractSeparateRegion(struct image_data *image, struct crop_mask *crop,
+
+ crop->regionlist[region].width = crop_width;
+ crop->regionlist[region].length = crop_length;
+- crop->regionlist[region].buffptr = crop_buff;
+
+ src = read_buff;
+ dst = crop_buff;
+@@ -7542,7 +7543,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
+ {
+ if (rotateImage(crop->rotation, image, &crop->combined_width,
+- &crop->combined_length, &crop_buff))
++ &crop->combined_length, &crop_buff, FALSE))
+ {
+ TIFFError("processCropSelections",
+ "Failed to rotate composite regions by %d degrees", crop->rotation);
+@@ -7648,7 +7649,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
+ {
+ if (rotateImage(crop->rotation, image, &crop->regionlist[i].width,
+- &crop->regionlist[i].length, &crop_buff))
++ &crop->regionlist[i].length, &crop_buff, FALSE))
+ {
+ TIFFError("processCropSelections",
+ "Failed to rotate crop region by %d degrees", crop->rotation);
+@@ -7780,7 +7781,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop,
+ if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
+ {
+ if (rotateImage(crop->rotation, image, &crop->combined_width,
+- &crop->combined_length, crop_buff_ptr))
++ &crop->combined_length, crop_buff_ptr, TRUE))
+ {
+ TIFFError("createCroppedImage",
+ "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
+@@ -8443,7 +8444,7 @@ rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
+ /* Rotate an image by a multiple of 90 degrees clockwise */
+ static int
+ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+- uint32 *img_length, unsigned char **ibuff_ptr)
++ uint32 *img_length, unsigned char **ibuff_ptr, int rot_image_params)
+ {
+ int shift_width;
+ uint32 bytes_per_pixel, bytes_per_sample;
+@@ -8634,11 +8635,15 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+
+ *img_width = length;
+ *img_length = width;
+- image->width = length;
+- image->length = width;
+- res_temp = image->xres;
+- image->xres = image->yres;
+- image->yres = res_temp;
++ /* Only toggle image parameters if whole input image is rotated. */
++ if (rot_image_params)
++ {
++ image->width = length;
++ image->length = width;
++ res_temp = image->xres;
++ image->xres = image->yres;
++ image->yres = res_temp;
++ }
+ break;
+
+ case 270: if ((bps % 8) == 0) /* byte aligned data */
+@@ -8711,11 +8716,15 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+
+ *img_width = length;
+ *img_length = width;
+- image->width = length;
+- image->length = width;
+- res_temp = image->xres;
+- image->xres = image->yres;
+- image->yres = res_temp;
++ /* Only toggle image parameters if whole input image is rotated. */
++ if (rot_image_params)
++ {
++ image->width = length;
++ image->length = width;
++ res_temp = image->xres;
++ image->xres = image->yres;
++ image->yres = res_temp;
++ }
+ break;
+ default:
+ break;
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-0800_0801_0802_0803_0804.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-0800_0801_0802_0803_0804.patch
new file mode 100644
index 0000000000..bf1a439b4d
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-0800_0801_0802_0803_0804.patch
@@ -0,0 +1,135 @@
+From e18be834497e0ebf68d443abb9e18187f36cd3bf Mon Sep 17 00:00:00 2001
+From: Markus Koschany <apo@debian.org>
+Date: Tue, 21 Feb 2023 14:39:52 +0100
+Subject: [PATCH] CVE-2023-0800
+
+This is also the fix for CVE-2023-0801, CVE-2023-0802, CVE-2023-0803,
+CVE-2023-0804.
+
+Bug-Debian: https://bugs.debian.org/1031632
+Origin: https://gitlab.com/libtiff/libtiff/-/commit/33aee1275d9d1384791d2206776eb8152d397f00
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u7.debian.tar.xz ]
+CVE: CVE-2023-0800 CVE-2023-0801 CVE-2023-0802 CVE-2023-0803 CVE-2023-0804
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ tools/tiffcrop.c | 73 +++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 69 insertions(+), 4 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index f21a7d7..742615a 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -5250,18 +5250,40 @@ computeInputPixelOffsets(struct crop_mask *crop, struct image_data *image,
+
+ crop->regionlist[i].buffsize = buffsize;
+ crop->bufftotal += buffsize;
++
++ /* For composite images with more than one region, the
++ * combined_length or combined_width always needs to be equal,
++ * respectively.
++ * Otherwise, even the first section/region copy
++ * action might cause buffer overrun. */
+ if (crop->img_mode == COMPOSITE_IMAGES)
+ {
+ switch (crop->edge_ref)
+ {
+ case EDGE_LEFT:
+ case EDGE_RIGHT:
++ if (i > 0 && zlength != crop->combined_length)
++ {
++ TIFFError(
++ "computeInputPixelOffsets",
++ "Only equal length regions can be combined for "
++ "-E left or right");
++ return (-1);
++ }
+ crop->combined_length = zlength;
+ crop->combined_width += zwidth;
+ break;
+ case EDGE_BOTTOM:
+ case EDGE_TOP: /* width from left, length from top */
+ default:
++ if (i > 0 && zwidth != crop->combined_width)
++ {
++ TIFFError("computeInputPixelOffsets",
++ "Only equal width regions can be "
++ "combined for -E "
++ "top or bottom");
++ return (-1);
++ }
+ crop->combined_width = zwidth;
+ crop->combined_length += zlength;
+ break;
+@@ -6416,6 +6438,47 @@ extractCompositeRegions(struct image_data *image, struct crop_mask *crop,
+ crop->combined_width = 0;
+ crop->combined_length = 0;
+
++ /* If there is more than one region, check beforehand whether all the width
++ * and length values of the regions are the same, respectively. */
++ switch (crop->edge_ref)
++ {
++ default:
++ case EDGE_TOP:
++ case EDGE_BOTTOM:
++ for (i = 1; i < crop->selections; i++)
++ {
++ uint32_t crop_width0 =
++ crop->regionlist[i - 1].x2 - crop->regionlist[i - 1].x1 + 1;
++ uint32_t crop_width1 =
++ crop->regionlist[i].x2 - crop->regionlist[i].x1 + 1;
++ if (crop_width0 != crop_width1)
++ {
++ TIFFError("extractCompositeRegions",
++ "Only equal width regions can be combined for -E "
++ "top or bottom");
++ return (1);
++ }
++ }
++ break;
++ case EDGE_LEFT:
++ case EDGE_RIGHT:
++ for (i = 1; i < crop->selections; i++)
++ {
++ uint32_t crop_length0 =
++ crop->regionlist[i - 1].y2 - crop->regionlist[i - 1].y1 + 1;
++ uint32_t crop_length1 =
++ crop->regionlist[i].y2 - crop->regionlist[i].y1 + 1;
++ if (crop_length0 != crop_length1)
++ {
++ TIFFError("extractCompositeRegions",
++ "Only equal length regions can be combined for "
++ "-E left or right");
++ return (1);
++ }
++ }
++ }
++
++
+ for (i = 0; i < crop->selections; i++)
+ {
+ /* rows, columns, width, length are expressed in pixels */
+@@ -6439,8 +6502,9 @@ extractCompositeRegions(struct image_data *image, struct crop_mask *crop,
+ default:
+ case EDGE_TOP:
+ case EDGE_BOTTOM:
+- if ((i > 0) && (crop_width != crop->regionlist[i - 1].width))
+- {
++ if ((crop->selections > i + 1) &&
++ (crop_width != crop->regionlist[i + 1].width))
++ {
+ TIFFError ("extractCompositeRegions",
+ "Only equal width regions can be combined for -E top or bottom");
+ return (1);
+@@ -6520,8 +6584,9 @@ extractCompositeRegions(struct image_data *image, struct crop_mask *crop,
+ break;
+ case EDGE_LEFT: /* splice the pieces of each row together, side by side */
+ case EDGE_RIGHT:
+- if ((i > 0) && (crop_length != crop->regionlist[i - 1].length))
+- {
++ if ((crop->selections > i + 1) &&
++ (crop_length != crop->regionlist[i + 1].length))
++ {
+ TIFFError ("extractCompositeRegions",
+ "Only equal length regions can be combined for -E left or right");
+ return (1);
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-1916.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-1916.patch
new file mode 100644
index 0000000000..9915b77645
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-1916.patch
@@ -0,0 +1,91 @@
+From 848434a81c443f59ec90d41218eba6e48a450a11 Mon Sep 17 00:00:00 2001
+From: zhailiangliang <zhailiangliang@loongson.cn>
+Date: Thu, 16 Mar 2023 16:16:54 +0800
+Subject: [PATCH] Fix heap-buffer-overflow in function extractImageSection
+
+CVE: CVE-2023-1916
+Upstream-Status: Submitted [https://gitlab.com/libtiff/libtiff/-/commit/848434a81c443f59ec90d41218eba6e48a450a11 https://gitlab.com/libtiff/libtiff/-/merge_requests/535]
+Signed-off-by: Marek Vasut <marex@denx.de>
+---
+ archive/tools/tiffcrop.c | 62 +++++++++++++++++++++++++++++-----------
+ 1 file changed, 45 insertions(+), 17 deletions(-)
+
+--- tiff-4.1.0+git191117.orig/tools/tiffcrop.c
++++ tiff-4.1.0+git191117/tools/tiffcrop.c
+@@ -5549,6 +5549,15 @@ getCropOffsets(struct image_data *image,
+ crop->combined_width += (uint32)zwidth;
+ else
+ crop->combined_width = (uint32)zwidth;
++
++ /* When the degrees clockwise rotation is 90 or 270, check the boundary */
++ if (((crop->rotation == 90) || (crop->rotation == 270))
++ && ((crop->combined_length > image->width) || (crop->combined_width > image->length)))
++ {
++ TIFFError("getCropOffsets", "The crop size exceeds the image boundary size");
++ return -1;
++ }
++
+ break;
+ case EDGE_BOTTOM: /* width from left, zones from bottom to top */
+ zwidth = offsets.crop_width;
+@@ -5579,6 +5588,15 @@ getCropOffsets(struct image_data *image,
+ else
+ crop->combined_length = (uint32)zlength;
+ crop->combined_width = (uint32)zwidth;
++
++ /* When the degrees clockwise rotation is 90 or 270, check the boundary */
++ if (((crop->rotation == 90) || (crop->rotation == 270))
++ && ((crop->combined_length > image->width) || (crop->combined_width > image->length)))
++ {
++ TIFFError("getCropOffsets", "The crop size exceeds the image boundary size");
++ return -1;
++ }
++
+ break;
+ case EDGE_RIGHT: /* zones from right to left, length from top */
+ zlength = offsets.crop_length;
+@@ -5606,6 +5624,15 @@ getCropOffsets(struct image_data *image,
+ crop->combined_width += (uint32)zwidth;
+ else
+ crop->combined_width = (uint32)zwidth;
++
++ /* When the degrees clockwise rotation is 90 or 270, check the boundary */
++ if (((crop->rotation == 90) || (crop->rotation == 270))
++ && ((crop->combined_length > image->width) || (crop->combined_width > image->length)))
++ {
++ TIFFError("getCropOffsets", "The crop size exceeds the image boundary size");
++ return -1;
++ }
++
+ break;
+ case EDGE_TOP: /* width from left, zones from top to bottom */
+ default:
+@@ -5632,6 +5659,15 @@ getCropOffsets(struct image_data *image,
+ else
+ crop->combined_length = (uint32)zlength;
+ crop->combined_width = (uint32)zwidth;
++
++ /* When the degrees clockwise rotation is 90 or 270, check the boundary */
++ if (((crop->rotation == 90) || (crop->rotation == 270))
++ && ((crop->combined_length > image->width) || (crop->combined_width > image->length)))
++ {
++ TIFFError("getCropOffsets", "The crop size exceeds the image boundary size");
++ return -1;
++ }
++
+ break;
+ } /* end switch statement */
+
+@@ -6827,9 +6863,9 @@ extractImageSection(struct image_data *i
+ * regardless of the way the data are organized in the input file.
+ * Furthermore, bytes and bits are arranged in buffer according to COMPRESSION=1 and FILLORDER=1
+ */
+- img_rowsize = (((img_width * spp * bps) + 7) / 8); /* row size in full bytes of source image */
+- full_bytes = (sect_width * spp * bps) / 8; /* number of COMPLETE bytes per row in section */
+- trailing_bits = (sect_width * spp * bps) % 8; /* trailing bits within the last byte of destination buffer */
++ img_rowsize = (((img_width * spp * bps) + 7) / 8); /* row size in full bytes of source image */
++ full_bytes = (sect_width * spp * bps) / 8; /* number of COMPLETE bytes per row in section */
++ trailing_bits = (sect_width * spp * bps) % 8; /* trailing bits within the last byte of destination buffer */
+
+ #ifdef DEVELMODE
+ TIFFError ("", "First row: %d, last row: %d, First col: %d, last col: %d\n",
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-25433.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-25433.patch
new file mode 100644
index 0000000000..7d6d40f25a
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-25433.patch
@@ -0,0 +1,173 @@
+From 9c22495e5eeeae9e00a1596720c969656bb8d678 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Fri, 3 Feb 2023 15:31:31 +0100
+Subject: [PATCH] tiffcrop correctly update buffersize after rotateImage()
+ fix#520 rotateImage() set up a new buffer and calculates its size
+ individually. Therefore, seg_buffs[] size needs to be updated accordingly.
+ Before this fix, the seg_buffs buffer size was calculated with a different
+ formula than within rotateImage().
+
+Closes #520.
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/9c22495e5eeeae9e00a1596720c969656bb8d678 && https://gitlab.com/libtiff/libtiff/-/commit/688012dca2c39033aa2dc7bcea9796787cfd1b44]
+CVE: CVE-2023-25433
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ tools/tiffcrop.c | 69 +++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 56 insertions(+), 13 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index 742615a..aab0ec6 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -531,7 +531,7 @@ static int rotateContigSamples24bits(uint16, uint16, uint16, uint32,
+ static int rotateContigSamples32bits(uint16, uint16, uint16, uint32,
+ uint32, uint32, uint8 *, uint8 *);
+ static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
+- unsigned char **, int);
++ unsigned char **, size_t *);
+ static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
+ unsigned char *);
+ static int invertImage(uint16, uint16, uint16, uint32, uint32,
+@@ -6384,7 +6384,7 @@ static int correct_orientation(struct image_data *image, unsigned char **work_b
+ * but switch xres, yres there. */
+ uint32_t width = image->width;
+ uint32_t length = image->length;
+- if (rotateImage(rotation, image, &width, &length, work_buff_ptr, TRUE))
++ if (rotateImage(rotation, image, &width, &length, work_buff_ptr, NULL))
+ {
+ TIFFError ("correct_orientation", "Unable to rotate image");
+ return (-1);
+@@ -7607,8 +7607,12 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+
+ if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
+ {
++ /* rotateImage() set up a new buffer and calculates its size
++ * individually. Therefore, seg_buffs size needs to be updated
++ * accordingly. */
++ size_t rot_buf_size = 0;
+ if (rotateImage(crop->rotation, image, &crop->combined_width,
+- &crop->combined_length, &crop_buff, FALSE))
++ &crop->combined_length, &crop_buff, &rot_buf_size))
+ {
+ TIFFError("processCropSelections",
+ "Failed to rotate composite regions by %d degrees", crop->rotation);
+@@ -7713,8 +7717,13 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+
+ if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
+ {
+- if (rotateImage(crop->rotation, image, &crop->regionlist[i].width,
+- &crop->regionlist[i].length, &crop_buff, FALSE))
++ /* Furthermore, rotateImage() set up a new buffer and calculates
++ * its size individually. Therefore, seg_buffs size needs to be
++ * updated accordingly. */
++ size_t rot_buf_size = 0;
++ if (rotateImage(
++ crop->rotation, image, &crop->regionlist[i].width,
++ &crop->regionlist[i].length, &crop_buff, &rot_buf_size))
+ {
+ TIFFError("processCropSelections",
+ "Failed to rotate crop region by %d degrees", crop->rotation);
+@@ -7725,8 +7734,7 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ crop->combined_width = total_width;
+ crop->combined_length = total_length;
+ seg_buffs[i].buffer = crop_buff;
+- seg_buffs[i].size = (((crop->regionlist[i].width * image->bps + 7 ) / 8)
+- * image->spp) * crop->regionlist[i].length;
++ seg_buffs[i].size = rot_buf_size;
+ }
+ }
+ }
+@@ -7735,7 +7743,6 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+
+ /* Copy the crop section of the data from the current image into a buffer
+ * and adjust the IFD values to reflect the new size. If no cropping is
+- * required, use the origial read buffer as the crop buffer.
+ *
+ * There is quite a bit of redundancy between this routine and the more
+ * specialized processCropSelections, but this provides
+@@ -7846,7 +7853,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop,
+ if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
+ {
+ if (rotateImage(crop->rotation, image, &crop->combined_width,
+- &crop->combined_length, crop_buff_ptr, TRUE))
++ &crop->combined_length, crop_buff_ptr, NULL))
+ {
+ TIFFError("createCroppedImage",
+ "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
+@@ -8515,7 +8522,8 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+ uint32 bytes_per_pixel, bytes_per_sample;
+ uint32 row, rowsize, src_offset, dst_offset;
+ uint32 i, col, width, length;
+- uint32 colsize, buffsize, col_offset, pix_offset;
++ uint32 colsize, col_offset, pix_offset;
++ tmsize_t buffsize;
+ unsigned char *ibuff;
+ unsigned char *src;
+ unsigned char *dst;
+@@ -8528,12 +8536,41 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+ spp = image->spp;
+ bps = image->bps;
+
++ if ((spp != 0 && bps != 0 &&
++ width > (uint32_t)((UINT32_MAX - 7) / spp / bps)) ||
++ (spp != 0 && bps != 0 &&
++ length > (uint32_t)((UINT32_MAX - 7) / spp / bps)))
++ {
++ TIFFError("rotateImage", "Integer overflow detected.");
++ return (-1);
++ }
++
+ rowsize = ((bps * spp * width) + 7) / 8;
+ colsize = ((bps * spp * length) + 7) / 8;
+ if ((colsize * width) > (rowsize * length))
+- buffsize = (colsize + 1) * width;
++{
++ if (((tmsize_t)colsize + 1) != 0 &&
++ (tmsize_t)width > ((TIFF_TMSIZE_T_MAX - NUM_BUFF_OVERSIZE_BYTES) /
++ ((tmsize_t)colsize + 1)))
++ {
++ TIFFError("rotateImage",
++ "Integer overflow when calculating buffer size.");
++ return (-1);
++ }
++ buffsize = ((tmsize_t)colsize + 1) * width;
++ }
+ else
+- buffsize = (rowsize + 1) * length;
++ {
++ if (((tmsize_t)rowsize + 1) != 0 &&
++ (tmsize_t)length > ((TIFF_TMSIZE_T_MAX - NUM_BUFF_OVERSIZE_BYTES) /
++ ((tmsize_t)rowsize + 1)))
++ {
++ TIFFError("rotateImage",
++ "Integer overflow when calculating buffer size.");
++ return (-1);
++ }
++ buffsize = (rowsize + 1) * length;
++ }
+
+ bytes_per_sample = (bps + 7) / 8;
+ bytes_per_pixel = ((bps * spp) + 7) / 8;
+@@ -8556,11 +8593,17 @@ rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+ /* Add 3 padding bytes for extractContigSamplesShifted32bits */
+ if (!(rbuff = (unsigned char *)_TIFFmalloc(buffsize + NUM_BUFF_OVERSIZE_BYTES)))
+ {
+- TIFFError("rotateImage", "Unable to allocate rotation buffer of %1u bytes", buffsize + NUM_BUFF_OVERSIZE_BYTES);
++ TIFFError("rotateImage",
++ "Unable to allocate rotation buffer of %" TIFF_SSIZE_FORMAT
++ " bytes ",
++ buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ return (-1);
+ }
+ _TIFFmemset(rbuff, '\0', buffsize + NUM_BUFF_OVERSIZE_BYTES);
+
++ if (rot_buf_size != NULL)
++ *rot_buf_size = buffsize;
++
+ ibuff = *ibuff_ptr;
+ switch (rotation)
+ {
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-25434-CVE-2023-25435.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-25434-CVE-2023-25435.patch
new file mode 100644
index 0000000000..6a6596f092
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-25434-CVE-2023-25435.patch
@@ -0,0 +1,94 @@
+From 69818e2f2d246e6631ac2a2da692c3706b849c38 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Sun, 29 Jan 2023 11:09:26 +0100
+Subject: [PATCH] tiffcrop: Amend rotateImage() not to toggle the input (main)
+ image width and length parameters when only cropped image sections are
+ rotated. Remove buffptr from region structure because never used.
+
+Closes #492 #493 #494 #495 #499 #518 #519
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/69818e2f2d246e6631ac2a2da692c3706b849c38]
+CVE: CVE-2023-25434 & CVE-2023-25435
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ tools/tiffcrop.c | 29 +++++++++++++++++------------
+ 1 file changed, 17 insertions(+), 12 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index aab0ec6..ce84414 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -531,7 +531,7 @@ static int rotateContigSamples24bits(uint16, uint16, uint16, uint32,
+ static int rotateContigSamples32bits(uint16, uint16, uint16, uint32,
+ uint32, uint32, uint8 *, uint8 *);
+ static int rotateImage(uint16, struct image_data *, uint32 *, uint32 *,
+- unsigned char **, size_t *);
++ unsigned char **, size_t *, int);
+ static int mirrorImage(uint16, uint16, uint16, uint32, uint32,
+ unsigned char *);
+ static int invertImage(uint16, uint16, uint16, uint32, uint32,
+@@ -6382,10 +6382,11 @@ static int correct_orientation(struct image_data *image, unsigned char **work_b
+ /* Dummy variable in order not to switch two times the
+ * image->width,->length within rotateImage(),
+ * but switch xres, yres there. */
+- uint32_t width = image->width;
+- uint32_t length = image->length;
+- if (rotateImage(rotation, image, &width, &length, work_buff_ptr, NULL))
+- {
++ uint32_t width = image->width;
++ uint32_t length = image->length;
++ if (rotateImage(rotation, image, &width, &length, work_buff_ptr, NULL,
++ TRUE))
++ {
+ TIFFError ("correct_orientation", "Unable to rotate image");
+ return (-1);
+ }
+@@ -7612,7 +7613,8 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ * accordingly. */
+ size_t rot_buf_size = 0;
+ if (rotateImage(crop->rotation, image, &crop->combined_width,
+- &crop->combined_length, &crop_buff, &rot_buf_size))
++ &crop->combined_length, &crop_buff, &rot_buf_size,
++ FALSE))
+ {
+ TIFFError("processCropSelections",
+ "Failed to rotate composite regions by %d degrees", crop->rotation);
+@@ -7721,9 +7723,10 @@ processCropSelections(struct image_data *image, struct crop_mask *crop,
+ * its size individually. Therefore, seg_buffs size needs to be
+ * updated accordingly. */
+ size_t rot_buf_size = 0;
+- if (rotateImage(
+- crop->rotation, image, &crop->regionlist[i].width,
+- &crop->regionlist[i].length, &crop_buff, &rot_buf_size))
++ if (rotateImage(crop->rotation, image,
++ &crop->regionlist[i].width,
++ &crop->regionlist[i].length, &crop_buff,
++ &rot_buf_size, FALSE))
+ {
+ TIFFError("processCropSelections",
+ "Failed to rotate crop region by %d degrees", crop->rotation);
+@@ -7853,7 +7856,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop,
+ if (crop->crop_mode & CROP_ROTATE) /* rotate should be last as it can reallocate the buffer */
+ {
+ if (rotateImage(crop->rotation, image, &crop->combined_width,
+- &crop->combined_length, crop_buff_ptr, NULL))
++ &crop->combined_length, crop_buff_ptr, NULL, TRUE))
+ {
+ TIFFError("createCroppedImage",
+ "Failed to rotate image or cropped selection by %d degrees", crop->rotation);
+@@ -8515,8 +8518,10 @@ rotateContigSamples32bits(uint16 rotation, uint16 spp, uint16 bps, uint32 width,
+
+ /* Rotate an image by a multiple of 90 degrees clockwise */
+ static int
+-rotateImage(uint16 rotation, struct image_data *image, uint32 *img_width,
+- uint32 *img_length, unsigned char **ibuff_ptr, int rot_image_params)
++rotateImage(uint16 rotation, struct image_data *image,
++ uint32 *img_width, uint32 *img_length,
++ unsigned char **ibuff_ptr, size_t *rot_buf_size,
++ int rot_image_params)
+ {
+ int shift_width;
+ uint32 bytes_per_pixel, bytes_per_sample;
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-26965.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-26965.patch
new file mode 100644
index 0000000000..b7a7e93764
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-26965.patch
@@ -0,0 +1,90 @@
+From ec8ef90c1f573c9eb1f17d6a056aa0015f184acf Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Tue, 14 Feb 2023 20:43:43 +0100
+Subject: [PATCH] tiffcrop: Do not reuse input buffer for subsequent images.
+ Fix issue 527
+
+Reuse of read_buff within loadImage() from previous image is quite unsafe, because other functions (like rotateImage() etc.) reallocate that buffer with different size without updating the local prev_readsize value.
+
+Closes #527
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u8.debian.tar.xz]
+CVE: CVE-2023-26965
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ tools/tiffcrop.c | 40 ++++++++++------------------------------
+ 1 file changed, 10 insertions(+), 30 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index ce84414..a533089 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -5935,9 +5935,7 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
+ uint32 tw = 0, tl = 0; /* Tile width and length */
+ tmsize_t tile_rowsize = 0;
+ unsigned char *read_buff = NULL;
+- unsigned char *new_buff = NULL;
+ int readunit = 0;
+- static tmsize_t prev_readsize = 0;
+
+ TIFFGetFieldDefaulted(in, TIFFTAG_BITSPERSAMPLE, &bps);
+ TIFFGetFieldDefaulted(in, TIFFTAG_SAMPLESPERPIXEL, &spp);
+@@ -6232,37 +6230,20 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
+ read_buff = *read_ptr;
+ /* +3 : add a few guard bytes since reverseSamples16bits() can read a bit */
+ /* outside buffer */
+- if (!read_buff)
++ if (read_buff)
+ {
+- if( buffsize > 0xFFFFFFFFU - 3 )
+- {
+- TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
+- return (-1);
+- }
+- read_buff = (unsigned char *)_TIFFmalloc(buffsize + NUM_BUFF_OVERSIZE_BYTES);
++ _TIFFfree(read_buff);
+ }
+- else
+- {
+- if (prev_readsize < buffsize)
+- {
+- if( buffsize > 0xFFFFFFFFU - 3 )
+- {
+- TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
+- return (-1);
+- }
+- new_buff = _TIFFrealloc(read_buff, buffsize + NUM_BUFF_OVERSIZE_BYTES);
+- if (!new_buff)
+- {
+- free (read_buff);
+- read_buff = (unsigned char *)_TIFFmalloc(buffsize + NUM_BUFF_OVERSIZE_BYTES);
+- }
+- else
+- read_buff = new_buff;
+- }
+- }
++ if (buffsize > 0xFFFFFFFFU - 3)
++ {
++ TIFFError("loadImage", "Required read buffer size too large");
++ return (-1);
++ }
++ read_buff =
++ (unsigned char *)_TIFFmalloc(buffsize + NUM_BUFF_OVERSIZE_BYTES);
+ if (!read_buff)
+ {
+- TIFFError("loadImage", "Unable to allocate/reallocate read buffer");
++ TIFFError("loadImage", "Unable to allocate read buffer");
+ return (-1);
+ }
+
+@@ -6270,7 +6251,6 @@ loadImage(TIFF* in, struct image_data *image, struct dump_opts *dump, unsigned c
+ read_buff[buffsize+1] = 0;
+ read_buff[buffsize+2] = 0;
+
+- prev_readsize = buffsize;
+ *read_ptr = read_buff;
+
+ /* N.B. The read functions used copy separate plane data into a buffer as interleaved
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-26966.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-26966.patch
new file mode 100644
index 0000000000..48657e6aa4
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-26966.patch
@@ -0,0 +1,35 @@
+From b0e1c25dd1d065200c8d8f59ad0afe014861a1b9 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Thu, 16 Feb 2023 12:03:16 +0100
+Subject: [PATCH] tif_luv: Check and correct for NaN data in uv_encode().
+
+Closes #530
+
+Upstream-Status: Backport [import from debian http://security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u8.debian.tar.xz]
+CVE: CVE-2023-26966
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ libtiff/tif_luv.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/libtiff/tif_luv.c b/libtiff/tif_luv.c
+index 6fe4858..8b2c5f1 100644
+--- a/libtiff/tif_luv.c
++++ b/libtiff/tif_luv.c
+@@ -923,6 +923,13 @@ uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
+ {
+ register int vi, ui;
+
++ /* check for NaN */
++ if (u != u || v != v)
++ {
++ u = U_NEU;
++ v = V_NEU;
++ }
++
+ if (v < UV_VSTART)
+ return oog_encode(u, v);
+ vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-2908.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-2908.patch
new file mode 100644
index 0000000000..62a5e1831c
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-2908.patch
@@ -0,0 +1,33 @@
+From 8c0859a80444c90b8dfb862a9f16de74e16f0a9e Mon Sep 17 00:00:00 2001
+From: xiaoxiaoafeifei <lliangliang2007@163.com>
+Date: Fri, 21 Apr 2023 13:01:34 +0000
+Subject: [PATCH] countInkNamesString(): fix `UndefinedBehaviorSanitizer`:
+ applying zero offset to null pointer
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/9bd48f0dbd64fb94dc2b5b05238fde0bfdd4ff3f]
+CVE: CVE-2023-2908
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ libtiff/tif_dir.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libtiff/tif_dir.c b/libtiff/tif_dir.c
+index 9d8267a..6389b40 100644
+--- a/libtiff/tif_dir.c
++++ b/libtiff/tif_dir.c
+@@ -145,10 +145,10 @@ static uint16
+ countInkNamesString(TIFF *tif, uint32 slen, const char *s)
+ {
+ uint16 i = 0;
+- const char *ep = s + slen;
+- const char *cp = s;
+
+ if (slen > 0) {
++ const char *ep = s + slen;
++ const char *cp = s;
+ do {
+ for (; cp < ep && *cp != '\0'; cp++) {}
+ if (cp >= ep)
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-3316.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-3316.patch
new file mode 100644
index 0000000000..8db24fc714
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-3316.patch
@@ -0,0 +1,59 @@
+From d63de61b1ec3385f6383ef9a1f453e4b8b11d536 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Fri, 3 Feb 2023 17:38:55 +0100
+Subject: [PATCH] TIFFClose() avoid NULL pointer dereferencing. fix#515
+
+Closes #515
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/d63de61b1ec3385f6383ef9a1f453e4b8b11d536]
+CVE: CVE-2023-3316
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ libtiff/tif_close.c | 11 +++++++----
+ tools/tiffcrop.c | 5 ++++-
+ 2 files changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/libtiff/tif_close.c b/libtiff/tif_close.c
+index e4228df..335e80f 100644
+--- a/libtiff/tif_close.c
++++ b/libtiff/tif_close.c
+@@ -118,13 +118,16 @@ TIFFCleanup(TIFF* tif)
+ */
+
+ void
+-TIFFClose(TIFF* tif)
++TIFFClose(TIFF *tif)
+ {
+- TIFFCloseProc closeproc = tif->tif_closeproc;
+- thandle_t fd = tif->tif_clientdata;
++ if (tif != NULL)
++ {
++ TIFFCloseProc closeproc = tif->tif_closeproc;
++ thandle_t fd = tif->tif_clientdata;
+
+ TIFFCleanup(tif);
+- (void) (*closeproc)(fd);
++ (void)(*closeproc)(fd);
++ }
+ }
+
+ /* vim: set ts=8 sts=8 sw=8 noet: */
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index a533089..f14bb0c 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -2526,7 +2526,10 @@ main(int argc, char* argv[])
+ }
+ }
+
+- TIFFClose(out);
++ if (out != NULL)
++ {
++ TIFFClose(out);
++ }
+
+ return (0);
+ } /* end main */
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-3576.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-3576.patch
new file mode 100644
index 0000000000..67837fe142
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-3576.patch
@@ -0,0 +1,35 @@
+From 881a070194783561fd209b7c789a4e75566f7f37 Mon Sep 17 00:00:00 2001
+From: zhailiangliang <zhailiangliang@loongson.cn>
+Date: Tue, 7 Mar 2023 15:02:08 +0800
+Subject: [PATCH] Fix memory leak in tiffcrop.c
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/881a070194783561fd209b7c789a4e75566f7f37]
+CVE: CVE-2023-3576
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ tools/tiffcrop.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index f14bb0c..7121c7c 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -7746,8 +7746,13 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop,
+
+ read_buff = *read_buff_ptr;
+
++ /* Memory is freed before crop_buff_ptr is overwritten */
++ if (*crop_buff_ptr != NULL)
++ {
++ _TIFFfree(*crop_buff_ptr);
++ }
++
+ /* process full image, no crop buffer needed */
+- crop_buff = read_buff;
+ *crop_buff_ptr = read_buff;
+ crop->combined_width = image->width;
+ crop->combined_length = image->length;
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-3618.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-3618.patch
new file mode 100644
index 0000000000..fd67305c0b
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-3618.patch
@@ -0,0 +1,47 @@
+From b5c7d4c4e03333ac16b5cfb11acaaeaa493334f8 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Fri, 5 May 2023 19:43:46 +0200
+Subject: [PATCH] Consider error return of writeSelections(). Fixes #553
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/b5c7d4c4e03333ac16b5cfb11acaaeaa493334f8]
+CVE: CVE-2023-3618
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ tools/tiffcrop.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
+index 7121c7c..93b7f96 100644
+--- a/tools/tiffcrop.c
++++ b/tools/tiffcrop.c
+@@ -2437,9 +2437,15 @@ main(int argc, char* argv[])
+ { /* Whole image or sections not based on output page size */
+ if (crop.selections > 0)
+ {
+- writeSelections(in, &out, &crop, &image, &dump, seg_buffs,
+- mp, argv[argc - 1], &next_page, total_pages);
+- }
++ if (writeSelections(in, &out, &crop, &image, &dump,
++ seg_buffs, mp, argv[argc - 1],
++ &next_page, total_pages))
++ {
++ TIFFError("main",
++ "Unable to write new image selections");
++ exit(EXIT_FAILURE);
++ }
++ }
+ else /* One file all images and sections */
+ {
+ if (update_output_file (&out, mp, crop.exp_mode, argv[argc - 1],
+@@ -7749,7 +7755,7 @@ createCroppedImage(struct image_data *image, struct crop_mask *crop,
+ /* Memory is freed before crop_buff_ptr is overwritten */
+ if (*crop_buff_ptr != NULL)
+ {
+- _TIFFfree(*crop_buff_ptr);
++ _TIFFfree(*crop_buff_ptr);
+ }
+
+ /* process full image, no crop buffer needed */
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-40745.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-40745.patch
new file mode 100644
index 0000000000..6eb286039f
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-40745.patch
@@ -0,0 +1,34 @@
+From 4fc16f649fa2875d5c388cf2edc295510a247ee5 Mon Sep 17 00:00:00 2001
+From: Arie Haenel <arie.haenel@jct.ac.il>
+Date: Wed, 19 Jul 2023 19:34:25 +0000
+Subject: [PATCH] tiffcp: fix memory corruption (overflow) on hostile images
+ (fixes #591)
+
+Upstream-Status: Backport from [https://gitlab.com/libtiff/libtiff/-/commit/4fc16f649fa2875d5c388cf2edc295510a247ee5]
+CVE: CVE-2023-40745
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+---
+ tools/tiffcp.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/tools/tiffcp.c b/tools/tiffcp.c
+index 83b3910..007bd05 100644
+--- a/tools/tiffcp.c
++++ b/tools/tiffcp.c
+@@ -1437,6 +1437,13 @@ DECLAREreadFunc(readSeparateTilesIntoBuffer)
+ TIFFError(TIFFFileName(in), "Error, cannot handle that much samples per tile row (Tile Width * Samples/Pixel)");
+ return 0;
+ }
++
++ if ( (imagew - tilew * spp) > INT_MAX ){
++ TIFFError(TIFFFileName(in),
++ "Error, image raster scan line size is too large");
++ return 0;
++ }
++
+ iskew = imagew - tilew*spp;
+ tilebuf = _TIFFmalloc(tilesize);
+ if (tilebuf == 0)
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-41175.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-41175.patch
new file mode 100644
index 0000000000..3f44a42012
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-41175.patch
@@ -0,0 +1,67 @@
+From 4cc97e3dfa6559f4d17af0d0687bcae07ca4b73d Mon Sep 17 00:00:00 2001
+From: Arie Haenel <arie.haenel@jct.ac.il>
+Date: Wed, 19 Jul 2023 19:40:01 +0000
+Subject: raw2tiff: fix integer overflow and bypass of the check (fixes #592)
+
+Upstream-Status: Backport [import from debian security.debian.org/debian-security/pool/updates/main/t/tiff/tiff_4.1.0+git191117-2~deb10u8.debian.tar.xz
+Upstream commit https://gitlab.com/libtiff/libtiff/-/commit/6e2dac5f904496d127c92ddc4e56eccfca25c2ee]
+CVE: CVE-2023-41175
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ tools/raw2tiff.c | 26 ++++++++++++++++++++++++++
+ 1 file changed, 26 insertions(+)
+
+diff --git a/tools/raw2tiff.c b/tools/raw2tiff.c
+index ab36ff4e..a905da52 100644
+--- a/tools/raw2tiff.c
++++ b/tools/raw2tiff.c
+@@ -35,6 +35,7 @@
+ #include <sys/types.h>
+ #include <math.h>
+ #include <ctype.h>
++#include <limits.h>
+
+ #ifdef HAVE_UNISTD_H
+ # include <unistd.h>
+@@ -101,6 +102,7 @@ main(int argc, char* argv[])
+ int fd;
+ char *outfilename = NULL;
+ TIFF *out;
++ uint32 temp_limit_check = 0;
+
+ uint32 row, col, band;
+ int c;
+@@ -212,6 +214,30 @@ main(int argc, char* argv[])
+ if (guessSize(fd, dtype, hdr_size, nbands, swab, &width, &length) < 0)
+ return 1;
+
++ if ((width == 0) || (length == 0) ){
++ fprintf(stderr, "Too large nbands value specified.\n");
++ return (EXIT_FAILURE);
++ }
++
++ temp_limit_check = nbands * depth;
++
++ if ( !temp_limit_check || length > ( UINT_MAX / temp_limit_check ) ) {
++ fprintf(stderr, "Too large length size specified.\n");
++ return (EXIT_FAILURE);
++ }
++ temp_limit_check = temp_limit_check * length;
++
++ if ( !temp_limit_check || width > ( UINT_MAX / temp_limit_check ) ) {
++ fprintf(stderr, "Too large width size specified.\n");
++ return (EXIT_FAILURE);
++ }
++ temp_limit_check = temp_limit_check * width;
++
++ if ( !temp_limit_check || hdr_size > ( UINT_MAX - temp_limit_check ) ) {
++ fprintf(stderr, "Too large header size specified.\n");
++ return (EXIT_FAILURE);
++ }
++
+ if (outfilename == NULL)
+ outfilename = argv[optind+1];
+ out = TIFFOpen(outfilename, "w");
+--
+2.30.2
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-52356.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-52356.patch
new file mode 100644
index 0000000000..1b651e6529
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-52356.patch
@@ -0,0 +1,53 @@
+[Ubuntu note: Backport of the following patch from upstream, with a few changes
+to match the current version of the file in the present Ubuntu release:
+ . using TIFFErrorExt instead of TIFFErrorExtR (the latter did not exist yet);
+-- Rodrigo Figueiredo Zaiden]
+
+Backport of:
+
+From 51558511bdbbcffdce534db21dbaf5d54b31638a Mon Sep 17 00:00:00 2001
+From: Even Rouault <even.rouault@spatialys.com>
+Date: Tue, 31 Oct 2023 15:58:41 +0100
+Subject: [PATCH] TIFFReadRGBAStrip/TIFFReadRGBATile: add more validation of
+ col/row (fixes #622)
+
+Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/tiff/tree/debian/patches/CVE-2023-52356.patch?h=ubuntu/focal-security
+Upstream commit https://gitlab.com/libtiff/libtiff/-/commit/51558511bdbbcffdce534db21dbaf5d54b31638a]
+CVE: CVE-2023-52356
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ libtiff/tif_getimage.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+
+--- tiff-4.1.0+git191117.orig/libtiff/tif_getimage.c
++++ tiff-4.1.0+git191117/libtiff/tif_getimage.c
+@@ -2926,6 +2926,13 @@ TIFFReadRGBAStripExt(TIFF* tif, uint32 r
+ }
+
+ if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
++ if (row >= img.height)
++ {
++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
++ "Invalid row passed to TIFFReadRGBAStrip().");
++ TIFFRGBAImageEnd(&img);
++ return (0);
++ }
+
+ img.row_offset = row;
+ img.col_offset = 0;
+@@ -3002,6 +3009,14 @@ TIFFReadRGBATileExt(TIFF* tif, uint32 co
+ return( 0 );
+ }
+
++ if (col >= img.width || row >= img.height)
++ {
++ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
++ "Invalid row/col passed to TIFFReadRGBATile().");
++ TIFFRGBAImageEnd(&img);
++ return (0);
++ }
++
+ /*
+ * The TIFFRGBAImageGet() function doesn't allow us to get off the
+ * edge of the image, even to fill an otherwise valid tile. So we
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-6228.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-6228.patch
new file mode 100644
index 0000000000..a777dea9b0
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-6228.patch
@@ -0,0 +1,30 @@
+From 1e7d217a323eac701b134afc4ae39b6bdfdbc96a Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Sat, 9 Sep 2023 15:45:47 +0200
+Subject: [PATCH] Check also if codec of input image is available,
+ independently from codec check of output image and return with error if not.
+ Fixes #606.
+
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/1e7d217a323eac701b134afc4ae39b6bdfdbc96a]
+CVE: CVE-2023-6228
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ tools/tiffcp.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/tiffcp.c b/tools/tiffcp.c
+index 007bd05..d2f7b66 100644
+--- a/tools/tiffcp.c
++++ b/tools/tiffcp.c
+@@ -628,6 +628,8 @@ tiffcp(TIFF* in, TIFF* out)
+ else
+ CopyField(TIFFTAG_COMPRESSION, compression);
+ TIFFGetFieldDefaulted(in, TIFFTAG_COMPRESSION, &input_compression);
++ if (!TIFFIsCODECConfigured(input_compression))
++ return FALSE;
+ TIFFGetFieldDefaulted(in, TIFFTAG_PHOTOMETRIC, &input_photometric);
+ if (input_compression == COMPRESSION_JPEG) {
+ /* Force conversion to RGB */
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-1.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-1.patch
new file mode 100644
index 0000000000..e955b3f2e4
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-1.patch
@@ -0,0 +1,191 @@
+[Ubuntu note: Backport of the following patch from upstream, with a few changes
+to match the current version of the file in the present Ubuntu release:
+ . included inttypes.h header to support PRIu32 and PRIu64;
+ . using TIFFWarningExt instead of TIFFWarningExtR (the latter did not exist yet);
+ . using uint64 instead of uint64_t to preserve the current code usage;
+ . calling _TIFFfree(data) instead of _TIFFfreeExt(tif, data) (the latter did not exist yet);
+ . calls to the check size, that is the idea of the patch, were added before
+ _TIFFCheckMalloc and may note match the original patch methods;
+-- Rodrigo Figueiredo Zaiden]
+
+Backport of:
+
+From 5320c9d89c054fa805d037d84c57da874470b01a Mon Sep 17 00:00:00 2001
+From: Su Laus <sulau@freenet.de>
+Date: Tue, 31 Oct 2023 15:43:29 +0000
+Subject: [PATCH] Prevent some out-of-memory attacks
+
+Some small fuzzer files fake large amounts of data and provoke out-of-memory situations. For non-compressed data content / tags, out-of-memory can be prevented by comparing with the file size.
+
+At image reading, data size of some tags / data structures (StripByteCounts, StripOffsets, StripArray, TIFF directory) is compared with file size to prevent provoked out-of-memory attacks.
+
+See issue https://gitlab.com/libtiff/libtiff/-/issues/614#note_1602683857
+
+Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/tiff/tree/debian/patches/CVE-2023-6277-1.patch?h=ubuntu/focal-security
+Upstream commit https://gitlab.com/libtiff/libtiff/-/commit/5320c9d89c054fa805d037d84c57da874470b01a]
+CVE: CVE-2023-6277
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ libtiff/tif_dirread.c | 92 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 90 insertions(+), 2 deletions(-)
+
+--- tiff-4.1.0+git191117.orig/libtiff/tif_dirread.c
++++ tiff-4.1.0+git191117/libtiff/tif_dirread.c
+@@ -37,6 +37,7 @@
+ #include "tiffiop.h"
+ #include <float.h>
+ #include <stdlib.h>
++#include <inttypes.h>
+
+ #define FAILED_FII ((uint32) -1)
+
+@@ -863,6 +864,21 @@ static enum TIFFReadDirEntryErr TIFFRead
+ datasize=(*count)*typesize;
+ assert((tmsize_t)datasize>0);
+
++ /* Before allocating a huge amount of memory for corrupted files, check if
++ * size of requested memory is not greater than file size.
++ */
++ uint64 filesize = TIFFGetFileSize(tif);
++ if (datasize > filesize)
++ {
++ TIFFWarningExt(tif->tif_clientdata, "ReadDirEntryArray",
++ "Requested memory size for tag %d (0x%x) %" PRIu32
++ " is greather than filesize %" PRIu64
++ ". Memory not allocated, tag not read",
++ direntry->tdir_tag, direntry->tdir_tag, datasize,
++ filesize);
++ return (TIFFReadDirEntryErrAlloc);
++ }
++
+ if( isMapped(tif) && datasize > (uint32)tif->tif_size )
+ return TIFFReadDirEntryErrIo;
+
+@@ -4534,6 +4550,20 @@ EstimateStripByteCounts(TIFF* tif, TIFFD
+ if( !_TIFFFillStrilesInternal( tif, 0 ) )
+ return -1;
+
++ /* Before allocating a huge amount of memory for corrupted files, check if
++ * size of requested memory is not greater than file size. */
++ uint64 filesize = TIFFGetFileSize(tif);
++ uint64 allocsize = (uint64)td->td_nstrips * sizeof(uint64);
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(tif->tif_clientdata, module,
++ "Requested memory size for StripByteCounts of %" PRIu64
++ " is greather than filesize %" PRIu64
++ ". Memory not allocated",
++ allocsize, filesize);
++ return -1;
++ }
++
+ if (td->td_stripbytecount_p)
+ _TIFFfree(td->td_stripbytecount_p);
+ td->td_stripbytecount_p = (uint64*)
+@@ -4544,9 +4574,7 @@ EstimateStripByteCounts(TIFF* tif, TIFFD
+
+ if (td->td_compression != COMPRESSION_NONE) {
+ uint64 space;
+- uint64 filesize;
+ uint16 n;
+- filesize = TIFFGetFileSize(tif);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ space=sizeof(TIFFHeaderClassic)+2+dircount*12+4;
+ else
+@@ -4854,6 +4882,20 @@ TIFFFetchDirectory(TIFF* tif, uint64 dir
+ dircount16 = (uint16)dircount64;
+ dirsize = 20;
+ }
++ /* Before allocating a huge amount of memory for corrupted files, check
++ * if size of requested memory is not greater than file size. */
++ uint64 filesize = TIFFGetFileSize(tif);
++ uint64 allocsize = (uint64)dircount16 * dirsize;
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(
++ tif->tif_clientdata, module,
++ "Requested memory size for TIFF directory of %" PRIu64
++ " is greather than filesize %" PRIu64
++ ". Memory not allocated, TIFF directory not read",
++ allocsize, filesize);
++ return 0;
++ }
+ origdir = _TIFFCheckMalloc(tif, dircount16,
+ dirsize, "to read TIFF directory");
+ if (origdir == NULL)
+@@ -4957,6 +4999,20 @@ TIFFFetchDirectory(TIFF* tif, uint64 dir
+ "Sanity check on directory count failed, zero tag directories not supported");
+ return 0;
+ }
++ /* Before allocating a huge amount of memory for corrupted files, check
++ * if size of requested memory is not greater than file size. */
++ uint64 filesize = TIFFGetFileSize(tif);
++ uint64 allocsize = (uint64)dircount16 * dirsize;
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(
++ tif->tif_clientdata, module,
++ "Requested memory size for TIFF directory of %" PRIu64
++ " is greather than filesize %" PRIu64
++ ". Memory not allocated, TIFF directory not read",
++ allocsize, filesize);
++ return 0;
++ }
+ origdir = _TIFFCheckMalloc(tif, dircount16,
+ dirsize,
+ "to read TIFF directory");
+@@ -5000,6 +5056,8 @@ TIFFFetchDirectory(TIFF* tif, uint64 dir
+ }
+ }
+ }
++ /* No check against filesize needed here because "dir" should have same size
++ * than "origdir" checked above. */
+ dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16,
+ sizeof(TIFFDirEntry),
+ "to read TIFF directory");
+@@ -5769,7 +5827,20 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEn
+ _TIFFfree(data);
+ return(0);
+ }
+-
++ /* Before allocating a huge amount of memory for corrupted files, check
++ * if size of requested memory is not greater than file size. */
++ uint64 filesize = TIFFGetFileSize(tif);
++ uint64 allocsize = (uint64)nstrips * sizeof(uint64);
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(tif->tif_clientdata, module,
++ "Requested memory size for StripArray of %" PRIu64
++ " is greather than filesize %" PRIu64
++ ". Memory not allocated",
++ allocsize, filesize);
++ _TIFFfree(data);
++ return (0);
++ }
+ resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
+ if (resizeddata==0) {
+ _TIFFfree(data);
+@@ -5865,6 +5936,23 @@ static void allocChoppedUpStripArrays(TI
+ }
+ bytecount = last_offset + last_bytecount - offset;
+
++ /* Before allocating a huge amount of memory for corrupted files, check if
++ * size of StripByteCount and StripOffset tags is not greater than
++ * file size.
++ */
++ uint64 allocsize = (uint64)nstrips * sizeof(uint64) * 2;
++ uint64 filesize = TIFFGetFileSize(tif);
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(tif->tif_clientdata, "allocChoppedUpStripArrays",
++ "Requested memory size for StripByteCount and "
++ "StripOffsets %" PRIu64
++ " is greather than filesize %" PRIu64
++ ". Memory not allocated",
++ allocsize, filesize);
++ return;
++ }
++
+ newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
+ "for chopped \"StripByteCounts\" array");
+ newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-2.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-2.patch
new file mode 100644
index 0000000000..644b3fdb3f
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-2.patch
@@ -0,0 +1,152 @@
+[Ubuntu note: Backport of the following patch from upstream, with a few changes
+to match the current version of the file in the present Ubuntu release:
+ . using TIFFWarningExt instead of TIFFWarningExtR (the latter did not exist yet);
+ . using uint64 instead of uint64_t to preserve the current code usage;
+-- Rodrigo Figueiredo Zaiden]
+
+Backport of:
+
+From 0b025324711213a75e38b52f7e7ba60235f108aa Mon Sep 17 00:00:00 2001
+From: Even Rouault <even.rouault@spatialys.com>
+Date: Tue, 31 Oct 2023 19:47:22 +0100
+Subject: [PATCH] tif_dirread.c: only issue TIFFGetFileSize() for large enough
+ RAM requests
+
+Ammends 5320c9d89c054fa805d037d84c57da874470b01a
+
+This fixes a performance regression caught by the GDAL regression test
+suite.
+
+Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/tiff/tree/debian/patches/CVE-2023-6277-2.patch?h=ubuntu/focal-security
+Upstream commit https://gitlab.com/libtiff/libtiff/-/commit/0b025324711213a75e38b52f7e7ba60235f108aa]
+CVE: CVE-2023-6277
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ libtiff/tif_dirread.c | 83 +++++++++++++++++++++++++------------------
+ 1 file changed, 48 insertions(+), 35 deletions(-)
+
+--- tiff-4.1.0+git191117.orig/libtiff/tif_dirread.c
++++ tiff-4.1.0+git191117/libtiff/tif_dirread.c
+@@ -864,19 +864,22 @@ static enum TIFFReadDirEntryErr TIFFRead
+ datasize=(*count)*typesize;
+ assert((tmsize_t)datasize>0);
+
+- /* Before allocating a huge amount of memory for corrupted files, check if
+- * size of requested memory is not greater than file size.
+- */
+- uint64 filesize = TIFFGetFileSize(tif);
+- if (datasize > filesize)
++ if (datasize > 100 * 1024 * 1024)
+ {
+- TIFFWarningExt(tif->tif_clientdata, "ReadDirEntryArray",
+- "Requested memory size for tag %d (0x%x) %" PRIu32
+- " is greather than filesize %" PRIu64
+- ". Memory not allocated, tag not read",
+- direntry->tdir_tag, direntry->tdir_tag, datasize,
+- filesize);
+- return (TIFFReadDirEntryErrAlloc);
++ /* Before allocating a huge amount of memory for corrupted files, check
++ * if size of requested memory is not greater than file size.
++ */
++ const uint64 filesize = TIFFGetFileSize(tif);
++ if (datasize > filesize)
++ {
++ TIFFWarningExt(tif->tif_clientdata, "ReadDirEntryArray",
++ "Requested memory size for tag %d (0x%x) %" PRIu32
++ " is greater than filesize %" PRIu64
++ ". Memory not allocated, tag not read",
++ direntry->tdir_tag, direntry->tdir_tag, datasize,
++ filesize);
++ return (TIFFReadDirEntryErrAlloc);
++ }
+ }
+
+ if( isMapped(tif) && datasize > (uint32)tif->tif_size )
+@@ -4550,18 +4553,22 @@ EstimateStripByteCounts(TIFF* tif, TIFFD
+ if( !_TIFFFillStrilesInternal( tif, 0 ) )
+ return -1;
+
+- /* Before allocating a huge amount of memory for corrupted files, check if
+- * size of requested memory is not greater than file size. */
+- uint64 filesize = TIFFGetFileSize(tif);
+- uint64 allocsize = (uint64)td->td_nstrips * sizeof(uint64);
+- if (allocsize > filesize)
++ const uint64 allocsize = (uint64)td->td_nstrips * sizeof(uint64);
++ uint64 filesize = 0;
++ if (allocsize > 100 * 1024 * 1024)
+ {
+- TIFFWarningExt(tif->tif_clientdata, module,
+- "Requested memory size for StripByteCounts of %" PRIu64
+- " is greather than filesize %" PRIu64
+- ". Memory not allocated",
+- allocsize, filesize);
+- return -1;
++ /* Before allocating a huge amount of memory for corrupted files, check
++ * if size of requested memory is not greater than file size. */
++ filesize = TIFFGetFileSize(tif);
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(
++ tif->tif_clientdata, module,
++ "Requested memory size for StripByteCounts of %" PRIu64
++ " is greater than filesize %" PRIu64 ". Memory not allocated",
++ allocsize, filesize);
++ return -1;
++ }
+ }
+
+ if (td->td_stripbytecount_p)
+@@ -4608,11 +4615,13 @@ EstimateStripByteCounts(TIFF* tif, TIFFD
+ return -1;
+ space+=datasize;
+ }
++ if (filesize == 0)
++ filesize = TIFFGetFileSize(tif);
+ if( filesize < space )
+- /* we should perhaps return in error ? */
+- space = filesize;
+- else
+- space = filesize - space;
++ /* we should perhaps return in error ? */
++ space = filesize;
++ else
++ space = filesize - space;
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ space /= td->td_samplesperpixel;
+ for (strip = 0; strip < td->td_nstrips; strip++)
+@@ -4882,19 +4891,23 @@ TIFFFetchDirectory(TIFF* tif, uint64 dir
+ dircount16 = (uint16)dircount64;
+ dirsize = 20;
+ }
+- /* Before allocating a huge amount of memory for corrupted files, check
+- * if size of requested memory is not greater than file size. */
+- uint64 filesize = TIFFGetFileSize(tif);
+- uint64 allocsize = (uint64)dircount16 * dirsize;
+- if (allocsize > filesize)
++ const uint64 allocsize = (uint64)dircount16 * dirsize;
++ if (allocsize > 100 * 1024 * 1024)
+ {
+- TIFFWarningExt(
+- tif->tif_clientdata, module,
+- "Requested memory size for TIFF directory of %" PRIu64
+- " is greather than filesize %" PRIu64
+- ". Memory not allocated, TIFF directory not read",
+- allocsize, filesize);
+- return 0;
++ /* Before allocating a huge amount of memory for corrupted files,
++ * check if size of requested memory is not greater than file size.
++ */
++ const uint64 filesize = TIFFGetFileSize(tif);
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(
++ tif->tif_clientdata, module,
++ "Requested memory size for TIFF directory of %" PRIu64
++ " is greater than filesize %" PRIu64
++ ". Memory not allocated, TIFF directory not read",
++ allocsize, filesize);
++ return 0;
++ }
+ }
+ origdir = _TIFFCheckMalloc(tif, dircount16,
+ dirsize, "to read TIFF directory");
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-3.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-3.patch
new file mode 100644
index 0000000000..ed7d7e7b96
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-3.patch
@@ -0,0 +1,46 @@
+Backport of:
+
+From de7bfd7d4377c266f81849579f696fa1ad5ba6c3 Mon Sep 17 00:00:00 2001
+From: Even Rouault <even.rouault@spatialys.com>
+Date: Tue, 31 Oct 2023 20:13:45 +0100
+Subject: [PATCH] TIFFFetchDirectory(): remove useless allocsize vs filesize
+ check
+
+CoverityScan rightly points that the max value for dircount16 * dirsize
+is 4096 * 20. That's small enough not to do any check
+
+Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/tiff/tree/debian/patches/CVE-2023-6277-3.patch?h=ubuntu/focal-security
+Upstream commit https://gitlab.com/libtiff/libtiff/-/commit/de7bfd7d4377c266f81849579f696fa1ad5ba6c3]
+CVE: CVE-2023-6277
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ libtiff/tif_dirread.c | 18 ------------------
+ 1 file changed, 18 deletions(-)
+
+--- tiff-4.1.0+git191117.orig/libtiff/tif_dirread.c
++++ tiff-4.1.0+git191117/libtiff/tif_dirread.c
+@@ -4891,24 +4891,6 @@ TIFFFetchDirectory(TIFF* tif, uint64 dir
+ dircount16 = (uint16)dircount64;
+ dirsize = 20;
+ }
+- const uint64 allocsize = (uint64)dircount16 * dirsize;
+- if (allocsize > 100 * 1024 * 1024)
+- {
+- /* Before allocating a huge amount of memory for corrupted files,
+- * check if size of requested memory is not greater than file size.
+- */
+- const uint64 filesize = TIFFGetFileSize(tif);
+- if (allocsize > filesize)
+- {
+- TIFFWarningExt(
+- tif->tif_clientdata, module,
+- "Requested memory size for TIFF directory of %" PRIu64
+- " is greater than filesize %" PRIu64
+- ". Memory not allocated, TIFF directory not read",
+- allocsize, filesize);
+- return 0;
+- }
+- }
+ origdir = _TIFFCheckMalloc(tif, dircount16,
+ dirsize, "to read TIFF directory");
+ if (origdir == NULL)
diff --git a/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-4.patch b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-4.patch
new file mode 100644
index 0000000000..1a43fd3230
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/files/CVE-2023-6277-4.patch
@@ -0,0 +1,94 @@
+[Ubuntu note: Backport of the following patch from upstream, with a few changes
+to match the current version of the file in the present Ubuntu release:
+ . using TIFFWarningExt instead of TIFFWarningExtR (the latter did not exist yet);
+ . using uint64 instead of uint64_t to preserve the current code usage;
+ . calling _TIFFfree(data) instead of _TIFFfreeExt(tif, data) (the latter did not exist yet);
+-- Rodrigo Figueiredo Zaiden]
+
+Backport of:
+
+From dbb825a8312f30e63a06c272010967d51af5c35a Mon Sep 17 00:00:00 2001
+From: Even Rouault <even.rouault@spatialys.com>
+Date: Tue, 31 Oct 2023 21:30:58 +0100
+Subject: [PATCH] tif_dirread.c: only issue TIFFGetFileSize() for large enough
+ RAM requests
+
+Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/tiff/tree/debian/patches/CVE-2023-6277-4.patch?h=ubuntu/focal-security
+Upstream commit https://gitlab.com/libtiff/libtiff/-/commit/dbb825a8312f30e63a06c272010967d51af5c35a]
+CVE: CVE-2023-6277
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ libtiff/tif_dirread.c | 54 +++++++++++++++++++++++++------------------
+ 1 file changed, 31 insertions(+), 23 deletions(-)
+
+--- tiff-4.1.0+git191117.orig/libtiff/tif_dirread.c
++++ tiff-4.1.0+git191117/libtiff/tif_dirread.c
+@@ -5822,19 +5822,24 @@ TIFFFetchStripThing(TIFF* tif, TIFFDirEn
+ _TIFFfree(data);
+ return(0);
+ }
+- /* Before allocating a huge amount of memory for corrupted files, check
+- * if size of requested memory is not greater than file size. */
+- uint64 filesize = TIFFGetFileSize(tif);
+- uint64 allocsize = (uint64)nstrips * sizeof(uint64);
+- if (allocsize > filesize)
++ const uint64 allocsize = (uint64)nstrips * sizeof(uint64);
++ if (allocsize > 100 * 1024 * 1024)
+ {
+- TIFFWarningExt(tif->tif_clientdata, module,
+- "Requested memory size for StripArray of %" PRIu64
+- " is greather than filesize %" PRIu64
+- ". Memory not allocated",
+- allocsize, filesize);
+- _TIFFfree(data);
+- return (0);
++ /* Before allocating a huge amount of memory for corrupted files,
++ * check if size of requested memory is not greater than file size.
++ */
++ const uint64 filesize = TIFFGetFileSize(tif);
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(
++ tif->tif_clientdata, module,
++ "Requested memory size for StripArray of %" PRIu64
++ " is greater than filesize %" PRIu64
++ ". Memory not allocated",
++ allocsize, filesize);
++ _TIFFfree(data);
++ return (0);
++ }
+ }
+ resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
+ if (resizeddata==0) {
+@@ -5935,17 +5940,20 @@ static void allocChoppedUpStripArrays(TI
+ * size of StripByteCount and StripOffset tags is not greater than
+ * file size.
+ */
+- uint64 allocsize = (uint64)nstrips * sizeof(uint64) * 2;
+- uint64 filesize = TIFFGetFileSize(tif);
+- if (allocsize > filesize)
+- {
+- TIFFWarningExt(tif->tif_clientdata, "allocChoppedUpStripArrays",
+- "Requested memory size for StripByteCount and "
+- "StripOffsets %" PRIu64
+- " is greather than filesize %" PRIu64
+- ". Memory not allocated",
+- allocsize, filesize);
+- return;
++ const uint64 allocsize = (uint64)nstrips * sizeof(uint64) * 2;
++ if (allocsize > 100 * 1024 * 1024)
++ {
++ const uint64 filesize = TIFFGetFileSize(tif);
++ if (allocsize > filesize)
++ {
++ TIFFWarningExt(tif->tif_clientdata, "allocChoppedUpStripArrays",
++ "Requested memory size for StripByteCount and "
++ "StripOffsets %" PRIu64
++ " is greater than filesize %" PRIu64
++ ". Memory not allocated",
++ allocsize, filesize);
++ return;
++ }
+ }
+
+ newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
diff --git a/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch b/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch
new file mode 100644
index 0000000000..71b85cac10
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1354.patch
@@ -0,0 +1,212 @@
+From 87881e093691a35c60b91cafed058ba2dd5d9807 Mon Sep 17 00:00:00 2001
+From: Even Rouault <even.rouault@spatialys.com>
+Date: Sun, 5 Dec 2021 14:37:46 +0100
+Subject: [PATCH] TIFFReadDirectory: fix OJPEG hack (fixes #319)
+
+to avoid having the size of the strip arrays inconsistent with the
+number of strips returned by TIFFNumberOfStrips(), which may cause
+out-ouf-bounds array read afterwards.
+
+One of the OJPEG hack that alters SamplesPerPixel may influence the
+number of strips. Hence compute tif_dir.td_nstrips only afterwards.
+
+CVE: CVE-2022-1354
+
+Upstream-Status: Backport
+[https://gitlab.com/libtiff/libtiff/-/commit/87f580f39011109b3bb5f6eca13fac543a542798]
+
+Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
+---
+ libtiff/tif_dirread.c | 162 ++++++++++++++++++++++--------------------
+ 1 file changed, 83 insertions(+), 79 deletions(-)
+
+diff --git a/libtiff/tif_dirread.c b/libtiff/tif_dirread.c
+index 8f434ef5..14c031d1 100644
+--- a/libtiff/tif_dirread.c
++++ b/libtiff/tif_dirread.c
+@@ -3794,50 +3794,7 @@ TIFFReadDirectory(TIFF* tif)
+ MissingRequired(tif,"ImageLength");
+ goto bad;
+ }
+- /*
+- * Setup appropriate structures (by strip or by tile)
+- */
+- if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
+- tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
+- tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
+- tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
+- tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
+- tif->tif_flags &= ~TIFF_ISTILED;
+- } else {
+- tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
+- tif->tif_flags |= TIFF_ISTILED;
+- }
+- if (!tif->tif_dir.td_nstrips) {
+- TIFFErrorExt(tif->tif_clientdata, module,
+- "Cannot handle zero number of %s",
+- isTiled(tif) ? "tiles" : "strips");
+- goto bad;
+- }
+- tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
+- if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
+- tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
+- if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
+-#ifdef OJPEG_SUPPORT
+- if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
+- (isTiled(tif)==0) &&
+- (tif->tif_dir.td_nstrips==1)) {
+- /*
+- * XXX: OJPEG hack.
+- * If a) compression is OJPEG, b) it's not a tiled TIFF,
+- * and c) the number of strips is 1,
+- * then we tolerate the absence of stripoffsets tag,
+- * because, presumably, all required data is in the
+- * JpegInterchangeFormat stream.
+- */
+- TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
+- } else
+-#endif
+- {
+- MissingRequired(tif,
+- isTiled(tif) ? "TileOffsets" : "StripOffsets");
+- goto bad;
+- }
+- }
++
+ /*
+ * Second pass: extract other information.
+ */
+@@ -4042,41 +3999,6 @@ TIFFReadDirectory(TIFF* tif)
+ } /* -- if (!dp->tdir_ignore) */
+ } /* -- for-loop -- */
+
+- if( tif->tif_mode == O_RDWR &&
+- tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
+- tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
+- tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
+- tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
+- tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
+- {
+- /* Directory typically created with TIFFDeferStrileArrayWriting() */
+- TIFFSetupStrips(tif);
+- }
+- else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
+- {
+- if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
+- {
+- if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
+- tif->tif_dir.td_nstrips,
+- &tif->tif_dir.td_stripoffset_p))
+- {
+- goto bad;
+- }
+- }
+- if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
+- {
+- if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
+- tif->tif_dir.td_nstrips,
+- &tif->tif_dir.td_stripbytecount_p))
+- {
+- goto bad;
+- }
+- }
+- }
+-
+ /*
+ * OJPEG hack:
+ * - If a) compression is OJPEG, and b) photometric tag is missing,
+@@ -4147,6 +4069,88 @@ TIFFReadDirectory(TIFF* tif)
+ }
+ }
+
++ /*
++ * Setup appropriate structures (by strip or by tile)
++ * We do that only after the above OJPEG hack which alters SamplesPerPixel
++ * and thus influences the number of strips in the separate planarconfig.
++ */
++ if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
++ tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
++ tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
++ tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
++ tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
++ tif->tif_flags &= ~TIFF_ISTILED;
++ } else {
++ tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
++ tif->tif_flags |= TIFF_ISTILED;
++ }
++ if (!tif->tif_dir.td_nstrips) {
++ TIFFErrorExt(tif->tif_clientdata, module,
++ "Cannot handle zero number of %s",
++ isTiled(tif) ? "tiles" : "strips");
++ goto bad;
++ }
++ tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
++ if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
++ tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
++ if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
++#ifdef OJPEG_SUPPORT
++ if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
++ (isTiled(tif)==0) &&
++ (tif->tif_dir.td_nstrips==1)) {
++ /*
++ * XXX: OJPEG hack.
++ * If a) compression is OJPEG, b) it's not a tiled TIFF,
++ * and c) the number of strips is 1,
++ * then we tolerate the absence of stripoffsets tag,
++ * because, presumably, all required data is in the
++ * JpegInterchangeFormat stream.
++ */
++ TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
++ } else
++#endif
++ {
++ MissingRequired(tif,
++ isTiled(tif) ? "TileOffsets" : "StripOffsets");
++ goto bad;
++ }
++ }
++
++ if( tif->tif_mode == O_RDWR &&
++ tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
++ tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
++ tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
++ tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
++ tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
++ {
++ /* Directory typically created with TIFFDeferStrileArrayWriting() */
++ TIFFSetupStrips(tif);
++ }
++ else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
++ {
++ if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
++ {
++ if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
++ tif->tif_dir.td_nstrips,
++ &tif->tif_dir.td_stripoffset_p))
++ {
++ goto bad;
++ }
++ }
++ if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
++ {
++ if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
++ tif->tif_dir.td_nstrips,
++ &tif->tif_dir.td_stripbytecount_p))
++ {
++ goto bad;
++ }
++ }
++ }
++
+ /*
+ * Make sure all non-color channels are extrasamples.
+ * If it's not the case, define them as such.
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1355.patch b/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1355.patch
new file mode 100644
index 0000000000..e59f5aad55
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/tiff/CVE-2022-1355.patch
@@ -0,0 +1,62 @@
+From fb1db384959698edd6caeea84e28253d272a0f96 Mon Sep 17 00:00:00 2001
+From: Su_Laus <sulau@freenet.de>
+Date: Sat, 2 Apr 2022 22:33:31 +0200
+Subject: [PATCH] tiffcp: avoid buffer overflow in "mode" string (fixes #400)
+
+CVE: CVE-2022-1355
+
+Upstream-Status: Backport
+[https://gitlab.com/libtiff/libtiff/-/commit/c1ae29f9ebacd29b7c3e0c7db671af7db3584bc2]
+
+Signed-off-by: Yi Zhao <yi.zhao@windriver.com>
+---
+ tools/tiffcp.c | 25 ++++++++++++++++++++-----
+ 1 file changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/tools/tiffcp.c b/tools/tiffcp.c
+index fd129bb7..8d944ff6 100644
+--- a/tools/tiffcp.c
++++ b/tools/tiffcp.c
+@@ -274,19 +274,34 @@ main(int argc, char* argv[])
+ deftilewidth = atoi(optarg);
+ break;
+ case 'B':
+- *mp++ = 'b'; *mp = '\0';
++ if (strlen(mode) < (sizeof(mode) - 1))
++ {
++ *mp++ = 'b'; *mp = '\0';
++ }
+ break;
+ case 'L':
+- *mp++ = 'l'; *mp = '\0';
++ if (strlen(mode) < (sizeof(mode) - 1))
++ {
++ *mp++ = 'l'; *mp = '\0';
++ }
+ break;
+ case 'M':
+- *mp++ = 'm'; *mp = '\0';
++ if (strlen(mode) < (sizeof(mode) - 1))
++ {
++ *mp++ = 'm'; *mp = '\0';
++ }
+ break;
+ case 'C':
+- *mp++ = 'c'; *mp = '\0';
++ if (strlen(mode) < (sizeof(mode) - 1))
++ {
++ *mp++ = 'c'; *mp = '\0';
++ }
+ break;
+ case '8':
+- *mp++ = '8'; *mp = '\0';
++ if (strlen(mode) < (sizeof(mode)-1))
++ {
++ *mp++ = '8'; *mp = '\0';
++ }
+ break;
+ case 'x':
+ pageInSeq = 1;
+--
+2.25.1
+
diff --git a/meta/recipes-multimedia/libtiff/tiff_4.1.0.bb b/meta/recipes-multimedia/libtiff/tiff_4.1.0.bb
index 4383f7af8e..7efaba3a38 100644
--- a/meta/recipes-multimedia/libtiff/tiff_4.1.0.bb
+++ b/meta/recipes-multimedia/libtiff/tiff_4.1.0.bb
@@ -25,6 +25,35 @@ SRC_URI = "http://download.osgeo.org/libtiff/tiff-${PV}.tar.gz \
file://CVE-2022-0891.patch \
file://CVE-2022-0924.patch \
file://CVE-2022-2056-CVE-2022-2057-CVE-2022-2058.patch \
+ file://CVE-2022-34526.patch \
+ file://CVE-2022-2867-CVE-2022-2868-CVE-2022-2869.patch \
+ file://CVE-2022-1354.patch \
+ file://CVE-2022-1355.patch \
+ file://CVE-2022-3570_3598.patch \
+ file://CVE-2022-3597_3626_3627.patch \
+ file://CVE-2022-3599.patch \
+ file://CVE-2022-3970.patch \
+ file://CVE-2022-48281.patch \
+ file://CVE-2023-0795_0796_0797_0798_0799.patch \
+ file://CVE-2023-0800_0801_0802_0803_0804.patch \
+ file://CVE-2023-1916.patch \
+ file://CVE-2023-25433.patch \
+ file://CVE-2023-25434-CVE-2023-25435.patch \
+ file://CVE-2023-26965.patch \
+ file://CVE-2023-26966.patch \
+ file://CVE-2023-2908.patch \
+ file://CVE-2023-3316.patch \
+ file://CVE-2023-3576.patch \
+ file://CVE-2023-3618.patch \
+ file://CVE-2023-40745.patch \
+ file://CVE-2023-41175.patch \
+ file://CVE-2022-40090.patch \
+ file://CVE-2023-6228.patch \
+ file://CVE-2023-6277-1.patch \
+ file://CVE-2023-6277-2.patch \
+ file://CVE-2023-6277-3.patch \
+ file://CVE-2023-6277-4.patch \
+ file://CVE-2023-52356.patch \
"
SRC_URI[md5sum] = "2165e7aba557463acc0664e71a3ed424"
SRC_URI[sha256sum] = "5d29f32517dadb6dbcd1255ea5bbc93a2b54b94fbf83653b4d65c7d6775b8634"
diff --git a/meta/recipes-multimedia/webp/files/CVE-2023-1999.patch b/meta/recipes-multimedia/webp/files/CVE-2023-1999.patch
new file mode 100644
index 0000000000..d293ab93ab
--- /dev/null
+++ b/meta/recipes-multimedia/webp/files/CVE-2023-1999.patch
@@ -0,0 +1,55 @@
+From a486d800b60d0af4cc0836bf7ed8f21e12974129 Mon Sep 17 00:00:00 2001
+From: James Zern <jzern@google.com>
+Date: Wed, 22 Feb 2023 22:15:47 -0800
+Subject: [PATCH] EncodeAlphaInternal: clear result->bw on error
+
+This avoids a double free should the function fail prior to
+VP8BitWriterInit() and a previous trial result's buffer carried over.
+Previously in ApplyFiltersAndEncode() trial.bw (with a previous
+iteration's buffer) would be freed, followed by best.bw pointing to the
+same buffer.
+
+Since:
+187d379d add a fallback to ALPHA_NO_COMPRESSION
+
+In addition, check the return value of VP8BitWriterInit() in this
+function.
+
+Bug: webp:603
+Change-Id: Ic258381ee26c8c16bc211d157c8153831c8c6910
+
+CVE: CVE-2023-1999
+Upstream-Status: Backport [https://github.com/webmproject/libwebp/commit/a486d800b60d0af4cc0836bf7ed8f21e12974129]
+Signed-off-by: Nikhil R <nikhil.r@kpit.com>
+---
+ src/enc/alpha_enc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/enc/alpha_enc.c b/src/enc/alpha_enc.c
+index f7c02690e3..7d205586fe 100644
+--- a/src/enc/alpha_enc.c
++++ b/src/enc/alpha_enc.c
+@@ -13,6 +13,7 @@
+
+ #include <assert.h>
+ #include <stdlib.h>
++#include <string.h>
+
+ #include "src/enc/vp8i_enc.h"
+ #include "src/dsp/dsp.h"
+@@ -148,6 +149,7 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
+ }
+ } else {
+ VP8LBitWriterWipeOut(&tmp_bw);
++ memset(&result->bw, 0, sizeof(result->bw));
+ return 0;
+ }
+ }
+@@ -162,7 +164,7 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
+ header = method | (filter << 2);
+ if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4;
+
+- VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size);
++ if (!VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size)) ok = 0;
+ ok = ok && VP8BitWriterAppend(&result->bw, &header, ALPHA_HEADER_LEN);
+ ok = ok && VP8BitWriterAppend(&result->bw, output, output_size);
diff --git a/meta/recipes-multimedia/webp/files/CVE-2023-4863-0001.patch b/meta/recipes-multimedia/webp/files/CVE-2023-4863-0001.patch
new file mode 100644
index 0000000000..419b12f7d9
--- /dev/null
+++ b/meta/recipes-multimedia/webp/files/CVE-2023-4863-0001.patch
@@ -0,0 +1,366 @@
+From 902bc9190331343b2017211debcec8d2ab87e17a Mon Sep 17 00:00:00 2001
+From: Vincent Rabaud <vrabaud@google.com>
+Date: Thu, 7 Sep 2023 21:16:03 +0200
+Subject: [PATCH 1/2] Fix OOB write in BuildHuffmanTable.
+
+First, BuildHuffmanTable is called to check if the data is valid.
+If it is and the table is not big enough, more memory is allocated.
+
+This will make sure that valid (but unoptimized because of unbalanced
+codes) streams are still decodable.
+
+Bug: chromium:1479274
+Change-Id: I31c36dbf3aa78d35ecf38706b50464fd3d375741
+
+CVE: CVE-2023-4863
+
+Upstream-Status: Backport [https://github.com/webmproject/libwebp/commit/902bc9190331343b2017211debcec8d2ab87e17a]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ src/dec/vp8l_dec.c | 46 ++++++++++---------
+ src/dec/vp8li_dec.h | 2 +-
+ src/utils/huffman_utils.c | 97 +++++++++++++++++++++++++++++++--------
+ src/utils/huffman_utils.h | 27 +++++++++--
+ 4 files changed, 129 insertions(+), 43 deletions(-)
+
+diff --git a/src/dec/vp8l_dec.c b/src/dec/vp8l_dec.c
+index 93615d4..0d38314 100644
+--- a/src/dec/vp8l_dec.c
++++ b/src/dec/vp8l_dec.c
+@@ -253,11 +253,11 @@ static int ReadHuffmanCodeLengths(
+ int symbol;
+ int max_symbol;
+ int prev_code_len = DEFAULT_CODE_LENGTH;
+- HuffmanCode table[1 << LENGTHS_TABLE_BITS];
++ HuffmanTables tables;
+
+- if (!VP8LBuildHuffmanTable(table, LENGTHS_TABLE_BITS,
+- code_length_code_lengths,
+- NUM_CODE_LENGTH_CODES)) {
++ if (!VP8LHuffmanTablesAllocate(1 << LENGTHS_TABLE_BITS, &tables) ||
++ !VP8LBuildHuffmanTable(&tables, LENGTHS_TABLE_BITS,
++ code_length_code_lengths, NUM_CODE_LENGTH_CODES)) {
+ goto End;
+ }
+
+@@ -277,7 +277,7 @@ static int ReadHuffmanCodeLengths(
+ int code_len;
+ if (max_symbol-- == 0) break;
+ VP8LFillBitWindow(br);
+- p = &table[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
++ p = &tables.curr_segment->start[VP8LPrefetchBits(br) & LENGTHS_TABLE_MASK];
+ VP8LSetBitPos(br, br->bit_pos_ + p->bits);
+ code_len = p->value;
+ if (code_len < kCodeLengthLiterals) {
+@@ -300,6 +300,7 @@ static int ReadHuffmanCodeLengths(
+ ok = 1;
+
+ End:
++ VP8LHuffmanTablesDeallocate(&tables);
+ if (!ok) dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
+ return ok;
+ }
+@@ -307,7 +308,8 @@ static int ReadHuffmanCodeLengths(
+ // 'code_lengths' is pre-allocated temporary buffer, used for creating Huffman
+ // tree.
+ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
+- int* const code_lengths, HuffmanCode* const table) {
++ int* const code_lengths,
++ HuffmanTables* const table) {
+ int ok = 0;
+ int size = 0;
+ VP8LBitReader* const br = &dec->br_;
+@@ -362,8 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+ VP8LMetadata* const hdr = &dec->hdr_;
+ uint32_t* huffman_image = NULL;
+ HTreeGroup* htree_groups = NULL;
+- HuffmanCode* huffman_tables = NULL;
+- HuffmanCode* huffman_table = NULL;
++ HuffmanTables* huffman_tables = &hdr->huffman_tables_;
+ int num_htree_groups = 1;
+ int num_htree_groups_max = 1;
+ int max_alphabet_size = 0;
+@@ -372,6 +373,10 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+ int* mapping = NULL;
+ int ok = 0;
+
++ // Check the table has been 0 initialized (through InitMetadata).
++ assert(huffman_tables->root.start == NULL);
++ assert(huffman_tables->curr_segment == NULL);
++
+ if (allow_recursion && VP8LReadBits(br, 1)) {
+ // use meta Huffman codes.
+ const int huffman_precision = VP8LReadBits(br, 3) + 2;
+@@ -434,16 +439,15 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+
+ code_lengths = (int*)WebPSafeCalloc((uint64_t)max_alphabet_size,
+ sizeof(*code_lengths));
+- huffman_tables = (HuffmanCode*)WebPSafeMalloc(num_htree_groups * table_size,
+- sizeof(*huffman_tables));
+ htree_groups = VP8LHtreeGroupsNew(num_htree_groups);
+
+- if (htree_groups == NULL || code_lengths == NULL || huffman_tables == NULL) {
++ if (htree_groups == NULL || code_lengths == NULL ||
++ !VP8LHuffmanTablesAllocate(num_htree_groups * table_size,
++ huffman_tables)) {
+ dec->status_ = VP8_STATUS_OUT_OF_MEMORY;
+ goto Error;
+ }
+
+- huffman_table = huffman_tables;
+ for (i = 0; i < num_htree_groups_max; ++i) {
+ // If the index "i" is unused in the Huffman image, just make sure the
+ // coefficients are valid but do not store them.
+@@ -468,19 +472,20 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+ int max_bits = 0;
+ for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
+ int alphabet_size = kAlphabetSize[j];
+- htrees[j] = huffman_table;
+ if (j == 0 && color_cache_bits > 0) {
+ alphabet_size += (1 << color_cache_bits);
+ }
+- size = ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_table);
++ size =
++ ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
++ htrees[j] = huffman_tables->curr_segment->curr_table;
+ if (size == 0) {
+ goto Error;
+ }
+ if (is_trivial_literal && kLiteralMap[j] == 1) {
+- is_trivial_literal = (huffman_table->bits == 0);
++ is_trivial_literal = (htrees[j]->bits == 0);
+ }
+- total_size += huffman_table->bits;
+- huffman_table += size;
++ total_size += htrees[j]->bits;
++ huffman_tables->curr_segment->curr_table += size;
+ if (j <= ALPHA) {
+ int local_max_bits = code_lengths[0];
+ int k;
+@@ -515,14 +520,13 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
+ hdr->huffman_image_ = huffman_image;
+ hdr->num_htree_groups_ = num_htree_groups;
+ hdr->htree_groups_ = htree_groups;
+- hdr->huffman_tables_ = huffman_tables;
+
+ Error:
+ WebPSafeFree(code_lengths);
+ WebPSafeFree(mapping);
+ if (!ok) {
+ WebPSafeFree(huffman_image);
+- WebPSafeFree(huffman_tables);
++ VP8LHuffmanTablesDeallocate(huffman_tables);
+ VP8LHtreeGroupsFree(htree_groups);
+ }
+ return ok;
+@@ -1354,7 +1358,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
+ assert(hdr != NULL);
+
+ WebPSafeFree(hdr->huffman_image_);
+- WebPSafeFree(hdr->huffman_tables_);
++ VP8LHuffmanTablesDeallocate(&hdr->huffman_tables_);
+ VP8LHtreeGroupsFree(hdr->htree_groups_);
+ VP8LColorCacheClear(&hdr->color_cache_);
+ VP8LColorCacheClear(&hdr->saved_color_cache_);
+@@ -1670,7 +1674,7 @@ int VP8LDecodeImage(VP8LDecoder* const dec) {
+ // Sanity checks.
+ if (dec == NULL) return 0;
+
+- assert(dec->hdr_.huffman_tables_ != NULL);
++ assert(dec->hdr_.huffman_tables_.root.start != NULL);
+ assert(dec->hdr_.htree_groups_ != NULL);
+ assert(dec->hdr_.num_htree_groups_ > 0);
+
+diff --git a/src/dec/vp8li_dec.h b/src/dec/vp8li_dec.h
+index 72b2e86..32540a4 100644
+--- a/src/dec/vp8li_dec.h
++++ b/src/dec/vp8li_dec.h
+@@ -51,7 +51,7 @@ typedef struct {
+ uint32_t* huffman_image_;
+ int num_htree_groups_;
+ HTreeGroup* htree_groups_;
+- HuffmanCode* huffman_tables_;
++ HuffmanTables huffman_tables_;
+ } VP8LMetadata;
+
+ typedef struct VP8LDecoder VP8LDecoder;
+diff --git a/src/utils/huffman_utils.c b/src/utils/huffman_utils.c
+index 0cba0fb..9efd628 100644
+--- a/src/utils/huffman_utils.c
++++ b/src/utils/huffman_utils.c
+@@ -177,21 +177,24 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+ if (num_open < 0) {
+ return 0;
+ }
+- if (root_table == NULL) continue;
+ for (; count[len] > 0; --count[len]) {
+ HuffmanCode code;
+ if ((key & mask) != low) {
+- table += table_size;
++ if (root_table != NULL) table += table_size;
+ table_bits = NextTableBitSize(count, len, root_bits);
+ table_size = 1 << table_bits;
+ total_size += table_size;
+ low = key & mask;
+- root_table[low].bits = (uint8_t)(table_bits + root_bits);
+- root_table[low].value = (uint16_t)((table - root_table) - low);
++ if (root_table != NULL) {
++ root_table[low].bits = (uint8_t)(table_bits + root_bits);
++ root_table[low].value = (uint16_t)((table - root_table) - low);
++ }
++ }
++ if (root_table != NULL) {
++ code.bits = (uint8_t)(len - root_bits);
++ code.value = (uint16_t)sorted[symbol++];
++ ReplicateValue(&table[key >> root_bits], step, table_size, code);
+ }
+- code.bits = (uint8_t)(len - root_bits);
+- code.value = (uint16_t)sorted[symbol++];
+- ReplicateValue(&table[key >> root_bits], step, table_size, code);
+ key = GetNextKey(key, len);
+ }
+ }
+@@ -211,25 +214,83 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
+ ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
+ // Cut-off value for switching between heap and stack allocation.
+ #define SORTED_SIZE_CUTOFF 512
+-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
++int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
+ const int code_lengths[], int code_lengths_size) {
+- int total_size;
++ const int total_size =
++ BuildHuffmanTable(NULL, root_bits, code_lengths, code_lengths_size, NULL);
+ assert(code_lengths_size <= MAX_CODE_LENGTHS_SIZE);
+- if (root_table == NULL) {
+- total_size = BuildHuffmanTable(NULL, root_bits,
+- code_lengths, code_lengths_size, NULL);
+- } else if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
++ if (total_size == 0 || root_table == NULL) return total_size;
++
++ if (root_table->curr_segment->curr_table + total_size >=
++ root_table->curr_segment->start + root_table->curr_segment->size) {
++ // If 'root_table' does not have enough memory, allocate a new segment.
++ // The available part of root_table->curr_segment is left unused because we
++ // need a contiguous buffer.
++ const int segment_size = root_table->curr_segment->size;
++ struct HuffmanTablesSegment* next =
++ (HuffmanTablesSegment*)WebPSafeMalloc(1, sizeof(*next));
++ if (next == NULL) return 0;
++ // Fill the new segment.
++ // We need at least 'total_size' but if that value is small, it is better to
++ // allocate a big chunk to prevent more allocations later. 'segment_size' is
++ // therefore chosen (any other arbitrary value could be chosen).
++ next->size = total_size > segment_size ? total_size : segment_size;
++ next->start =
++ (HuffmanCode*)WebPSafeMalloc(next->size, sizeof(*next->start));
++ if (next->start == NULL) {
++ WebPSafeFree(next);
++ return 0;
++ }
++ next->curr_table = next->start;
++ next->next = NULL;
++ // Point to the new segment.
++ root_table->curr_segment->next = next;
++ root_table->curr_segment = next;
++ }
++ if (code_lengths_size <= SORTED_SIZE_CUTOFF) {
+ // use local stack-allocated array.
+ uint16_t sorted[SORTED_SIZE_CUTOFF];
+- total_size = BuildHuffmanTable(root_table, root_bits,
+- code_lengths, code_lengths_size, sorted);
+- } else { // rare case. Use heap allocation.
++ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
++ code_lengths, code_lengths_size, sorted);
++ } else { // rare case. Use heap allocation.
+ uint16_t* const sorted =
+ (uint16_t*)WebPSafeMalloc(code_lengths_size, sizeof(*sorted));
+ if (sorted == NULL) return 0;
+- total_size = BuildHuffmanTable(root_table, root_bits,
+- code_lengths, code_lengths_size, sorted);
++ BuildHuffmanTable(root_table->curr_segment->curr_table, root_bits,
++ code_lengths, code_lengths_size, sorted);
+ WebPSafeFree(sorted);
+ }
+ return total_size;
+ }
++
++int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables) {
++ // Have 'segment' point to the first segment for now, 'root'.
++ HuffmanTablesSegment* const root = &huffman_tables->root;
++ huffman_tables->curr_segment = root;
++ // Allocate root.
++ root->start = (HuffmanCode*)WebPSafeMalloc(size, sizeof(*root->start));
++ if (root->start == NULL) return 0;
++ root->curr_table = root->start;
++ root->next = NULL;
++ root->size = size;
++ return 1;
++}
++
++void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables) {
++ HuffmanTablesSegment *current, *next;
++ if (huffman_tables == NULL) return;
++ // Free the root node.
++ current = &huffman_tables->root;
++ next = current->next;
++ WebPSafeFree(current->start);
++ current->start = NULL;
++ current->next = NULL;
++ current = next;
++ // Free the following nodes.
++ while (current != NULL) {
++ next = current->next;
++ WebPSafeFree(current->start);
++ WebPSafeFree(current);
++ current = next;
++ }
++}
+diff --git a/src/utils/huffman_utils.h b/src/utils/huffman_utils.h
+index 13b7ad1..98415c5 100644
+--- a/src/utils/huffman_utils.h
++++ b/src/utils/huffman_utils.h
+@@ -43,6 +43,29 @@ typedef struct {
+ // or non-literal symbol otherwise
+ } HuffmanCode32;
+
++// Contiguous memory segment of HuffmanCodes.
++typedef struct HuffmanTablesSegment {
++ HuffmanCode* start;
++ // Pointer to where we are writing into the segment. Starts at 'start' and
++ // cannot go beyond 'start' + 'size'.
++ HuffmanCode* curr_table;
++ // Pointer to the next segment in the chain.
++ struct HuffmanTablesSegment* next;
++ int size;
++} HuffmanTablesSegment;
++
++// Chained memory segments of HuffmanCodes.
++typedef struct HuffmanTables {
++ HuffmanTablesSegment root;
++ // Currently processed segment. At first, this is 'root'.
++ HuffmanTablesSegment* curr_segment;
++} HuffmanTables;
++
++// Allocates a HuffmanTables with 'size' contiguous HuffmanCodes. Returns 0 on
++// memory allocation error, 1 otherwise.
++int VP8LHuffmanTablesAllocate(int size, HuffmanTables* huffman_tables);
++void VP8LHuffmanTablesDeallocate(HuffmanTables* const huffman_tables);
++
+ #define HUFFMAN_PACKED_BITS 6
+ #define HUFFMAN_PACKED_TABLE_SIZE (1u << HUFFMAN_PACKED_BITS)
+
+@@ -78,9 +101,7 @@ void VP8LHtreeGroupsFree(HTreeGroup* const htree_groups);
+ // the huffman table.
+ // Returns built table size or 0 in case of error (invalid tree or
+ // memory error).
+-// If root_table is NULL, it returns 0 if a lookup cannot be built, something
+-// > 0 otherwise (but not the table size).
+-int VP8LBuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
++int VP8LBuildHuffmanTable(HuffmanTables* const root_table, int root_bits,
+ const int code_lengths[], int code_lengths_size);
+
+ #ifdef __cplusplus
+--
+2.40.0
+
diff --git a/meta/recipes-multimedia/webp/files/CVE-2023-4863-0002.patch b/meta/recipes-multimedia/webp/files/CVE-2023-4863-0002.patch
new file mode 100644
index 0000000000..c1eedb6100
--- /dev/null
+++ b/meta/recipes-multimedia/webp/files/CVE-2023-4863-0002.patch
@@ -0,0 +1,53 @@
+From 95ea5226c870449522240ccff26f0b006037c520 Mon Sep 17 00:00:00 2001
+From: Vincent Rabaud <vrabaud@google.com>
+Date: Mon, 11 Sep 2023 16:06:08 +0200
+Subject: [PATCH 2/2] Fix invalid incremental decoding check.
+
+The first condition is only necessary if we have not read enough
+(enough being defined by src_last, not src_end which is the end
+of the image).
+The second condition now fits the comment below: "if not
+incremental, and we are past the end of buffer".
+
+BUG=oss-fuzz:62136
+
+Change-Id: I0700f67c62db8e1c02c2e429a069a71e606a5e4f
+
+CVE: CVE-2023-4863
+
+Upstream-Status: Backport [https://github.com/webmproject/libwebp/commit/95ea5226c870449522240ccff26f0b006037c520]
+
+Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
+---
+ src/dec/vp8l_dec.c | 15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+diff --git a/src/dec/vp8l_dec.c b/src/dec/vp8l_dec.c
+index 0d38314..684a5b6 100644
+--- a/src/dec/vp8l_dec.c
++++ b/src/dec/vp8l_dec.c
+@@ -1237,9 +1237,20 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
+ }
+
+ br->eos_ = VP8LIsEndOfStream(br);
+- if (dec->incremental_ && br->eos_ && src < src_end) {
++ // In incremental decoding:
++ // br->eos_ && src < src_last: if 'br' reached the end of the buffer and
++ // 'src_last' has not been reached yet, there is not enough data. 'dec' has to
++ // be reset until there is more data.
++ // !br->eos_ && src < src_last: this cannot happen as either the buffer is
++ // fully read, either enough has been read to reach 'src_last'.
++ // src >= src_last: 'src_last' is reached, all is fine. 'src' can actually go
++ // beyond 'src_last' in case the image is cropped and an LZ77 goes further.
++ // The buffer might have been enough or there is some left. 'br->eos_' does
++ // not matter.
++ assert(!dec->incremental_ || (br->eos_ && src < src_last) || src >= src_last);
++ if (dec->incremental_ && br->eos_ && src < src_last) {
+ RestoreState(dec);
+- } else if (!br->eos_) {
++ } else if ((dec->incremental_ && src >= src_last) || !br->eos_) {
+ // Process the remaining rows corresponding to last row-block.
+ if (process_func != NULL) {
+ process_func(dec, row > last_row ? last_row : row);
+--
+2.40.0
diff --git a/meta/recipes-multimedia/webp/libwebp_1.1.0.bb b/meta/recipes-multimedia/webp/libwebp_1.1.0.bb
index 68e5ae2b3c..88c36cb76c 100644
--- a/meta/recipes-multimedia/webp/libwebp_1.1.0.bb
+++ b/meta/recipes-multimedia/webp/libwebp_1.1.0.bb
@@ -19,6 +19,12 @@ SRC_URI[sha256sum] = "98a052268cc4d5ece27f76572a7f50293f439c17a98e67c4ea0c7ed6f5
UPSTREAM_CHECK_URI = "http://downloads.webmproject.org/releases/webp/index.html"
+SRC_URI += " \
+ file://CVE-2023-1999.patch \
+ file://CVE-2023-4863-0001.patch \
+ file://CVE-2023-4863-0002.patch \
+"
+
EXTRA_OECONF = " \
--disable-wic \
--enable-libwebpmux \