diff --git a/NEWS b/NEWS index bce75111ae7..e7bed7be2fa 100644 --- a/NEWS +++ b/NEWS @@ -136,6 +136,10 @@ PHP NEWS . Fixed bug GH-16293 (Failed assertion when throwing in assert() callback with bail enabled). (ilutov) +- SysVMsg: + . Fixed bug GH-16592 (msg_send() crashes when a type does not properly + serialized). (David Carlier / cmb) + - SysVShm: . Fixed bug GH-16591 (Assertion error in shm_put_var). (nielsdos, cmb) diff --git a/ext/sysvmsg/sysvmsg.c b/ext/sysvmsg/sysvmsg.c index 20bdecedb50..55935766ed0 100644 --- a/ext/sysvmsg/sysvmsg.c +++ b/ext/sysvmsg/sysvmsg.c @@ -371,11 +371,19 @@ PHP_FUNCTION(msg_send) php_var_serialize(&msg_var, message, &var_hash); PHP_VAR_SERIALIZE_DESTROY(var_hash); + if (UNEXPECTED(EG(exception))) { + smart_str_free(&msg_var); + RETURN_THROWS(); + } + + + zend_string *str = smart_str_extract(&msg_var); + message_len = ZSTR_LEN(str); /* NB: php_msgbuf is 1 char bigger than a long, so there is no need to * allocate the extra byte. */ - messagebuffer = safe_emalloc(ZSTR_LEN(msg_var.s), 1, sizeof(struct php_msgbuf)); - memcpy(messagebuffer->mtext, ZSTR_VAL(msg_var.s), ZSTR_LEN(msg_var.s) + 1); - message_len = ZSTR_LEN(msg_var.s); + messagebuffer = safe_emalloc(message_len, 1, sizeof(struct php_msgbuf)); + memcpy(messagebuffer->mtext, ZSTR_VAL(str), message_len + 1); + zend_string_release_ex(str, false); smart_str_free(&msg_var); } else { char *p; diff --git a/ext/sysvmsg/tests/gh16592.phpt b/ext/sysvmsg/tests/gh16592.phpt new file mode 100644 index 00000000000..8490d000f89 --- /dev/null +++ b/ext/sysvmsg/tests/gh16592.phpt @@ -0,0 +1,19 @@ +--TEST-- +msg_send() segfault when the type does not serialize as expected +--EXTENSIONS-- +sysvmsg +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Test::__serialize() must return an array