Skip to content

Commit 73e43b6

Browse files
committed
Fix #80216: imap_mail_compose() does not validate types/encodings
We need to check whether the given `type`s and `encoding`s are within bounds to avoid segfaults and out-of-bound reads. Closes phpGH-6323.
1 parent c1962e9 commit 73e43b6

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ PHP NEWS
1515
. Fixed bug #80220 (imap_mail_compose() may leak memory). (cmb)
1616
. Fixed bug #80223 (imap_mail_compose() leaks envelope on malformed bodies).
1717
(cmb)
18+
. Fixed bug #80216 (imap_mail_compose() does not validate types/encodings).
19+
(cmb)
1820

1921
- MySQLnd:
2022
. Fixed bug #80115 (mysqlnd.debug doesn't recognize absolute paths with

ext/imap/php_imap.c

+18-9
Original file line numberDiff line numberDiff line change
@@ -3631,10 +3631,16 @@ PHP_FUNCTION(imap_mail_compose)
36313631
topbod = bod;
36323632

36333633
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "type", sizeof("type") - 1)) != NULL) {
3634-
bod->type = (short) zval_get_long(pvalue);
3634+
zend_long type = zval_get_long(pvalue);
3635+
if (type >= 0 && type <= TYPEMAX && body_types[type] != NULL) {
3636+
bod->type = (short) type;
3637+
}
36353638
}
36363639
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "encoding", sizeof("encoding") - 1)) != NULL) {
3637-
bod->encoding = (short) zval_get_long(pvalue);
3640+
zend_long encoding = zval_get_long(pvalue);
3641+
if (encoding >= 0 && encoding <= ENCMAX && body_encodings[encoding] != NULL) {
3642+
bod->encoding = (short) encoding;
3643+
}
36383644
}
36393645
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
36403646
convert_to_string_ex(pvalue);
@@ -3716,10 +3722,13 @@ PHP_FUNCTION(imap_mail_compose)
37163722
bod->md5 = cpystr(Z_STRVAL_P(pvalue));
37173723
}
37183724
} else if (Z_TYPE_P(data) == IS_ARRAY && topbod->type == TYPEMULTIPART) {
3719-
short type = -1;
3725+
short type = 0;
37203726
SEPARATE_ARRAY(data);
37213727
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "type", sizeof("type") - 1)) != NULL) {
3722-
type = (short) zval_get_long(pvalue);
3728+
zend_long tmp_type = zval_get_long(pvalue);
3729+
if (tmp_type >= 0 && tmp_type <= TYPEMAX && tmp_type != TYPEMULTIPART && body_types[tmp_type] != NULL) {
3730+
type = (short) tmp_type;
3731+
}
37233732
}
37243733

37253734
if (!toppart) {
@@ -3732,13 +3741,13 @@ PHP_FUNCTION(imap_mail_compose)
37323741
}
37333742

37343743
bod = &mypart->body;
3735-
3736-
if (type != TYPEMULTIPART) {
3737-
bod->type = type;
3738-
}
3744+
bod->type = type;
37393745

37403746
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "encoding", sizeof("encoding") - 1)) != NULL) {
3741-
bod->encoding = (short) zval_get_long(pvalue);
3747+
zend_long encoding = zval_get_long(pvalue);
3748+
if (encoding >= 0 && encoding <= ENCMAX && body_encodings[encoding] != NULL) {
3749+
bod->encoding = (short) encoding;
3750+
}
37423751
}
37433752
if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
37443753
convert_to_string_ex(pvalue);

ext/imap/tests/bug80216.phpt

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #80216 (imap_mail_compose() does not validate types/encodings)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('imap')) die('skip imap extension not available');
6+
?>
7+
--FILE--
8+
<?php
9+
imap_mail_compose([], [['type' => TYPEMULTIPART], []]);
10+
imap_mail_compose([], [['type' => 12]]);
11+
imap_mail_compose([], [['type' => TYPEMULTIPART], ['type' => 12]]);
12+
imap_mail_compose([], [['encoding' => 8]]);
13+
imap_mail_compose([], [['type' => TYPEMULTIPART], ['encoding' => 8]]);
14+
echo "done\n";
15+
?>
16+
--EXPECT--
17+
done

0 commit comments

Comments
 (0)