]> granicus.if.org Git - php/commitdiff
Fix #80216: imap_mail_compose() does not validate types/encodings
authorChristoph M. Becker <cmbecker69@gmx.de>
Mon, 12 Oct 2020 12:04:18 +0000 (14:04 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Mon, 12 Oct 2020 14:27:49 +0000 (16:27 +0200)
We need to check whether the given `type`s and `encoding`s are within
bounds to avoid segfaults and out-of-bound reads.

Closes GH-6323.

NEWS
ext/imap/php_imap.c
ext/imap/tests/bug80216.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 368199ed74cbef8dac414c3e49edd4b7d48b051d..6e1a2f78572b569b1ed52bdbe137c1c40b9a9a3d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@ PHP                                                                        NEWS
   . Fixed bug #80220 (imap_mail_compose() may leak memory). (cmb)
   . Fixed bug #80223 (imap_mail_compose() leaks envelope on malformed bodies).
     (cmb)
+  . Fixed bug #80216 (imap_mail_compose() does not validate types/encodings).
+    (cmb)
 
 - MySQLnd:
   . Fixed bug #80115 (mysqlnd.debug doesn't recognize absolute paths with
index 63b5464808a12de3eab45ca24344f3180b45451e..5f05a0c359c34c8f9135f7ac58c835c3dff3797d 100644 (file)
@@ -3631,10 +3631,16 @@ PHP_FUNCTION(imap_mail_compose)
                        topbod = bod;
 
                        if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "type", sizeof("type") - 1)) != NULL) {
-                               bod->type = (short) zval_get_long(pvalue);
+                               zend_long type = zval_get_long(pvalue);
+                               if (type >= 0 && type <= TYPEMAX && body_types[type] != NULL) {
+                                       bod->type = (short) type;
+                               }
                        }
                        if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "encoding", sizeof("encoding") - 1)) != NULL) {
-                               bod->encoding = (short) zval_get_long(pvalue);
+                               zend_long encoding = zval_get_long(pvalue);
+                               if (encoding >= 0 && encoding <= ENCMAX && body_encodings[encoding] != NULL) {
+                                       bod->encoding = (short) encoding;
+                               }
                        }
                        if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
                                convert_to_string_ex(pvalue);
@@ -3716,10 +3722,13 @@ PHP_FUNCTION(imap_mail_compose)
                                bod->md5 = cpystr(Z_STRVAL_P(pvalue));
                        }
                } else if (Z_TYPE_P(data) == IS_ARRAY && topbod->type == TYPEMULTIPART) {
-                       short type = -1;
+                       short type = 0;
                        SEPARATE_ARRAY(data);
                        if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "type", sizeof("type") - 1)) != NULL) {
-                               type = (short) zval_get_long(pvalue);
+                               zend_long tmp_type = zval_get_long(pvalue);
+                               if (tmp_type >= 0 && tmp_type <= TYPEMAX && tmp_type != TYPEMULTIPART && body_types[tmp_type] != NULL) {
+                                       type = (short) tmp_type;
+                               }
                        }
 
                        if (!toppart) {
@@ -3732,13 +3741,13 @@ PHP_FUNCTION(imap_mail_compose)
                        }
 
                        bod = &mypart->body;
-
-                       if (type != TYPEMULTIPART) {
-                               bod->type = type;
-                       }
+                       bod->type = type;
 
                        if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "encoding", sizeof("encoding") - 1)) != NULL) {
-                               bod->encoding = (short) zval_get_long(pvalue);
+                               zend_long encoding = zval_get_long(pvalue);
+                               if (encoding >= 0 && encoding <= ENCMAX && body_encodings[encoding] != NULL) {
+                                       bod->encoding = (short) encoding;
+                               }
                        }
                        if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
                                convert_to_string_ex(pvalue);
diff --git a/ext/imap/tests/bug80216.phpt b/ext/imap/tests/bug80216.phpt
new file mode 100644 (file)
index 0000000..ccaf1e1
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #80216 (imap_mail_compose() does not validate types/encodings)
+--SKIPIF--
+<?php
+if (!extension_loaded('imap')) die('skip imap extension not available');
+?>
+--FILE--
+<?php
+imap_mail_compose([], [['type' => TYPEMULTIPART], []]);
+imap_mail_compose([], [['type' => 12]]);
+imap_mail_compose([], [['type' => TYPEMULTIPART], ['type' => 12]]);
+imap_mail_compose([], [['encoding' => 8]]);
+imap_mail_compose([], [['type' => TYPEMULTIPART], ['encoding' => 8]]);
+echo "done\n";
+?>
+--EXPECT--
+done