summaryrefslogtreecommitdiffstats
path: root/meta/recipes-graphics/jpeg/files
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-graphics/jpeg/files')
-rw-r--r--meta/recipes-graphics/jpeg/files/CVE-2020-35538-1.patch457
-rw-r--r--meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch400
-rw-r--r--meta/recipes-graphics/jpeg/files/CVE-2021-46822.patch133
-rw-r--r--meta/recipes-graphics/jpeg/files/CVE-2023-2804-1.patch97
-rw-r--r--meta/recipes-graphics/jpeg/files/CVE-2023-2804-2.patch75
5 files changed, 1162 insertions, 0 deletions
diff --git a/meta/recipes-graphics/jpeg/files/CVE-2020-35538-1.patch b/meta/recipes-graphics/jpeg/files/CVE-2020-35538-1.patch
new file mode 100644
index 0000000000..8a52ed01e9
--- /dev/null
+++ b/meta/recipes-graphics/jpeg/files/CVE-2020-35538-1.patch
@@ -0,0 +1,457 @@
+From 9120a247436e84c0b4eea828cb11e8f665fcde30 Mon Sep 17 00:00:00 2001
+From: DRC <information@libjpeg-turbo.org>
+Date: Thu, 23 Jul 2020 21:24:38 -0500
+Subject: [PATCH] Fix jpeg_skip_scanlines() segfault w/merged upsamp
+
+The additional segfault mentioned in #244 was due to the fact that
+the merged upsamplers use a different private structure than the
+non-merged upsamplers. jpeg_skip_scanlines() was assuming the latter, so
+when merged upsampling was enabled, jpeg_skip_scanlines() clobbered one
+of the IDCT method pointers in the merged upsampler's private structure.
+
+For reasons unknown, the test image in #441 did not encounter this
+segfault (too small?), but it encountered an issue similar to the one
+fixed in 5bc43c7821df982f65aa1c738f67fbf7cba8bd69, whereby it was
+necessary to set up a dummy postprocessing function in
+read_and_discard_scanlines() when merged upsampling was enabled.
+Failing to do so caused either a segfault in merged_2v_upsample() (due
+to a NULL pointer being passed to jcopy_sample_rows()) or an error
+("Corrupt JPEG data: premature end of data segment"), depending on the
+number of scanlines skipped and whether the first scanline skipped was
+an odd- or even-numbered row.
+
+Fixes #441
+Fixes #244 (for real this time)
+
+Upstream-Status: Backport [https://github.com/libjpeg-turbo/libjpeg-turbo/commit/9120a247436e84c0b4eea828cb11e8f665fcde30]
+CVE: CVE-2020-35538
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ ChangeLog.md | 7 +++++
+ jdapistd.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++------
+ jdmerge.c | 46 +++++++--------------------------
+ jdmerge.h | 47 ++++++++++++++++++++++++++++++++++
+ jdmrg565.c | 10 ++++----
+ jdmrgext.c | 6 ++---
+ 6 files changed, 135 insertions(+), 53 deletions(-)
+ create mode 100644 jdmerge.h
+
+diff --git a/ChangeLog.md b/ChangeLog.md
+index 2ebfe71..19d18fa 100644
+--- a/ChangeLog.md
++++ b/ChangeLog.md
+@@ -54,6 +54,13 @@ a 16-bit binary PGM file into an RGB image buffer.
+ generated when using the `tjLoadImage()` function to load a 16-bit binary PPM
+ file into an extended RGB image buffer.
+
++2. Fixed segfaults or "Corrupt JPEG data: premature end of data segment" errors
++in `jpeg_skip_scanlines()` that occurred when decompressing 4:2:2 or 4:2:0 JPEG
++images using the merged (non-fancy) upsampling algorithms (that is, when
++setting `cinfo.do_fancy_upsampling` to `FALSE`.) 2.0.0[6] was a similar fix,
++but it did not cover all cases.
++
++
+ 2.0.3
+ =====
+
+diff --git a/jdapistd.c b/jdapistd.c
+index 2c808fa..91da642 100644
+--- a/jdapistd.c
++++ b/jdapistd.c
+@@ -4,7 +4,7 @@
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+- * Copyright (C) 2010, 2015-2018, D. R. Commander.
++ * Copyright (C) 2010, 2015-2018, 2020, D. R. Commander.
+ * Copyright (C) 2015, Google, Inc.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+@@ -21,6 +21,8 @@
+ #include "jinclude.h"
+ #include "jdmainct.h"
+ #include "jdcoefct.h"
++#include "jdmaster.h"
++#include "jdmerge.h"
+ #include "jdsample.h"
+ #include "jmemsys.h"
+
+@@ -304,6 +306,16 @@ noop_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ }
+
+
++/* Dummy postprocessing function used by jpeg_skip_scanlines() */
++LOCAL(void)
++noop_post_process (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
++ JDIMENSION *in_row_group_ctr,
++ JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
++ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
++{
++}
++
++
+ /*
+ * In some cases, it is best to call jpeg_read_scanlines() and discard the
+ * output, rather than skipping the scanlines, because this allows us to
+@@ -316,11 +328,17 @@ LOCAL(void)
+ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ {
+ JDIMENSION n;
++ my_master_ptr master = (my_master_ptr)cinfo->master;
+ void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION input_row, JSAMPARRAY output_buf,
+ int num_rows) = NULL;
+ void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows) = NULL;
++ void (*post_process_data) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
++ JDIMENSION *in_row_group_ctr,
++ JDIMENSION in_row_groups_avail,
++ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
++ JDIMENSION out_rows_avail) = NULL;
+
+ if (cinfo->cconvert && cinfo->cconvert->color_convert) {
+ color_convert = cinfo->cconvert->color_convert;
+@@ -332,6 +350,12 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ cinfo->cquantize->color_quantize = noop_quantize;
+ }
+
++ if (master->using_merged_upsample && cinfo->post &&
++ cinfo->post->post_process_data) {
++ post_process_data = cinfo->post->post_process_data;
++ cinfo->post->post_process_data = noop_post_process;
++ }
++
+ for (n = 0; n < num_lines; n++)
+ jpeg_read_scanlines(cinfo, NULL, 1);
+
+@@ -340,6 +364,9 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+
+ if (color_quantize)
+ cinfo->cquantize->color_quantize = color_quantize;
++
++ if (post_process_data)
++ cinfo->post->post_process_data = post_process_data;
+ }
+
+
+@@ -382,7 +409,7 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ {
+ my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
+ my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_master_ptr master = (my_master_ptr)cinfo->master;
+ JDIMENSION i, x;
+ int y;
+ JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row;
+@@ -445,8 +472,16 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ main_ptr->buffer_full = FALSE;
+ main_ptr->rowgroup_ctr = 0;
+ main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
+- upsample->next_row_out = cinfo->max_v_samp_factor;
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ if (master->using_merged_upsample) {
++ my_merged_upsample_ptr upsample =
++ (my_merged_upsample_ptr)cinfo->upsample;
++ upsample->spare_full = FALSE;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ } else {
++ my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ upsample->next_row_out = cinfo->max_v_samp_factor;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ }
+ }
+
+ /* Skipping is much simpler when context rows are not required. */
+@@ -458,8 +493,16 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ cinfo->output_scanline += lines_left_in_iMCU_row;
+ main_ptr->buffer_full = FALSE;
+ main_ptr->rowgroup_ctr = 0;
+- upsample->next_row_out = cinfo->max_v_samp_factor;
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ if (master->using_merged_upsample) {
++ my_merged_upsample_ptr upsample =
++ (my_merged_upsample_ptr)cinfo->upsample;
++ upsample->spare_full = FALSE;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ } else {
++ my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ upsample->next_row_out = cinfo->max_v_samp_factor;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ }
+ }
+ }
+
+@@ -494,7 +537,14 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row;
+ increment_simple_rowgroup_ctr(cinfo, lines_to_read);
+ }
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ if (master->using_merged_upsample) {
++ my_merged_upsample_ptr upsample =
++ (my_merged_upsample_ptr)cinfo->upsample;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ } else {
++ my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ }
+ return num_lines;
+ }
+
+@@ -535,7 +585,13 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ * bit odd, since "rows_to_go" seems to be redundantly keeping track of
+ * output_scanline.
+ */
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ if (master->using_merged_upsample) {
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ } else {
++ my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
++ }
+
+ /* Always skip the requested number of lines. */
+ return num_lines;
+diff --git a/jdmerge.c b/jdmerge.c
+index dff5a35..833ad67 100644
+--- a/jdmerge.c
++++ b/jdmerge.c
+@@ -5,7 +5,7 @@
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+ * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
+- * Copyright (C) 2009, 2011, 2014-2015, D. R. Commander.
++ * Copyright (C) 2009, 2011, 2014-2015, 2020, D. R. Commander.
+ * Copyright (C) 2013, Linaro Limited.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+@@ -40,41 +40,13 @@
+ #define JPEG_INTERNALS
+ #include "jinclude.h"
+ #include "jpeglib.h"
++#include "jdmerge.h"
+ #include "jsimd.h"
+ #include "jconfigint.h"
+
+ #ifdef UPSAMPLE_MERGING_SUPPORTED
+
+
+-/* Private subobject */
+-
+-typedef struct {
+- struct jpeg_upsampler pub; /* public fields */
+-
+- /* Pointer to routine to do actual upsampling/conversion of one row group */
+- void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+- JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);
+-
+- /* Private state for YCC->RGB conversion */
+- int *Cr_r_tab; /* => table for Cr to R conversion */
+- int *Cb_b_tab; /* => table for Cb to B conversion */
+- JLONG *Cr_g_tab; /* => table for Cr to G conversion */
+- JLONG *Cb_g_tab; /* => table for Cb to G conversion */
+-
+- /* For 2:1 vertical sampling, we produce two output rows at a time.
+- * We need a "spare" row buffer to hold the second output row if the
+- * application provides just a one-row buffer; we also use the spare
+- * to discard the dummy last row if the image height is odd.
+- */
+- JSAMPROW spare_row;
+- boolean spare_full; /* T if spare buffer is occupied */
+-
+- JDIMENSION out_row_width; /* samples per output row */
+- JDIMENSION rows_to_go; /* counts rows remaining in image */
+-} my_upsampler;
+-
+-typedef my_upsampler *my_upsample_ptr;
+-
+ #define SCALEBITS 16 /* speediest right-shift on some machines */
+ #define ONE_HALF ((JLONG)1 << (SCALEBITS - 1))
+ #define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5))
+@@ -189,7 +161,7 @@ typedef my_upsampler *my_upsample_ptr;
+ LOCAL(void)
+ build_ycc_rgb_table(j_decompress_ptr cinfo)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ int i;
+ JLONG x;
+ SHIFT_TEMPS
+@@ -232,7 +204,7 @@ build_ycc_rgb_table(j_decompress_ptr cinfo)
+ METHODDEF(void)
+ start_pass_merged_upsample(j_decompress_ptr cinfo)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+
+ /* Mark the spare buffer empty */
+ upsample->spare_full = FALSE;
+@@ -254,7 +226,7 @@ merged_2v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
+ /* 2:1 vertical sampling case: may need a spare row. */
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ JSAMPROW work_ptrs[2];
+ JDIMENSION num_rows; /* number of rows returned to caller */
+
+@@ -305,7 +277,7 @@ merged_1v_upsample(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
+ /* 1:1 vertical sampling case: much easier, never need a spare row. */
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+
+ /* Just do the upsampling. */
+ (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
+@@ -566,11 +538,11 @@ h2v2_merged_upsample_565D(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ GLOBAL(void)
+ jinit_merged_upsampler(j_decompress_ptr cinfo)
+ {
+- my_upsample_ptr upsample;
++ my_merged_upsample_ptr upsample;
+
+- upsample = (my_upsample_ptr)
++ upsample = (my_merged_upsample_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
+- sizeof(my_upsampler));
++ sizeof(my_merged_upsampler));
+ cinfo->upsample = (struct jpeg_upsampler *)upsample;
+ upsample->pub.start_pass = start_pass_merged_upsample;
+ upsample->pub.need_context_rows = FALSE;
+diff --git a/jdmerge.h b/jdmerge.h
+new file mode 100644
+index 0000000..b583396
+--- /dev/null
++++ b/jdmerge.h
+@@ -0,0 +1,47 @@
++/*
++ * jdmerge.h
++ *
++ * This file was part of the Independent JPEG Group's software:
++ * Copyright (C) 1994-1996, Thomas G. Lane.
++ * libjpeg-turbo Modifications:
++ * Copyright (C) 2020, D. R. Commander.
++ * For conditions of distribution and use, see the accompanying README.ijg
++ * file.
++ */
++
++#define JPEG_INTERNALS
++#include "jpeglib.h"
++
++#ifdef UPSAMPLE_MERGING_SUPPORTED
++
++
++/* Private subobject */
++
++typedef struct {
++ struct jpeg_upsampler pub; /* public fields */
++
++ /* Pointer to routine to do actual upsampling/conversion of one row group */
++ void (*upmethod) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
++ JDIMENSION in_row_group_ctr, JSAMPARRAY output_buf);
++
++ /* Private state for YCC->RGB conversion */
++ int *Cr_r_tab; /* => table for Cr to R conversion */
++ int *Cb_b_tab; /* => table for Cb to B conversion */
++ JLONG *Cr_g_tab; /* => table for Cr to G conversion */
++ JLONG *Cb_g_tab; /* => table for Cb to G conversion */
++
++ /* For 2:1 vertical sampling, we produce two output rows at a time.
++ * We need a "spare" row buffer to hold the second output row if the
++ * application provides just a one-row buffer; we also use the spare
++ * to discard the dummy last row if the image height is odd.
++ */
++ JSAMPROW spare_row;
++ boolean spare_full; /* T if spare buffer is occupied */
++
++ JDIMENSION out_row_width; /* samples per output row */
++ JDIMENSION rows_to_go; /* counts rows remaining in image */
++} my_merged_upsampler;
++
++typedef my_merged_upsampler *my_merged_upsample_ptr;
++
++#endif /* UPSAMPLE_MERGING_SUPPORTED */
+diff --git a/jdmrg565.c b/jdmrg565.c
+index 1b87e37..53f1e16 100644
+--- a/jdmrg565.c
++++ b/jdmrg565.c
+@@ -5,7 +5,7 @@
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2013, Linaro Limited.
+- * Copyright (C) 2014-2015, 2018, D. R. Commander.
++ * Copyright (C) 2014-2015, 2018, 2020, D. R. Commander.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ *
+@@ -19,7 +19,7 @@ h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr;
+@@ -90,7 +90,7 @@ h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr;
+@@ -163,7 +163,7 @@ h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr0, outptr1;
+@@ -259,7 +259,7 @@ h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr0, outptr1;
+diff --git a/jdmrgext.c b/jdmrgext.c
+index b1c27df..c9a44d8 100644
+--- a/jdmrgext.c
++++ b/jdmrgext.c
+@@ -4,7 +4,7 @@
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+- * Copyright (C) 2011, 2015, D. R. Commander.
++ * Copyright (C) 2011, 2015, 2020, D. R. Commander.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ *
+@@ -25,7 +25,7 @@ h2v1_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr;
+@@ -97,7 +97,7 @@ h2v2_merged_upsample_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+ {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr0, outptr1;
+--
+2.25.1
+
diff --git a/meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch b/meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch
new file mode 100644
index 0000000000..f86175dff0
--- /dev/null
+++ b/meta/recipes-graphics/jpeg/files/CVE-2020-35538-2.patch
@@ -0,0 +1,400 @@
+From a46c111d9f3642f0ef3819e7298846ccc61869e0 Mon Sep 17 00:00:00 2001
+From: DRC <information@libjpeg-turbo.org>
+Date: Mon, 27 Jul 2020 14:21:23 -0500
+Subject: [PATCH] Further jpeg_skip_scanlines() fixes
+
+- Introduce a partial image decompression regression test script that
+ validates the correctness of jpeg_skip_scanlines() and
+ jpeg_crop_scanlines() for a variety of cropping regions and libjpeg
+ settings.
+
+ This regression test catches the following issues:
+ #182, fixed in 5bc43c7
+ #237, fixed in 6e95c08
+ #244, fixed in 398c1e9
+ #441, fully fixed in this commit
+
+ It does not catch the following issues:
+ #194, fixed in 773040f
+ #244 (additional segfault), fixed in
+ 9120a24
+
+- Modify the libjpeg-turbo regression test suite (make test) so that it
+ checks for the issue reported in #441 (segfault in
+ jpeg_skip_scanlines() when used with 4:2:0 merged upsampling/color
+ conversion.)
+
+- Fix issues in jpeg_skip_scanlines() that caused incorrect output with
+ h2v2 (4:2:0) merged upsampling/color conversion. The previous commit
+ fixed the segfault reported in #441, but that was a symptom of a
+ larger problem. Because merged 4:2:0 upsampling uses a "spare row"
+ buffer, it is necessary to allow the upsampler to run when skipping
+ rows (fancy 4:2:0 upsampling, which uses context rows, also requires
+ this.) Otherwise, if skipping starts at an odd-numbered row, the
+ output image will be incorrect.
+
+- Throw an error if jpeg_skip_scanlines() is called with two-pass color
+ quantization enabled. With two-pass color quantization, the first
+ pass occurs within jpeg_start_decompress(), so subsequent calls to
+ jpeg_skip_scanlines() interfere with the multipass state and prevent
+ the second pass from occurring during subsequent calls to
+ jpeg_read_scanlines().
+
+Upstream-Status: Backport [https://github.com/libjpeg-turbo/libjpeg-turbo/commit/a46c111d9f3642f0ef3819e7298846ccc61869e0]
+CVE: CVE-2020-35538
+Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
+---
+ CMakeLists.txt | 9 +++--
+ ChangeLog.md | 15 +++++---
+ croptest.in | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ jdapistd.c | 70 +++++++++++--------------------------
+ libjpeg.txt | 6 ++--
+ 5 files changed, 136 insertions(+), 59 deletions(-)
+ create mode 100755 croptest.in
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index aee74c9..de451f4 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -753,7 +753,7 @@ else()
+ set(MD5_PPM_3x2_IFAST fd283664b3b49127984af0a7f118fccd)
+ set(MD5_JPEG_420_ISLOW_ARI e986fb0a637a8d833d96e8a6d6d84ea1)
+ set(MD5_JPEG_444_ISLOW_PROGARI 0a8f1c8f66e113c3cf635df0a475a617)
+- set(MD5_PPM_420M_IFAST_ARI 72b59a99bcf1de24c5b27d151bde2437)
++ set(MD5_PPM_420M_IFAST_ARI 57251da28a35b46eecb7177d82d10e0e)
+ set(MD5_JPEG_420_ISLOW 9a68f56bc76e466aa7e52f415d0f4a5f)
+ set(MD5_PPM_420M_ISLOW_2_1 9f9de8c0612f8d06869b960b05abf9c9)
+ set(MD5_PPM_420M_ISLOW_15_8 b6875bc070720b899566cc06459b63b7)
+@@ -1131,7 +1131,7 @@ foreach(libtype ${TEST_LIBTYPES})
+
+ if(WITH_ARITH_DEC)
+ # CC: RGB->YCC SAMP: h2v2 merged IDCT: ifast ENT: arith
+- add_bittest(djpeg 420m-ifast-ari "-fast;-ppm"
++ add_bittest(djpeg 420m-ifast-ari "-fast;-skip;1,20;-ppm"
+ testout_420m_ifast_ari.ppm ${TESTIMAGES}/testimgari.jpg
+ ${MD5_PPM_420M_IFAST_ARI})
+
+@@ -1266,6 +1266,11 @@ endforeach()
+ add_custom_target(testclean COMMAND ${CMAKE_COMMAND} -P
+ ${CMAKE_CURRENT_SOURCE_DIR}/cmakescripts/testclean.cmake)
+
++configure_file(croptest.in croptest @ONLY)
++add_custom_target(croptest
++ COMMAND echo croptest
++ COMMAND ${BASH} ${CMAKE_CURRENT_BINARY_DIR}/croptest)
++
+ if(WITH_TURBOJPEG)
+ configure_file(tjbenchtest.in tjbenchtest @ONLY)
+ configure_file(tjexampletest.in tjexampletest @ONLY)
+diff --git a/ChangeLog.md b/ChangeLog.md
+index 19d18fa..4562eff 100644
+--- a/ChangeLog.md
++++ b/ChangeLog.md
+@@ -54,11 +54,16 @@ a 16-bit binary PGM file into an RGB image buffer.
+ generated when using the `tjLoadImage()` function to load a 16-bit binary PPM
+ file into an extended RGB image buffer.
+
+-2. Fixed segfaults or "Corrupt JPEG data: premature end of data segment" errors
+-in `jpeg_skip_scanlines()` that occurred when decompressing 4:2:2 or 4:2:0 JPEG
+-images using the merged (non-fancy) upsampling algorithms (that is, when
+-setting `cinfo.do_fancy_upsampling` to `FALSE`.) 2.0.0[6] was a similar fix,
+-but it did not cover all cases.
++2. Fixed or worked around multiple issues with `jpeg_skip_scanlines()`:
++
++ - Fixed segfaults or "Corrupt JPEG data: premature end of data segment"
++errors in `jpeg_skip_scanlines()` that occurred when decompressing 4:2:2 or
++4:2:0 JPEG images using merged (non-fancy) upsampling/color conversion (that
++is, when setting `cinfo.do_fancy_upsampling` to `FALSE`.) 2.0.0[6] was a
++similar fix, but it did not cover all cases.
++ - `jpeg_skip_scanlines()` now throws an error if two-pass color
++quantization is enabled. Two-pass color quantization never worked properly
++with `jpeg_skip_scanlines()`, and the issues could not readily be fixed.
+
+
+ 2.0.3
+diff --git a/croptest.in b/croptest.in
+new file mode 100755
+index 0000000..7e3c293
+--- /dev/null
++++ b/croptest.in
+@@ -0,0 +1,95 @@
++#!/bin/bash
++
++set -u
++set -e
++trap onexit INT
++trap onexit TERM
++trap onexit EXIT
++
++onexit()
++{
++ if [ -d $OUTDIR ]; then
++ rm -rf $OUTDIR
++ fi
++}
++
++runme()
++{
++ echo \*\*\* $*
++ $*
++}
++
++IMAGE=vgl_6548_0026a.bmp
++WIDTH=128
++HEIGHT=95
++IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages
++OUTDIR=`mktemp -d /tmp/__croptest_output.XXXXXX`
++EXEDIR=@CMAKE_CURRENT_BINARY_DIR@
++
++if [ -d $OUTDIR ]; then
++ rm -rf $OUTDIR
++fi
++mkdir -p $OUTDIR
++
++exec >$EXEDIR/croptest.log
++
++echo "============================================================"
++echo "$IMAGE ($WIDTH x $HEIGHT)"
++echo "============================================================"
++echo
++
++for PROGARG in "" -progressive; do
++
++ cp $IMGDIR/$IMAGE $OUTDIR
++ basename=`basename $IMAGE .bmp`
++ echo "------------------------------------------------------------"
++ echo "Generating test images"
++ echo "------------------------------------------------------------"
++ echo
++ runme $EXEDIR/cjpeg $PROGARG -grayscale -outfile $OUTDIR/${basename}_GRAY.jpg $IMGDIR/${basename}.bmp
++ runme $EXEDIR/cjpeg $PROGARG -sample 2x2 -outfile $OUTDIR/${basename}_420.jpg $IMGDIR/${basename}.bmp
++ runme $EXEDIR/cjpeg $PROGARG -sample 2x1 -outfile $OUTDIR/${basename}_422.jpg $IMGDIR/${basename}.bmp
++ runme $EXEDIR/cjpeg $PROGARG -sample 1x2 -outfile $OUTDIR/${basename}_440.jpg $IMGDIR/${basename}.bmp
++ runme $EXEDIR/cjpeg $PROGARG -sample 1x1 -outfile $OUTDIR/${basename}_444.jpg $IMGDIR/${basename}.bmp
++ echo
++
++ for NSARG in "" -nosmooth; do
++
++ for COLORSARG in "" "-colors 256 -dither none -onepass"; do
++
++ for Y in {0..16}; do
++
++ for H in {1..16}; do
++
++ X=$(( (Y*16)%128 ))
++ W=$(( WIDTH-X-7 ))
++ if [ $Y -le 15 ]; then
++ CROPSPEC="${W}x${H}+${X}+${Y}"
++ else
++ Y2=$(( HEIGHT-H ));
++ CROPSPEC="${W}x${H}+${X}+${Y2}"
++ fi
++
++ echo "------------------------------------------------------------"
++ echo $PROGARG $NSARG $COLORSARG -crop $CROPSPEC
++ echo "------------------------------------------------------------"
++ echo
++ for samp in GRAY 420 422 440 444; do
++ $EXEDIR/djpeg $NSARG $COLORSARG -rgb -outfile $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}.jpg
++ convert -crop $CROPSPEC $OUTDIR/${basename}_${samp}_full.ppm $OUTDIR/${basename}_${samp}_ref.ppm
++ runme $EXEDIR/djpeg $NSARG $COLORSARG -crop $CROPSPEC -rgb -outfile $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}.jpg
++ runme cmp $OUTDIR/${basename}_${samp}.ppm $OUTDIR/${basename}_${samp}_ref.ppm
++ done
++ echo
++
++ done
++
++ done
++
++ done
++
++ done
++
++done
++
++echo SUCCESS!
+diff --git a/jdapistd.c b/jdapistd.c
+index 91da642..c502909 100644
+--- a/jdapistd.c
++++ b/jdapistd.c
+@@ -306,16 +306,6 @@ noop_quantize(j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ }
+
+
+-/* Dummy postprocessing function used by jpeg_skip_scanlines() */
+-LOCAL(void)
+-noop_post_process (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+- JDIMENSION *in_row_group_ctr,
+- JDIMENSION in_row_groups_avail, JSAMPARRAY output_buf,
+- JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail)
+-{
+-}
+-
+-
+ /*
+ * In some cases, it is best to call jpeg_read_scanlines() and discard the
+ * output, rather than skipping the scanlines, because this allows us to
+@@ -329,16 +319,12 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ {
+ JDIMENSION n;
+ my_master_ptr master = (my_master_ptr)cinfo->master;
++ JSAMPARRAY scanlines = NULL;
+ void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+ JDIMENSION input_row, JSAMPARRAY output_buf,
+ int num_rows) = NULL;
+ void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows) = NULL;
+- void (*post_process_data) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
+- JDIMENSION *in_row_group_ctr,
+- JDIMENSION in_row_groups_avail,
+- JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+- JDIMENSION out_rows_avail) = NULL;
+
+ if (cinfo->cconvert && cinfo->cconvert->color_convert) {
+ color_convert = cinfo->cconvert->color_convert;
+@@ -350,23 +336,19 @@ read_and_discard_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ cinfo->cquantize->color_quantize = noop_quantize;
+ }
+
+- if (master->using_merged_upsample && cinfo->post &&
+- cinfo->post->post_process_data) {
+- post_process_data = cinfo->post->post_process_data;
+- cinfo->post->post_process_data = noop_post_process;
++ if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) {
++ my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
++ scanlines = &upsample->spare_row;
+ }
+
+ for (n = 0; n < num_lines; n++)
+- jpeg_read_scanlines(cinfo, NULL, 1);
++ jpeg_read_scanlines(cinfo, scanlines, 1);
+
+ if (color_convert)
+ cinfo->cconvert->color_convert = color_convert;
+
+ if (color_quantize)
+ cinfo->cquantize->color_quantize = color_quantize;
+-
+- if (post_process_data)
+- cinfo->post->post_process_data = post_process_data;
+ }
+
+
+@@ -380,6 +362,12 @@ increment_simple_rowgroup_ctr(j_decompress_ptr cinfo, JDIMENSION rows)
+ {
+ JDIMENSION rows_left;
+ my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
++ my_master_ptr master = (my_master_ptr)cinfo->master;
++
++ if (master->using_merged_upsample && cinfo->max_v_samp_factor == 2) {
++ read_and_discard_scanlines(cinfo, rows);
++ return;
++ }
+
+ /* Increment the counter to the next row group after the skipped rows. */
+ main_ptr->rowgroup_ctr += rows / cinfo->max_v_samp_factor;
+@@ -410,11 +398,16 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ my_main_ptr main_ptr = (my_main_ptr)cinfo->main;
+ my_coef_ptr coef = (my_coef_ptr)cinfo->coef;
+ my_master_ptr master = (my_master_ptr)cinfo->master;
++ my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+ JDIMENSION i, x;
+ int y;
+ JDIMENSION lines_per_iMCU_row, lines_left_in_iMCU_row, lines_after_iMCU_row;
+ JDIMENSION lines_to_skip, lines_to_read;
+
++ /* Two-pass color quantization is not supported. */
++ if (cinfo->quantize_colors && cinfo->two_pass_quantize)
++ ERREXIT(cinfo, JERR_NOTIMPL);
++
+ if (cinfo->global_state != DSTATE_SCANNING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+@@ -472,13 +465,7 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ main_ptr->buffer_full = FALSE;
+ main_ptr->rowgroup_ctr = 0;
+ main_ptr->context_state = CTX_PREPARE_FOR_IMCU;
+- if (master->using_merged_upsample) {
+- my_merged_upsample_ptr upsample =
+- (my_merged_upsample_ptr)cinfo->upsample;
+- upsample->spare_full = FALSE;
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+- } else {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ if (!master->using_merged_upsample) {
+ upsample->next_row_out = cinfo->max_v_samp_factor;
+ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+ }
+@@ -493,13 +480,7 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ cinfo->output_scanline += lines_left_in_iMCU_row;
+ main_ptr->buffer_full = FALSE;
+ main_ptr->rowgroup_ctr = 0;
+- if (master->using_merged_upsample) {
+- my_merged_upsample_ptr upsample =
+- (my_merged_upsample_ptr)cinfo->upsample;
+- upsample->spare_full = FALSE;
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+- } else {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ if (!master->using_merged_upsample) {
+ upsample->next_row_out = cinfo->max_v_samp_factor;
+ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+ }
+@@ -537,14 +518,8 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ cinfo->output_iMCU_row += lines_to_skip / lines_per_iMCU_row;
+ increment_simple_rowgroup_ctr(cinfo, lines_to_read);
+ }
+- if (master->using_merged_upsample) {
+- my_merged_upsample_ptr upsample =
+- (my_merged_upsample_ptr)cinfo->upsample;
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+- } else {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
++ if (!master->using_merged_upsample)
+ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+- }
+ return num_lines;
+ }
+
+@@ -585,13 +560,8 @@ jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines)
+ * bit odd, since "rows_to_go" seems to be redundantly keeping track of
+ * output_scanline.
+ */
+- if (master->using_merged_upsample) {
+- my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
++ if (!master->using_merged_upsample)
+ upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+- } else {
+- my_upsample_ptr upsample = (my_upsample_ptr)cinfo->upsample;
+- upsample->rows_to_go = cinfo->output_height - cinfo->output_scanline;
+- }
+
+ /* Always skip the requested number of lines. */
+ return num_lines;
+diff --git a/libjpeg.txt b/libjpeg.txt
+index c50cf90..c233ecb 100644
+--- a/libjpeg.txt
++++ b/libjpeg.txt
+@@ -3,7 +3,7 @@ USING THE IJG JPEG LIBRARY
+ This file was part of the Independent JPEG Group's software:
+ Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding.
+ libjpeg-turbo Modifications:
+-Copyright (C) 2010, 2014-2018, D. R. Commander.
++Copyright (C) 2010, 2014-2018, 2020, D. R. Commander.
+ Copyright (C) 2015, Google, Inc.
+ For conditions of distribution and use, see the accompanying README.ijg file.
+
+@@ -750,7 +750,9 @@ multiple rows in the JPEG image.
+
+ Suspending data sources are not supported by this function. Calling
+ jpeg_skip_scanlines() with a suspending data source will result in undefined
+-behavior.
++behavior. Two-pass color quantization is also not supported by this function.
++Calling jpeg_skip_scanlines() with two-pass color quantization enabled will
++result in an error.
+
+ jpeg_skip_scanlines() will not allow skipping past the bottom of the image. If
+ the value of num_lines is large enough to skip past the bottom of the image,
+--
+2.25.1
+
diff --git a/meta/recipes-graphics/jpeg/files/CVE-2021-46822.patch b/meta/recipes-graphics/jpeg/files/CVE-2021-46822.patch
new file mode 100644
index 0000000000..68cf89e628
--- /dev/null
+++ b/meta/recipes-graphics/jpeg/files/CVE-2021-46822.patch
@@ -0,0 +1,133 @@
+From f35fd27ec641c42d6b115bfa595e483ec58188d2 Mon Sep 17 00:00:00 2001
+From: DRC <information@libjpeg-turbo.org>
+Date: Tue, 6 Apr 2021 12:51:03 -0500
+Subject: [PATCH] tjLoadImage: Fix issues w/loading 16-bit PPMs/PGMs
+
+- The PPM reader now throws an error rather than segfaulting (due to a
+ buffer overrun) if an application attempts to load a 16-bit PPM file
+ into a grayscale uncompressed image buffer. No known applications
+ allowed that (not even the test applications in libjpeg-turbo),
+ because that mode of operation was never expected to work and did not
+ work under any circumstances. (In fact, it was necessary to modify
+ TJBench in order to reproduce the issue outside of a fuzzing
+ environment.) This was purely a matter of making the library bow out
+ gracefully rather than crash if an application tries to do something
+ really stupid.
+
+- The PPM reader now throws an error rather than generating incorrect
+ pixels if an application attempts to load a 16-bit PGM file into an
+ RGB uncompressed image buffer.
+
+- The PPM reader now correctly loads 16-bit PPM files into extended
+ RGB uncompressed image buffers. (Previously it generated incorrect
+ pixels unless the input colorspace was JCS_RGB or JCS_EXT_RGB.)
+
+The only way that users could have potentially encountered these issues
+was through the tjLoadImage() function. cjpeg and TJBench were
+unaffected.
+
+CVE: CVE-2021-46822
+Upstream-Status: Backport [https://github.com/libjpeg-turbo/libjpeg-turbo/commit/f35fd27ec641c42d6b115bfa595e483ec58188d2.patch]
+Comment: Refreshed hunks from ChangeLog.md
+ Refreshed hunks from rdppm.c
+
+Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
+
+---
+ ChangeLog.md | 10 ++++++++++
+ rdppm.c | 26 ++++++++++++++++++++------
+ 2 files changed, 30 insertions(+), 6 deletions(-)
+
+diff --git a/ChangeLog.md b/ChangeLog.md
+index 968969c6b..12e730a0e 100644
+--- a/ChangeLog.md
++++ b/ChangeLog.md
+@@ -44,6 +44,15 @@
+ that maximum value was less than 255. libjpeg-turbo 1.5.0 already included a
+ similar fix for binary PPM/PGM files with maximum values greater than 255.
+
++7. The PPM reader now throws an error, rather than segfaulting (due to a buffer
++overrun) or generating incorrect pixels, if an application attempts to use the
++`tjLoadImage()` function to load a 16-bit binary PPM file (a binary PPM file
++with a maximum value greater than 255) into a grayscale image buffer or to load
++a 16-bit binary PGM file into an RGB image buffer.
++
++8. Fixed an issue in the PPM reader that caused incorrect pixels to be
++generated when using the `tjLoadImage()` function to load a 16-bit binary PPM
++file into an extended RGB image buffer.
+
+ 2.0.3
+ =====
+diff --git a/rdppm.c b/rdppm.c
+index c4c937e8a..6ac8fdbf7 100644
+--- a/rdppm.c
++++ b/rdppm.c
+@@ -5,7 +5,7 @@
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 2009 by Bill Allombert, Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+- * Copyright (C) 2015-2017, 2020, D. R. Commander.
++ * Copyright (C) 2015-2017, 2020-2021, D. R. Commander.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ *
+@@ -516,6 +516,11 @@ get_word_rgb_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+ register JSAMPLE *rescale = source->rescale;
+ JDIMENSION col;
+ unsigned int maxval = source->maxval;
++ register int rindex = rgb_red[cinfo->in_color_space];
++ register int gindex = rgb_green[cinfo->in_color_space];
++ register int bindex = rgb_blue[cinfo->in_color_space];
++ register int aindex = alpha_index[cinfo->in_color_space];
++ register int ps = rgb_pixelsize[cinfo->in_color_space];
+
+ if (!ReadOK(source->pub.input_file, source->iobuffer, source->buffer_width))
+ ERREXIT(cinfo, JERR_INPUT_EOF);
+@@ -527,17 +532,20 @@ get_word_rgb_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+ temp |= UCH(*bufferptr++);
+ if (temp > maxval)
+ ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
+- *ptr++ = rescale[temp];
++ ptr[rindex] = rescale[temp];
+ temp = UCH(*bufferptr++) << 8;
+ temp |= UCH(*bufferptr++);
+ if (temp > maxval)
+ ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
+- *ptr++ = rescale[temp];
++ ptr[gindex] = rescale[temp];
+ temp = UCH(*bufferptr++) << 8;
+ temp |= UCH(*bufferptr++);
+ if (temp > maxval)
+ ERREXIT(cinfo, JERR_PPM_OUTOFRANGE);
+- *ptr++ = rescale[temp];
++ ptr[bindex] = rescale[temp];
++ if (aindex >= 0)
++ ptr[aindex] = 0xFF;
++ ptr += ps;
+ }
+ return 1;
+ }
+@@ -624,7 +632,10 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
+ cinfo->in_color_space = JCS_GRAYSCALE;
+ TRACEMS2(cinfo, 1, JTRC_PGM, w, h);
+ if (maxval > 255) {
+- source->pub.get_pixel_rows = get_word_gray_row;
++ if (cinfo->in_color_space == JCS_GRAYSCALE)
++ source->pub.get_pixel_rows = get_word_gray_row;
++ else
++ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR) &&
+ cinfo->in_color_space == JCS_GRAYSCALE) {
+ source->pub.get_pixel_rows = get_raw_row;
+@@ -657,7 +657,10 @@
+ cinfo->in_color_space = JCS_EXT_RGB;
+ TRACEMS2(cinfo, 1, JTRC_PPM, w, h);
+ if (maxval > 255) {
+- source->pub.get_pixel_rows = get_word_rgb_row;
++ if (IsExtRGB(cinfo->in_color_space))
++ source->pub.get_pixel_rows = get_word_rgb_row;
++ else
++ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ } else if (maxval == MAXJSAMPLE && sizeof(JSAMPLE) == sizeof(U_CHAR) &&
+ (cinfo->in_color_space == JCS_EXT_RGB
+ #if RGB_RED == 0 && RGB_GREEN == 1 && RGB_BLUE == 2 && RGB_PIXELSIZE == 3
diff --git a/meta/recipes-graphics/jpeg/files/CVE-2023-2804-1.patch b/meta/recipes-graphics/jpeg/files/CVE-2023-2804-1.patch
new file mode 100644
index 0000000000..6668f6e41d
--- /dev/null
+++ b/meta/recipes-graphics/jpeg/files/CVE-2023-2804-1.patch
@@ -0,0 +1,97 @@
+From 9679473547874c472569d54fecce32b463999a9d Mon Sep 17 00:00:00 2001
+From: DRC <information@libjpeg-turbo.org>
+Date: Tue, 4 Apr 2023 19:06:20 -0500
+Subject: [PATCH] Decomp: Don't enable 2-pass color quant w/ RGB565
+
+The 2-pass color quantization algorithm assumes 3-sample pixels. RGB565
+is the only 3-component colorspace that doesn't have 3-sample pixels, so
+we need to treat it as a special case when determining whether to enable
+2-pass color quantization. Otherwise, attempting to initialize 2-pass
+color quantization with an RGB565 output buffer could cause
+prescan_quantize() to read from uninitialized memory and subsequently
+underflow/overflow the histogram array.
+
+djpeg is supposed to fail gracefully if both -rgb565 and -colors are
+specified, because none of its destination managers (image writers)
+support color quantization with RGB565. However, prescan_quantize() was
+called before that could occur. It is possible but very unlikely that
+these issues could have been reproduced in applications other than
+djpeg. The issues involve the use of two features (12-bit precision and
+RGB565) that are incompatible, and they also involve the use of two
+rarely-used legacy features (RGB565 and color quantization) that don't
+make much sense when combined.
+
+Fixes #668
+Fixes #671
+Fixes #680
+
+CVE: CVE-2023-2804
+Upstream-Status: Backport [https://github.com/libjpeg-turbo/libjpeg-turbo/commit/9679473547874c472569d54fecce32b463999a9d]
+
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ ChangeLog.md | 6 ++++++
+ jdmaster.c | 5 +++--
+ jquant2.c | 5 +++--
+ 3 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/ChangeLog.md b/ChangeLog.md
+index e605abe73..de0c4d0dd 100644
+--- a/ChangeLog.md
++++ b/ChangeLog.md
+@@ -1,3 +1,9 @@ quality values.
++9. Fixed an oversight in 1.4 beta1[8] that caused various segfaults and buffer
++overruns when attempting to decompress various specially-crafted malformed
++12-bit-per-component JPEG images using a 12-bit-per-component build of djpeg
++(`-DWITH_12BIT=1`) with both color quantization and RGB565 color conversion
++enabled.
++
+ 2.0.4
+ =====
+
+diff --git a/jdmaster.c b/jdmaster.c
+index b20906438..8d8ef9956 100644
+--- a/jdmaster.c
++++ b/jdmaster.c
+@@ -5,7 +5,7 @@
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 2002-2009 by Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+- * Copyright (C) 2009-2011, 2016, D. R. Commander.
++ * Copyright (C) 2009-2011, 2016, 2023, D. R. Commander.
+ * Copyright (C) 2013, Linaro Limited.
+ * Copyright (C) 2015, Google, Inc.
+ * For conditions of distribution and use, see the accompanying README.ijg
+@@ -492,7 +492,8 @@ master_selection(j_decompress_ptr cinfo)
+ if (cinfo->raw_data_out)
+ ERREXIT(cinfo, JERR_NOTIMPL);
+ /* 2-pass quantizer only works in 3-component color space. */
+- if (cinfo->out_color_components != 3) {
++ if (cinfo->out_color_components != 3 ||
++ cinfo->out_color_space == JCS_RGB565) {
+ cinfo->enable_1pass_quant = TRUE;
+ cinfo->enable_external_quant = FALSE;
+ cinfo->enable_2pass_quant = FALSE;
+diff --git a/jquant2.c b/jquant2.c
+index 6570613bb..c760380fb 100644
+--- a/jquant2.c
++++ b/jquant2.c
+@@ -4,7 +4,7 @@
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+- * Copyright (C) 2009, 2014-2015, D. R. Commander.
++ * Copyright (C) 2009, 2014-2015, 2020, 2023, D. R. Commander.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ *
+@@ -1230,7 +1230,8 @@ jinit_2pass_quantizer(j_decompress_ptr cinfo)
+ cquantize->error_limiter = NULL;
+
+ /* Make sure jdmaster didn't give me a case I can't handle */
+- if (cinfo->out_color_components != 3)
++ if (cinfo->out_color_components != 3 ||
++ cinfo->out_color_space == JCS_RGB565)
+ ERREXIT(cinfo, JERR_NOTIMPL);
+
+ /* Allocate the histogram/inverse colormap storage */
diff --git a/meta/recipes-graphics/jpeg/files/CVE-2023-2804-2.patch b/meta/recipes-graphics/jpeg/files/CVE-2023-2804-2.patch
new file mode 100644
index 0000000000..bcba0b513d
--- /dev/null
+++ b/meta/recipes-graphics/jpeg/files/CVE-2023-2804-2.patch
@@ -0,0 +1,75 @@
+From 0deab87e24ab3106d5332205f829d1846fa65001 Mon Sep 17 00:00:00 2001
+From: DRC <information@libjpeg-turbo.org>
+Date: Thu, 6 Apr 2023 18:33:41 -0500
+Subject: [PATCH] jpeg_crop_scanline: Fix calc w/sclg + 2x4,4x2 samp
+
+When computing the downsampled width for a particular component,
+jpeg_crop_scanline() needs to take into account the fact that the
+libjpeg code uses a combination of IDCT scaling and upsampling to
+implement 4x2 and 2x4 upsampling with certain decompression scaling
+factors. Failing to account for that led to incomplete upsampling of
+4x2- or 2x4-subsampled components, which caused the color converter to
+read from uninitialized memory. With 12-bit data precision, this caused
+a buffer overrun or underrun and subsequent segfault if the
+uninitialized memory contained a value that was outside of the valid
+sample range (because the color converter uses the value as an array
+index.)
+
+Fixes #669
+
+CVE: CVE-2023-2804
+Upstream-Status: Backport [https://github.com/libjpeg-turbo/libjpeg-turbo/commit/0deab87e24ab3106d5332205f829d1846fa65001]
+
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ ChangeLog.md | 8 ++++++++
+ jdapistd.c | 10 ++++++----
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/ChangeLog.md b/ChangeLog.md
+index de0c4d0dd..159bd1610 100644
+--- a/ChangeLog.md
++++ b/ChangeLog.md
+@@ -4,6 +4,14 @@ overruns when attempting to decompress various specially-crafted malformed
+ (`-DWITH_12BIT=1`) with both color quantization and RGB565 color conversion
+ enabled.
+
++10. Fixed an issue whereby `jpeg_crop_scanline()` sometimes miscalculated the
++downsampled width for components with 4x2 or 2x4 subsampling factors if
++decompression scaling was enabled. This caused the components to be upsampled
++incompletely, which caused the color converter to read from uninitialized
++memory. With 12-bit data precision, this caused a buffer overrun or underrun
++and subsequent segfault if the sample value read from unitialized memory was
++outside of the valid sample range.
++
+ 2.0.4
+ =====
+
+diff --git a/jdapistd.c b/jdapistd.c
+index 628626254..eb577928c 100644
+--- a/jdapistd.c
++++ b/jdapistd.c
+@@ -4,7 +4,7 @@
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * libjpeg-turbo Modifications:
+- * Copyright (C) 2010, 2015-2018, 2020, D. R. Commander.
++ * Copyright (C) 2010, 2015-2018, 2020, 2023, D. R. Commander.
+ * Copyright (C) 2015, Google, Inc.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+@@ -225,9 +225,11 @@ jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
+ /* Set downsampled_width to the new output width. */
+ orig_downsampled_width = compptr->downsampled_width;
+ compptr->downsampled_width =
+- (JDIMENSION)jdiv_round_up((long)(cinfo->output_width *
+- compptr->h_samp_factor),
+- (long)cinfo->max_h_samp_factor);
++ (JDIMENSION)jdiv_round_up((long)cinfo->output_width *
++ (long)(compptr->h_samp_factor *
++ compptr->_DCT_scaled_size),
++ (long)(cinfo->max_h_samp_factor *
++ cinfo->_min_DCT_scaled_size));
+ if (compptr->downsampled_width < 2 && orig_downsampled_width >= 2)
+ reinit_upsampler = TRUE;
+