diff options
| author | Ben Fuhrmannek | 2021-08-03 15:33:17 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2021-08-03 15:33:17 +0200 |
| commit | 7cce9171be0c8bb19818e9f668626af41efe3aae (patch) | |
| tree | 97f6bc2172c520de782208d5c94a84d4ac78347a /src/sp_crypt.c | |
| parent | d4993c7deaefadbc5675f39404a46e64006174b9 (diff) | |
fixed memleaks in zval encryption/decryption routines
Diffstat (limited to 'src/sp_crypt.c')
| -rw-r--r-- | src/sp_crypt.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/src/sp_crypt.c b/src/sp_crypt.c index c57ac0b..eeffe33 100644 --- a/src/sp_crypt.c +++ b/src/sp_crypt.c | |||
| @@ -40,11 +40,10 @@ void generate_key(unsigned char *key) { | |||
| 40 | // This function return 0 upon success , non-zero otherwise | 40 | // This function return 0 upon success , non-zero otherwise |
| 41 | int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { | 41 | int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { |
| 42 | unsigned char key[crypto_secretbox_KEYBYTES] = {0}; | 42 | unsigned char key[crypto_secretbox_KEYBYTES] = {0}; |
| 43 | unsigned char *decrypted; | 43 | unsigned char *decrypted = NULL, *backup = NULL; |
| 44 | zend_string *debase64; | ||
| 45 | int ret = 0; | 44 | int ret = 0; |
| 46 | 45 | ||
| 47 | debase64 = php_base64_decode((unsigned char *)(Z_STRVAL_P(pDest)), | 46 | zend_string *debase64 = php_base64_decode((unsigned char *)(Z_STRVAL_P(pDest)), |
| 48 | Z_STRLEN_P(pDest)); | 47 | Z_STRLEN_P(pDest)); |
| 49 | 48 | ||
| 50 | if (ZSTR_LEN(debase64) < crypto_secretbox_NONCEBYTES) { | 49 | if (ZSTR_LEN(debase64) < crypto_secretbox_NONCEBYTES) { |
| @@ -52,15 +51,15 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { | |||
| 52 | sp_log_simulation( | 51 | sp_log_simulation( |
| 53 | "cookie_encryption", | 52 | "cookie_encryption", |
| 54 | "Buffer underflow tentative detected in cookie encryption handling " | 53 | "Buffer underflow tentative detected in cookie encryption handling " |
| 55 | "for %s. Using the cookie 'as it' instead of decrypting it", | 54 | "for %s. Using the cookie 'as is' instead of decrypting it", |
| 56 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); | 55 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); |
| 57 | return ZEND_HASH_APPLY_KEEP; | 56 | ret = ZEND_HASH_APPLY_KEEP; goto out; |
| 58 | } else { | 57 | } else { |
| 59 | // LCOV_EXCL_START | 58 | // LCOV_EXCL_START |
| 60 | sp_log_drop( | 59 | sp_log_drop( |
| 61 | "cookie_encryption", | 60 | "cookie_encryption", |
| 62 | "Buffer underflow tentative detected in cookie encryption handling"); | 61 | "Buffer underflow (tentative) detected in cookie encryption handling"); |
| 63 | return ZEND_HASH_APPLY_REMOVE; | 62 | ret = ZEND_HASH_APPLY_REMOVE; goto out; |
| 64 | // LCOV_EXCL_STOP | 63 | // LCOV_EXCL_STOP |
| 65 | } | 64 | } |
| 66 | } | 65 | } |
| @@ -71,15 +70,15 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { | |||
| 71 | if (true == simulation) { | 70 | if (true == simulation) { |
| 72 | sp_log_simulation( | 71 | sp_log_simulation( |
| 73 | "cookie_encryption", | 72 | "cookie_encryption", |
| 74 | "Integer overflow tentative detected in cookie encryption handling " | 73 | "Integer overflow (tentative) detected in cookie encryption handling " |
| 75 | "for %s. Using the cookie 'as it' instead of decrypting it.", | 74 | "for %s. Using the cookie 'as it' instead of decrypting it.", |
| 76 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); | 75 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); |
| 77 | return ZEND_HASH_APPLY_KEEP; | 76 | ret = ZEND_HASH_APPLY_KEEP; goto out; |
| 78 | } else { | 77 | } else { |
| 79 | sp_log_drop( | 78 | sp_log_drop( |
| 80 | "cookie_encryption", | 79 | "cookie_encryption", |
| 81 | "Integer overflow tentative detected in cookie encryption handling."); | 80 | "Integer overflow (tentative) detected in cookie encryption handling."); |
| 82 | return ZEND_HASH_APPLY_REMOVE; | 81 | ret = ZEND_HASH_APPLY_REMOVE; goto out; |
| 83 | } | 82 | } |
| 84 | } | 83 | } |
| 85 | // LCOV_EXCL_STOP | 84 | // LCOV_EXCL_STOP |
| @@ -87,7 +86,7 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { | |||
| 87 | generate_key(key); | 86 | generate_key(key); |
| 88 | 87 | ||
| 89 | decrypted = ecalloc(ZSTR_LEN(debase64) + crypto_secretbox_ZEROBYTES, 1); | 88 | decrypted = ecalloc(ZSTR_LEN(debase64) + crypto_secretbox_ZEROBYTES, 1); |
| 90 | char *backup = ecalloc(ZSTR_LEN(debase64), 1); | 89 | backup = ecalloc(ZSTR_LEN(debase64), 1); |
| 91 | memcpy(backup, ZSTR_VAL(debase64), ZSTR_LEN(debase64)); | 90 | memcpy(backup, ZSTR_VAL(debase64), ZSTR_LEN(debase64)); |
| 92 | 91 | ||
| 93 | ret = crypto_secretbox_open( | 92 | ret = crypto_secretbox_open( |
| @@ -101,28 +100,31 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { | |||
| 101 | sp_log_simulation( | 100 | sp_log_simulation( |
| 102 | "cookie_encryption", | 101 | "cookie_encryption", |
| 103 | "Something went wrong with the decryption of %s. Using the cookie " | 102 | "Something went wrong with the decryption of %s. Using the cookie " |
| 104 | "'as it' instead of decrypting it", | 103 | "'as is' instead of decrypting it", |
| 105 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); | 104 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); |
| 106 | memcpy(ZSTR_VAL(debase64), backup, ZSTR_LEN(debase64)); | 105 | memcpy(ZSTR_VAL(debase64), backup, ZSTR_LEN(debase64)); |
| 107 | efree(backup); | 106 | ret = ZEND_HASH_APPLY_KEEP; goto out; |
| 108 | return ZEND_HASH_APPLY_KEEP; | ||
| 109 | } else { | 107 | } else { |
| 110 | sp_log_warn("cookie_encryption", | 108 | sp_log_warn("cookie_encryption", |
| 111 | "Something went wrong with the decryption of %s", | 109 | "Something went wrong with the decryption of %s", |
| 112 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); | 110 | hash_key ? ZSTR_VAL(hash_key->key) : "the session"); |
| 113 | efree(backup); | 111 | ret = ZEND_HASH_APPLY_REMOVE; goto out; |
| 114 | return ZEND_HASH_APPLY_REMOVE; | ||
| 115 | } | 112 | } |
| 116 | } | 113 | } |
| 117 | efree(backup); | ||
| 118 | 114 | ||
| 119 | ZVAL_STRINGL(pDest, (char *)(decrypted + crypto_secretbox_ZEROBYTES), | 115 | ZVAL_STRINGL(pDest, (char *)(decrypted + crypto_secretbox_ZEROBYTES), |
| 120 | ZSTR_LEN(debase64) - crypto_secretbox_NONCEBYTES - 1 - | 116 | ZSTR_LEN(debase64) - crypto_secretbox_NONCEBYTES - 1 - |
| 121 | crypto_secretbox_ZEROBYTES); | 117 | crypto_secretbox_ZEROBYTES); |
| 122 | 118 | ||
| 123 | efree(decrypted); | 119 | ret = ZEND_HASH_APPLY_KEEP; |
| 124 | 120 | ||
| 125 | return ZEND_HASH_APPLY_KEEP; | 121 | out: |
| 122 | |||
| 123 | if (debase64) { zend_string_efree(debase64); } | ||
| 124 | if (decrypted) { efree(decrypted); } | ||
| 125 | if (backup) { efree(backup); } | ||
| 126 | |||
| 127 | return ret; | ||
| 126 | } | 128 | } |
| 127 | 129 | ||
| 128 | /* | 130 | /* |
| @@ -156,10 +158,19 @@ zend_string *encrypt_zval(zend_string *data) { | |||
| 156 | 158 | ||
| 157 | memcpy(encrypted_data, nonce, crypto_secretbox_NONCEBYTES); | 159 | memcpy(encrypted_data, nonce, crypto_secretbox_NONCEBYTES); |
| 158 | 160 | ||
| 159 | crypto_secretbox(encrypted_data + crypto_secretbox_NONCEBYTES, | 161 | int err = crypto_secretbox(encrypted_data + crypto_secretbox_NONCEBYTES, |
| 160 | data_to_encrypt, encrypted_msg_len, nonce, key); | 162 | data_to_encrypt, encrypted_msg_len, nonce, key); |
| 161 | 163 | ||
| 162 | zend_string *z = php_base64_encode(encrypted_data, emsg_and_nonce_len); | 164 | zend_string *z = NULL; |
| 165 | if (err) { | ||
| 166 | sp_log_err("cookie_encryption", "something went wrong during encryption"); | ||
| 167 | z = zend_string_init("<sp_encryption_error>", 21, 0); | ||
| 168 | } else { | ||
| 169 | z = php_base64_encode(encrypted_data, emsg_and_nonce_len); | ||
| 170 | } | ||
| 171 | |||
| 172 | efree(data_to_encrypt); | ||
| 173 | efree(encrypted_data); | ||
| 163 | 174 | ||
| 164 | return z; | 175 | return z; |
| 165 | } | 176 | } |
