Bug #61124 [Com]: Segmentation fault
Edit report at https://bugs.php.net/bug.php?id=61124&edit=1
ID: 61124
Comment by: me at ktamura dot com
Reported by: mangirdas at impresspages dot org
Summary: Segmentation fault
Status: Open
Type: Bug
Package: OpenSSL related
Operating System: CentOS release 5.7 (Final)
PHP Version: 5.3.10
Block user comment: N
Private report: N
New Comment:
I think I know why. Basically, when the input data is malformed but $raw_input is set to false, we
get a null pointer. Here is a suggested patch (Also available at https://gist.github.com/1857431)
Index: ext/openssl/openssl.c
===================================================================
--- ext/openssl/openssl.c (revision 323312)
+++ ext/openssl/openssl.c (working copy)
@@ -4801,6 +4801,11 @@
base64_str = (char*)php_base64_decode((unsigned char*)data, data_len, &base64_str_len);
data_len = base64_str_len;
data = base64_str;
+
+ if (data == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to decode the base64
input");
+ RETURN_FALSE;
+ }
}
keylen = EVP_CIPHER_key_length(cipher_type);
Previous Comments:
------------------------------------------------------------------------
[2012-02-18 01:02:48] me at ktamura dot com
I feel that the real issue is that there is no input check on the first argument of
openssl_decrypt. Looking at http://linux.die.net/man/3/evp_decryptupdate
it is
unclear what the expected behavior is if you feed invalid input into
EVP_DecryptUpdate. Perhaps we can do input validation?
------------------------------------------------------------------------
[2012-02-18 00:53:01] me at ktamura dot com
FYI...the said "hacky" patch of adding 16 as opposed to 1 bytes do not solve the
problem for PHP 5.3.8 built with --enable-debug and --with-openssl --without-iconv
options on snow leopard.
------------------------------------------------------------------------
[2012-02-17 17:35:53] rasmus@php.net
Confirmed
It would help to mention that this gives this warning:
Warning: openssl_decrypt(): IV passed is only 4 bytes long, cipher expects an IV
of precisely 16 bytes, padding with \0
which is probably the cause here. The buffer we pass in is not large enough to
fit the IV.
A quick hack which fixes the segfault:
--- ext/openssl/openssl.c (revision 323261)
+++ ext/openssl/openssl.c (working copy)
@@ -4819,7 +4819,7 @@
free_iv = php_openssl_validate_iv(&iv, &iv_len,
EVP_CIPHER_iv_length(cipher_type) TSRMLS_CC);
outlen = data_len + EVP_CIPHER_block_size(cipher_type);
- outbuf = emalloc(outlen + 1);
+ outbuf = emalloc(outlen + 16);
EVP_DecryptInit(&cipher_ctx, cipher_type, NULL, NULL);
if (password_len > keylen) {
but it obviously isn't the right solution.
------------------------------------------------------------------------
[2012-02-17 17:11:09] mangirdas at impresspages dot org
Description:
------------
This function throws a segmentation fault:
openssl_decrypt ('kzo w2RMExUTYQXW2Xzxmg==', 'aes-128-cbc', 'pass',
$rawOutput,
'pass');
Test script:
---------------
<?php
openssl_decrypt ('kzo w2RMExUTYQXW2Xzxmg==', 'aes-128-cbc', 'pass',
$rawOutput,
'pass');
Expected result:
----------------
FALSE, because encrypted string is incorrect.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=61124&edit=1
Thread (8 messages)