Commit: fbfae33e398c874132ed21dc6ab93a7d8fcbc258 Author: Jakub Zelenka <bu...@php.net> Wed, 4 Dec 2013 19:01:39 +0000 Parents: 8710929b78b728c3ef6d09309b7375ae236e78eb Branches: str_size_and_int64
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=fbfae33e398c874132ed21dc6ab93a7d8fcbc258 Log: Add missing overflow checks Changed paths: M ext/openssl/openssl.c Diff: diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 820e6c4..0a4f932 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4856,6 +4856,12 @@ PHP_FUNCTION(openssl_seal) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Szza/|S", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) { return; } + + if (data_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, data_len); + RETURN_FALSE; + } pubkeysht = HASH_OF(pubkeys); nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0; @@ -4922,7 +4928,7 @@ PHP_FUNCTION(openssl_seal) zval_dtor(sealdata); buf[len1 + len2] = '\0'; buf = erealloc(buf, len1 + len2 + 1); - ZVAL_STRINGL(sealdata, (char *)buf, (zend_str_size_int)(len1 + len2), 0); + ZVAL_STRINGL(sealdata, (char *)buf, len1 + len2, 0); zval_dtor(ekeys); array_init(ekeys); @@ -4984,6 +4990,17 @@ PHP_FUNCTION(openssl_open) return; } + if (data_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, data_len); + RETURN_FALSE; + } + if (ekey_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Envelope key is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, ekey_len); + RETURN_FALSE; + } + pkey = php_openssl_evp_from_zval(privkey, 0, "", 0, &keyresource TSRMLS_CC); if (pkey == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to coerce parameter 4 into a private key"); @@ -5022,7 +5039,7 @@ PHP_FUNCTION(openssl_open) } zval_dtor(opendata); buf[len1 + len2] = '\0'; - ZVAL_STRINGL(opendata, erealloc(buf, len1 + len2 + 1), (zend_str_size_int)(len1 + len2), 0); + ZVAL_STRINGL(opendata, erealloc(buf, len1 + len2 + 1), len1 + len2, 0); RETURN_TRUE; } /* }}} */ @@ -5455,7 +5472,7 @@ static zend_bool php_openssl_validate_iv(char **piv, zend_str_size_int *piv_len, iv_new = ecalloc(1, iv_required_len + 1); - if (*piv_len <= 0) { + if (*piv_len == 0) { /* BC behavior */ *piv_len = iv_required_len; *piv = iv_new; @@ -5494,6 +5511,18 @@ PHP_FUNCTION(openssl_encrypt) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SSS|iS", &data, &data_len, &method, &method_len, &password, &password_len, &options, &iv, &iv_len) == FAILURE) { return; } + + if (data_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, data_len); + RETURN_FALSE; + } + if (password_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Password is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, password_len); + RETURN_FALSE; + } + cipher_type = EVP_get_cipherbyname(method); if (!cipher_type) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm"); @@ -5509,8 +5538,8 @@ PHP_FUNCTION(openssl_encrypt) key = (unsigned char*)password; } - max_iv_len = (zend_str_size_int)EVP_CIPHER_iv_length(cipher_type); - if (iv_len <= 0 && max_iv_len > 0) { + max_iv_len = EVP_CIPHER_iv_length(cipher_type); + if (iv_len == 0 && max_iv_len > 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Using an empty Initialization Vector (iv) is potentially insecure and not recommended"); } free_iv = php_openssl_validate_iv(&iv, &iv_len, max_iv_len TSRMLS_CC); @@ -5576,6 +5605,17 @@ PHP_FUNCTION(openssl_decrypt) return; } + if (data_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Data is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, data_len); + RETURN_FALSE; + } + if (password_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Password is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, password_len); + RETURN_FALSE; + } + if (!method_len) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm"); RETURN_FALSE; @@ -5684,6 +5724,13 @@ PHP_FUNCTION(openssl_dh_compute_key) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Sr", &pub_str, &pub_len, &key) == FAILURE) { return; } + + if (pub_len > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Public key is too long; it needs to be at most %d bytes, not " ZEND_UINT_FMT, + INT_MAX, pub_len); + RETURN_FALSE; + } + ZEND_FETCH_RESOURCE(pkey, EVP_PKEY *, &key, -1, "OpenSSL key", le_key); if (!pkey || EVP_PKEY_type(pkey->type) != EVP_PKEY_DH || !pkey->pkey.dh) { RETURN_FALSE; @@ -5722,6 +5769,11 @@ PHP_FUNCTION(openssl_random_pseudo_bytes) if (buffer_length <= 0) { RETURN_FALSE; } + if (buffer_length > INT_MAX) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Public key is too long; it needs to be at most %d bytes, not " ZEND_INT_FMT, + INT_MAX, buffer_length); + RETURN_FALSE; + } if (zstrong_result_returned) { zval_dtor(zstrong_result_returned); -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php