Fixed bug #78333
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 29 Jul 2019 09:23:26 +0000 (11:23 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 29 Jul 2019 09:25:27 +0000 (11:25 +0200)
Don't dereference float/double values at unknown address, instead
memcpy it into an aligned stack slot and dereference that.

NEWS
ext/exif/exif.c

diff --git a/NEWS b/NEWS
index bb4dc2a5f52de4f78799afea3ac79d5a996c1c0e..e37a9bc8fe6e20d9e2960c0a6ac5d4a811a5c69c 100644 (file)
--- 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)
 
index 6f91dda8c24a4674d84579cc6227b9d7522ca7b9..3e06b6c9d0700968574321db6aaa8d28f6c1e710 100644 (file)
@@ -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;
                                }
                        }