mirror of
https://github.com/openharmony/third_party_libpng.git
synced 2026-07-01 09:25:04 -04:00
漏洞修复CVE-2025-64505、CVE-2025-64506、CVE-2025-64720、CVE-2025-65018
Signed-off-by: zhwang0 <zhwang0@163.com>
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
diff --git a/pngrtran.c b/pngrtran.c
|
||||
index 1526123..072db9a 100644
|
||||
--- a/pngrtran.c
|
||||
+++ b/pngrtran.c
|
||||
@@ -439,9 +439,19 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
|
||||
{
|
||||
int i;
|
||||
|
||||
+ /* Initialize the array to index colors.
|
||||
+ *
|
||||
+ * Ensure quantize_index can fit 256 elements (PNG_MAX_PALETTE_LENGTH)
|
||||
+ * rather than num_palette elements. This is to prevent buffer overflows
|
||||
+ * caused by malformed PNG files with out-of-range palette indices.
|
||||
+ *
|
||||
+ * Be careful to avoid leaking memory. Applications are allowed to call
|
||||
+ * this function more than once per png_struct.
|
||||
+ */
|
||||
+ png_free(png_ptr, png_ptr->quantize_index);
|
||||
png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
|
||||
- (png_alloc_size_t)num_palette);
|
||||
- for (i = 0; i < num_palette; i++)
|
||||
+ PNG_MAX_PALETTE_LENGTH);
|
||||
+ for (i = 0; i < PNG_MAX_PALETTE_LENGTH; i++)
|
||||
png_ptr->quantize_index[i] = (png_byte)i;
|
||||
}
|
||||
|
||||
@@ -453,15 +463,15 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
|
||||
* Perhaps not the best solution, but good enough.
|
||||
*/
|
||||
|
||||
- int i;
|
||||
+ png_bytep quantize_sort;
|
||||
+ int i, j;
|
||||
|
||||
- /* Initialize an array to sort colors */
|
||||
- png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
|
||||
+ /* Initialize the local array to sort colors. */
|
||||
+ quantize_sort = (png_bytep)png_malloc(png_ptr,
|
||||
(png_alloc_size_t)num_palette);
|
||||
|
||||
- /* Initialize the quantize_sort array */
|
||||
for (i = 0; i < num_palette; i++)
|
||||
- png_ptr->quantize_sort[i] = (png_byte)i;
|
||||
+ quantize_sort[i] = (png_byte)i;
|
||||
|
||||
/* Find the least used palette entries by starting a
|
||||
* bubble sort, and running it until we have sorted
|
||||
@@ -473,19 +483,18 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
|
||||
for (i = num_palette - 1; i >= maximum_colors; i--)
|
||||
{
|
||||
int done; /* To stop early if the list is pre-sorted */
|
||||
- int j;
|
||||
|
||||
done = 1;
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
- if (histogram[png_ptr->quantize_sort[j]]
|
||||
- < histogram[png_ptr->quantize_sort[j + 1]])
|
||||
+ if (histogram[quantize_sort[j]]
|
||||
+ < histogram[quantize_sort[j + 1]])
|
||||
{
|
||||
png_byte t;
|
||||
|
||||
- t = png_ptr->quantize_sort[j];
|
||||
- png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
|
||||
- png_ptr->quantize_sort[j + 1] = t;
|
||||
+ t = quantize_sort[j];
|
||||
+ quantize_sort[j] = quantize_sort[j + 1];
|
||||
+ quantize_sort[j + 1] = t;
|
||||
done = 0;
|
||||
}
|
||||
}
|
||||
@@ -497,18 +506,18 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
|
||||
/* Swap the palette around, and set up a table, if necessary */
|
||||
if (full_quantize != 0)
|
||||
{
|
||||
- int j = num_palette;
|
||||
+ j = num_palette;
|
||||
|
||||
/* Put all the useful colors within the max, but don't
|
||||
* move the others.
|
||||
*/
|
||||
for (i = 0; i < maximum_colors; i++)
|
||||
{
|
||||
- if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
|
||||
+ if ((int)quantize_sort[i] >= maximum_colors)
|
||||
{
|
||||
do
|
||||
j--;
|
||||
- while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
|
||||
+ while ((int)quantize_sort[j] >= maximum_colors);
|
||||
|
||||
palette[i] = palette[j];
|
||||
}
|
||||
@@ -516,7 +525,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
|
||||
}
|
||||
else
|
||||
{
|
||||
- int j = num_palette;
|
||||
+ j = num_palette;
|
||||
|
||||
/* Move all the used colors inside the max limit, and
|
||||
* develop a translation table.
|
||||
@@ -524,13 +533,13 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
|
||||
for (i = 0; i < maximum_colors; i++)
|
||||
{
|
||||
/* Only move the colors we need to */
|
||||
- if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
|
||||
+ if ((int)quantize_sort[i] >= maximum_colors)
|
||||
{
|
||||
png_color tmp_color;
|
||||
|
||||
do
|
||||
j--;
|
||||
- while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
|
||||
+ while ((int)quantize_sort[j] >= maximum_colors);
|
||||
|
||||
tmp_color = palette[j];
|
||||
palette[j] = palette[i];
|
||||
@@ -568,8 +577,8 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
|
||||
}
|
||||
}
|
||||
}
|
||||
- png_free(png_ptr, png_ptr->quantize_sort);
|
||||
- png_ptr->quantize_sort = NULL;
|
||||
+ png_free(png_ptr, quantize_sort);
|
||||
+
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4925,13 +4934,8 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
|
||||
|
||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
||||
if ((png_ptr->transformations & PNG_QUANTIZE) != 0)
|
||||
- {
|
||||
png_do_quantize(row_info, png_ptr->row_buf + 1,
|
||||
png_ptr->palette_lookup, png_ptr->quantize_index);
|
||||
-
|
||||
- if (row_info->rowbytes == 0)
|
||||
- png_error(png_ptr, "png_do_quantize returned rowbytes=0");
|
||||
- }
|
||||
#endif /* READ_QUANTIZE */
|
||||
|
||||
#ifdef PNG_READ_EXPAND_16_SUPPORTED
|
||||
diff --git a/pngstruct.h b/pngstruct.h
|
||||
index 7c38464..105a6c1 100644
|
||||
--- a/pngstruct.h
|
||||
+++ b/pngstruct.h
|
||||
@@ -421,7 +421,6 @@ struct png_struct_def
|
||||
|
||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
||||
/* The following three members were added at version 1.0.14 and 1.2.4 */
|
||||
- png_bytep quantize_sort; /* working sort array */
|
||||
png_bytep index_to_palette; /* where the original index currently is
|
||||
in the palette */
|
||||
png_bytep palette_to_index; /* which original index points to this
|
||||
--
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
diff --git a/pngwrite.c b/pngwrite.c
|
||||
index 923a0b0..cb72816 100644
|
||||
--- a/pngwrite.c
|
||||
+++ b/pngwrite.c
|
||||
@@ -2132,8 +2132,7 @@ png_image_write_main(png_voidp argument)
|
||||
* before it is written. This only applies when the input is 16-bit and
|
||||
* either there is an alpha channel or it is converted to 8-bit.
|
||||
*/
|
||||
- if ((linear != 0 && alpha != 0 ) ||
|
||||
- (colormap == 0 && display->convert_to_8bit != 0))
|
||||
+ if (linear != 0 && (alpha != 0 || display->convert_to_8bit != 0))
|
||||
{
|
||||
png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
|
||||
png_get_rowbytes(png_ptr, info_ptr)));
|
||||
--
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
diff --git a/pngrtran.c b/pngrtran.c
|
||||
index 072db9a..dbfeac8 100644
|
||||
--- a/pngrtran.c
|
||||
+++ b/pngrtran.c
|
||||
@@ -1699,19 +1699,51 @@ png_init_read_transformations(png_structrp png_ptr)
|
||||
}
|
||||
else /* if (png_ptr->trans_alpha[i] != 0xff) */
|
||||
{
|
||||
- png_byte v, w;
|
||||
-
|
||||
- v = png_ptr->gamma_to_1[palette[i].red];
|
||||
- png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
|
||||
- palette[i].red = png_ptr->gamma_from_1[w];
|
||||
-
|
||||
- v = png_ptr->gamma_to_1[palette[i].green];
|
||||
- png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
|
||||
- palette[i].green = png_ptr->gamma_from_1[w];
|
||||
-
|
||||
- v = png_ptr->gamma_to_1[palette[i].blue];
|
||||
- png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
|
||||
- palette[i].blue = png_ptr->gamma_from_1[w];
|
||||
+ if ((png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0)
|
||||
+ {
|
||||
+ /* Premultiply only:
|
||||
+ * component = round((component * alpha) / 255)
|
||||
+ */
|
||||
+ png_uint_32 component;
|
||||
+
|
||||
+ component = png_ptr->gamma_to_1[palette[i].red];
|
||||
+ component =
|
||||
+ (component * png_ptr->trans_alpha[i] + 128) / 255;
|
||||
+ palette[i].red = png_ptr->gamma_from_1[component];
|
||||
+
|
||||
+ component = png_ptr->gamma_to_1[palette[i].green];
|
||||
+ component =
|
||||
+ (component * png_ptr->trans_alpha[i] + 128) / 255;
|
||||
+ palette[i].green = png_ptr->gamma_from_1[component];
|
||||
+
|
||||
+ component = png_ptr->gamma_to_1[palette[i].blue];
|
||||
+ component =
|
||||
+ (component * png_ptr->trans_alpha[i] + 128) / 255;
|
||||
+ palette[i].blue = png_ptr->gamma_from_1[component];
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* Composite with background color:
|
||||
+ * component =
|
||||
+ * alpha * component + (1 - alpha) * background
|
||||
+ */
|
||||
+ png_byte v, w;
|
||||
+
|
||||
+ v = png_ptr->gamma_to_1[palette[i].red];
|
||||
+ png_composite(w, v,
|
||||
+ png_ptr->trans_alpha[i], back_1.red);
|
||||
+ palette[i].red = png_ptr->gamma_from_1[w];
|
||||
+
|
||||
+ v = png_ptr->gamma_to_1[palette[i].green];
|
||||
+ png_composite(w, v,
|
||||
+ png_ptr->trans_alpha[i], back_1.green);
|
||||
+ palette[i].green = png_ptr->gamma_from_1[w];
|
||||
+
|
||||
+ v = png_ptr->gamma_to_1[palette[i].blue];
|
||||
+ png_composite(w, v,
|
||||
+ png_ptr->trans_alpha[i], back_1.blue);
|
||||
+ palette[i].blue = png_ptr->gamma_from_1[w];
|
||||
+ }
|
||||
}
|
||||
}
|
||||
else
|
||||
--
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
diff --git a/pngread.c b/pngread.c
|
||||
index a7a644e..7f9c5de 100644
|
||||
--- a/pngread.c
|
||||
+++ b/pngread.c
|
||||
@@ -3521,6 +3521,54 @@ png_image_read_colormapped(png_voidp argument)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Row reading for interlaced 16-to-8 bit depth conversion with local buffer. */
|
||||
+static int
|
||||
+png_image_read_direct_scaled(png_voidp argument)
|
||||
+{
|
||||
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
|
||||
+ argument);
|
||||
+ png_imagep image = display->image;
|
||||
+ png_structrp png_ptr = image->opaque->png_ptr;
|
||||
+ png_bytep local_row = png_voidcast(png_bytep, display->local_row);
|
||||
+ png_bytep first_row = png_voidcast(png_bytep, display->first_row);
|
||||
+ ptrdiff_t row_bytes = display->row_bytes;
|
||||
+ int passes;
|
||||
+
|
||||
+ /* Handle interlacing. */
|
||||
+ switch (png_ptr->interlaced)
|
||||
+ {
|
||||
+ case PNG_INTERLACE_NONE:
|
||||
+ passes = 1;
|
||||
+ break;
|
||||
+
|
||||
+ case PNG_INTERLACE_ADAM7:
|
||||
+ passes = PNG_INTERLACE_ADAM7_PASSES;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ png_error(png_ptr, "unknown interlace type");
|
||||
+ }
|
||||
+
|
||||
+ /* Read each pass using local_row as intermediate buffer. */
|
||||
+ while (--passes >= 0)
|
||||
+ {
|
||||
+ png_uint_32 y = image->height;
|
||||
+ png_bytep output_row = first_row;
|
||||
+
|
||||
+ for (; y > 0; --y)
|
||||
+ {
|
||||
+ /* Read into local_row (gets transformed 8-bit data). */
|
||||
+ png_read_row(png_ptr, local_row, NULL);
|
||||
+
|
||||
+ /* Copy from local_row to user buffer. */
|
||||
+ memcpy(output_row, local_row, (size_t)row_bytes);
|
||||
+ output_row += row_bytes;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/* Just the row reading part of png_image_read. */
|
||||
static int
|
||||
png_image_read_composite(png_voidp argument)
|
||||
@@ -3942,6 +3990,7 @@ png_image_read_direct(png_voidp argument)
|
||||
int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
|
||||
int do_local_compose = 0;
|
||||
int do_local_background = 0; /* to avoid double gamma correction bug */
|
||||
+ int do_local_scale = 0; /* for interlaced 16-to-8 bit conversion */
|
||||
int passes = 0;
|
||||
|
||||
/* Add transforms to ensure the correct output format is produced then check
|
||||
@@ -4068,8 +4117,16 @@ png_image_read_direct(png_voidp argument)
|
||||
png_set_expand_16(png_ptr);
|
||||
|
||||
else /* 8-bit output */
|
||||
+ {
|
||||
png_set_scale_16(png_ptr);
|
||||
|
||||
+ /* For interlaced images, use local_row buffer to avoid overflow
|
||||
+ * in png_combine_row() which writes using IHDR bit-depth.
|
||||
+ */
|
||||
+ if (png_ptr->interlaced != 0)
|
||||
+ do_local_scale = 1;
|
||||
+ }
|
||||
+
|
||||
change &= ~PNG_FORMAT_FLAG_LINEAR;
|
||||
}
|
||||
|
||||
@@ -4345,6 +4402,24 @@ png_image_read_direct(png_voidp argument)
|
||||
return result;
|
||||
}
|
||||
|
||||
+ else if (do_local_scale != 0)
|
||||
+ {
|
||||
+ /* For interlaced 16-to-8 conversion, use an intermediate row buffer
|
||||
+ * to avoid buffer overflows in png_combine_row. The local_row is sized
|
||||
+ * for the transformed (8-bit) output, preventing the overflow that would
|
||||
+ * occur if png_combine_row wrote 16-bit data directly to the user buffer.
|
||||
+ */
|
||||
+ int result;
|
||||
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
|
||||
+
|
||||
+ display->local_row = row;
|
||||
+ result = png_safe_execute(image, png_image_read_direct_scaled, display);
|
||||
+ display->local_row = NULL;
|
||||
+ png_free(png_ptr, row);
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
else
|
||||
{
|
||||
png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes;
|
||||
--
|
||||
|
||||
+10
-2
@@ -38,7 +38,11 @@ def move_file(src_path, dst_path):
|
||||
"backport-libpng-1.6.37-enable-valid.patch",
|
||||
"pnglibconf.h",
|
||||
"CVE-2018-14048.patch",
|
||||
"libpng_optimize.patch"
|
||||
"libpng_optimize.patch",
|
||||
"CVE-2025-64505.patch",
|
||||
"CVE-2025-64506.patch",
|
||||
"CVE-2025-64720.patch",
|
||||
"CVE-2025-65018.patch"
|
||||
]
|
||||
for file in files:
|
||||
src_file = os.path.join(src_path, file)
|
||||
@@ -64,7 +68,11 @@ def do_patch(target_dir):
|
||||
"libpng-multilib.patch",
|
||||
"backport-libpng-1.6.37-enable-valid.patch",
|
||||
"CVE-2018-14048.patch",
|
||||
"libpng_optimize.patch"
|
||||
"libpng_optimize.patch",
|
||||
"CVE-2025-64505.patch",
|
||||
"CVE-2025-64506.patch",
|
||||
"CVE-2025-64720.patch",
|
||||
"CVE-2025-65018.patch"
|
||||
]
|
||||
|
||||
for patch in patch_file:
|
||||
|
||||
Reference in New Issue
Block a user