[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[freetype2] master dbf9142 67/68: [sfnt] Fix crash in `Load_SBit_Png` on
From: |
Werner Lemberg |
Subject: |
[freetype2] master dbf9142 67/68: [sfnt] Fix crash in `Load_SBit_Png` on Windows x64. |
Date: |
Fri, 5 Mar 2021 09:29:46 -0500 (EST) |
branch: master
commit dbf9142f7e0432c9ed618b3276e2b61fa39e7262
Author: Jesse Towner <townerj@gmail.com>
Commit: Werner Lemberg <wl@gnu.org>
[sfnt] Fix crash in `Load_SBit_Png` on Windows x64.
This change fixes a crash that occurs in `Load_SBit_Png` when
running on a 64-bit Windows OS. A memory access violation exception
would be raised by `setjmp` if the `jmp_buf` is not aligned to a
16-byte memory boundary. This is due to setjmp executing `movdqa`
instructions to store 128-bit XMM registers to memory, which require
correct memory alignment. This problem occurs because
`png_create_read_struct` uses `malloc` and `free` for memory
management, which only guarantees 8-byte alignment on Windows.
Instead, to fix the problem, `png_create_read_struct_2` is used on
64-bit Windows, which allows for user-defined memory allocation and
deallocation callbacks to be specified. These callbacks forward the
allocation and deallocation requests to `_aligned_alloc` and
`_aligned_free`, ensuring that the allocated `png_struct` and
internal `jmp_buf` have the requisite 16-byte alignment.
* src/sfnt/pngshim.c <_WIN64>: Include `malloc.h`.
(malloc_callback, free_callback) <_WIN64>: New functions.
(Load_SBit_Png) <_WIN64>: Use `png_create_read_struct_2` instead of
`png_create_read_struct`
---
ChangeLog | 25 +++++++++++++++++++++++++
src/sfnt/pngshim.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index 7945b1e..3c522d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2021-02-27 Jesse Towner <townerj@gmail.com>
+
+ [sfnt] Fix crash in `Load_SBit_Png` on Windows x64.
+
+ This change fixes a crash that occurs in `Load_SBit_Png` when
+ running on a 64-bit Windows OS. A memory access violation exception
+ would be raised by `setjmp` if the `jmp_buf` is not aligned to a
+ 16-byte memory boundary. This is due to setjmp executing `movdqa`
+ instructions to store 128-bit XMM registers to memory, which require
+ correct memory alignment. This problem occurs because
+ `png_create_read_struct` uses `malloc` and `free` for memory
+ management, which only guarantees 8-byte alignment on Windows.
+
+ Instead, to fix the problem, `png_create_read_struct_2` is used on
+ 64-bit Windows, which allows for user-defined memory allocation and
+ deallocation callbacks to be specified. These callbacks forward the
+ allocation and deallocation requests to `_aligned_alloc` and
+ `_aligned_free`, ensuring that the allocated `png_struct` and
+ internal `jmp_buf` have the requisite 16-byte alignment.
+
+ * src/sfnt/pngshim.c <_WIN64>: Include `malloc.h`.
+ (malloc_callback, free_callback) <_WIN64>: New functions.
+ (Load_SBit_Png) <_WIN64>: Use `png_create_read_struct_2` instead of
+ `png_create_read_struct`
+
2021-02-25 Werner Lemberg <wl@gnu.org>
[woff2] Fix memory leak.
diff --git a/src/sfnt/pngshim.c b/src/sfnt/pngshim.c
index c7a2938..2973b9a 100644
--- a/src/sfnt/pngshim.c
+++ b/src/sfnt/pngshim.c
@@ -33,6 +33,16 @@
#include "sferrors.h"
+ /* Use _aligned_malloc / _aligned_free on 64-bit Windows to ensure that */
+ /* the jmp_buf needed for ft_setjmp is aligned to a 16-byte boundary. */
+ /* If the jmp_buf is not aligned to a 16-byte boundary then a memory */
+ /* access violation exception will occur upon ft_setjmp being called. */
+#ifdef _WIN64
+#ifndef PNG_USER_MEM_SUPPORTED
+#error "libpng user-defined memory allocation is required for 64-bit Windows"
+#endif
+#include <malloc.h>
+#endif
/* This code is freely based on cairo-png.c. There's so many ways */
/* to call libpng, and the way cairo does it is defacto standard. */
@@ -221,6 +231,32 @@
}
+#ifdef _WIN64
+
+ /* Memory allocation callback to ensure that the jmp_buf that is stored */
+ /* within the png_struct has 16-byte alignment for 64-bit Windows. */
+ static png_voidp
+ malloc_callback( png_structp png,
+ png_alloc_size_t size )
+ {
+ FT_UNUSED( png );
+ return _aligned_malloc( size, 16 );
+ }
+
+
+ /* Memory deallocation callback to release memory that was allocated */
+ /* with the matching memory allocation callback above. */
+ static void
+ free_callback( png_structp png,
+ png_voidp ptr )
+ {
+ FT_UNUSED( png );
+ _aligned_free( ptr );
+ }
+
+#endif /* _WIN64 */
+
+
static void
read_data_from_FT_Stream( png_structp png,
png_bytep data,
@@ -292,10 +328,20 @@
FT_Stream_OpenMemory( &stream, data, png_len );
+#ifdef _WIN64
+ png = png_create_read_struct_2( PNG_LIBPNG_VER_STRING,
+ &error,
+ error_callback,
+ warning_callback,
+ NULL,
+ malloc_callback,
+ free_callback );
+#else
png = png_create_read_struct( PNG_LIBPNG_VER_STRING,
&error,
error_callback,
warning_callback );
+#endif
if ( !png )
{
error = FT_THROW( Out_Of_Memory );
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [freetype2] master dbf9142 67/68: [sfnt] Fix crash in `Load_SBit_Png` on Windows x64.,
Werner Lemberg <=