From d142dfc93d71bb387c19a06f77c265e89fc9d516 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 29 Jul 2019 11:23:26 +0200 Subject: [PATCH] Fixed bug #78333 Don't dereference float/double values at unknown address, instead memcpy it into an aligned stack slot and dereference that. --- NEWS | 4 ++++ ext/exif/exif.c | 26 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index bb4dc2a5f5..e37a9bc8fe 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fixed bug #77946 (Bad cURL resources returned by curl_multi_info_read()). (Abyr Valg) +- Exif: + . Fixed bug #78333 (Exif crash (bus error) due to wrong alignment and + invalid cast). (Nikita) + - LiteSpeed: . Updated to LiteSpeed SAPI V7.5 (Fixed clean shutdown). (George Wang) diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 6f91dda8c2..3e06b6c9d0 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -1541,6 +1541,20 @@ static void php_ifd_set32u(char *data, size_t value, int motorola_intel) } /* }}} */ +static float php_ifd_get_float(char *data) { + /* Copy to avoid alignment issues */ + float f; + memcpy(&f, data, sizeof(float)); + return f; +} + +static double php_ifd_get_double(char *data) { + /* Copy to avoid alignment issues */ + double f; + memcpy(&f, data, sizeof(double)); + return f; +} + #ifdef EXIF_DEBUG char * exif_dump_data(int *dump_free, int format, int components, int length, int motorola_intel, char *value_ptr) /* {{{ */ { @@ -1653,12 +1667,12 @@ static double exif_convert_any_format(void *value, int format, int motorola_inte #ifdef EXIF_DEBUG php_error_docref(NULL, E_NOTICE, "Found value of type single"); #endif - return (double)*(float *)value; + return (double) php_ifd_get_float(value); case TAG_FMT_DOUBLE: #ifdef EXIF_DEBUG php_error_docref(NULL, E_NOTICE, "Found value of type double"); #endif - return *(double *)value; + return php_ifd_get_double(value); } return 0; } @@ -1716,12 +1730,12 @@ static size_t exif_convert_any_to_int(void *value, int format, int motorola_inte #ifdef EXIF_DEBUG php_error_docref(NULL, E_NOTICE, "Found value of type single"); #endif - return (size_t)*(float *)value; + return (size_t) php_ifd_get_float(value); case TAG_FMT_DOUBLE: #ifdef EXIF_DEBUG php_error_docref(NULL, E_NOTICE, "Found value of type double"); #endif - return (size_t)*(double *)value; + return (size_t) php_ifd_get_double(value); } return 0; } @@ -2188,13 +2202,13 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c #ifdef EXIF_DEBUG php_error_docref(NULL, E_WARNING, "Found value of type single"); #endif - info_value->f = *(float *)value; + info_value->f = php_ifd_get_float(value); break; case TAG_FMT_DOUBLE: #ifdef EXIF_DEBUG php_error_docref(NULL, E_WARNING, "Found value of type double"); #endif - info_value->d = *(double *)value; + info_value->d = php_ifd_get_double(value); break; } } -- 2.40.0