[php-src] master: Merge branch 'PHP-8.5'
Ilia Alshanetsky <[email protected]>
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: Ilia Alshanetsky (iliaal)
Date: 2026-06-29T10:37:55-04:00
Commit: https://github.com/php/php-src/commit/81f09e8cf06c72cf5de809a8085fda76357ab556
Raw diff: https://github.com/php/php-src/commit/81f09e8cf06c72cf5de809a8085fda76357ab556.diff
Merge branch 'PHP-8.5'
* PHP-8.5:
Fix GH-18173: ext/hash relies on implementation-defined malloc alignment
Changed paths:
M ext/hash/hash.c
M ext/hash/hash_adler32.c
M ext/hash/hash_crc32.c
M ext/hash/hash_fnv.c
M ext/hash/hash_gost.c
M ext/hash/hash_haval.c
M ext/hash/hash_joaat.c
M ext/hash/hash_md.c
M ext/hash/hash_murmur.c
M ext/hash/hash_ripemd.c
M ext/hash/hash_sha.c
M ext/hash/hash_sha3.c
M ext/hash/hash_snefru.c
M ext/hash/hash_tiger.c
M ext/hash/hash_whirlpool.c
M ext/hash/hash_xxhash.c
M ext/hash/php_hash.h
Diff:
diff --git a/ext/hash/hash.c b/ext/hash/hash.c
index 3ba42c8ff85d..e2af98c81ddf 100644
--- a/ext/hash/hash.c
+++ b/ext/hash/hash.c
@@ -386,7 +386,7 @@ static void php_hash_do_hash(
}
php_stream_close(stream);
if (n < 0) {
- efree(context);
+ php_hash_free_context(ops, context);
RETURN_FALSE;
}
} else {
@@ -395,7 +395,7 @@ static void php_hash_do_hash(
digest = zend_string_alloc(ops->digest_size, 0);
ops->hash_final((unsigned char *) ZSTR_VAL(digest), context);
- efree(context);
+ php_hash_free_context(ops, context);
if (raw_output) {
ZSTR_VAL(digest)[ops->digest_size] = 0;
@@ -534,7 +534,7 @@ static void php_hash_do_hash_hmac(
}
php_stream_close(stream);
if (n < 0) {
- efree(context);
+ php_hash_free_context(ops, context);
efree(K);
zend_string_efree(digest);
RETURN_FALSE;
@@ -552,7 +552,7 @@ static void php_hash_do_hash_hmac(
/* Zero the key */
ZEND_SECURE_ZERO(K, ops->block_size);
efree(K);
- efree(context);
+ php_hash_free_context(ops, context);
if (raw_output) {
ZSTR_VAL(digest)[ops->digest_size] = 0;
@@ -813,7 +813,7 @@ PHP_FUNCTION(hash_final)
ZSTR_VAL(digest)[digest_len] = 0;
/* Invalidate the object from further use */
- efree(hash->context);
+ php_hash_free_context(hash->ops, hash->context);
hash->context = NULL;
if (raw_output) {
@@ -967,7 +967,7 @@ PHP_FUNCTION(hash_hkdf)
ZEND_SECURE_ZERO(digest, ops->digest_size);
ZEND_SECURE_ZERO(prk, ops->digest_size);
efree(K);
- efree(context);
+ php_hash_free_context(ops, context);
efree(prk);
efree(digest);
ZSTR_VAL(returnval)[length] = 0;
@@ -1083,7 +1083,7 @@ PHP_FUNCTION(hash_pbkdf2)
efree(K1);
efree(K2);
efree(computed_salt);
- efree(context);
+ php_hash_free_context(ops, context);
efree(digest);
efree(temp);
@@ -1348,7 +1348,7 @@ PHP_FUNCTION(mhash_keygen_s2k)
RETVAL_STRINGL(key, bytes);
ZEND_SECURE_ZERO(key, bytes);
efree(digest);
- efree(context);
+ php_hash_free_context(ops, context);
efree(key);
}
}
@@ -1378,7 +1378,7 @@ static void php_hashcontext_dtor(zend_object *obj) {
php_hashcontext_object *hash = php_hashcontext_from_object(obj);
if (hash->context) {
- efree(hash->context);
+ php_hash_free_context(hash->ops, hash->context);
hash->context = NULL;
}
@@ -1414,7 +1414,7 @@ static zend_object *php_hashcontext_clone(zend_object *zobj) {
newobj->ops->hash_init(newobj->context, NULL);
if (SUCCESS != newobj->ops->hash_copy(newobj->ops, oldobj->context, newobj->context)) {
- efree(newobj->context);
+ php_hash_free_context(newobj->ops, newobj->context);
newobj->context = NULL;
return znew;
}
diff --git a/ext/hash/hash_adler32.c b/ext/hash/hash_adler32.c
index 2a40b3318cd5..1f5ae3756a0a 100644
--- a/ext/hash/hash_adler32.c
+++ b/ext/hash/hash_adler32.c
@@ -68,5 +68,6 @@ const php_hash_ops php_hash_adler32_ops = {
4, /* what to say here? */
4,
sizeof(PHP_ADLER32_CTX),
+ 0,
0
};
diff --git a/ext/hash/hash_crc32.c b/ext/hash/hash_crc32.c
index 795cfcdf05b2..407150a1cdd3 100644
--- a/ext/hash/hash_crc32.c
+++ b/ext/hash/hash_crc32.c
@@ -100,6 +100,7 @@ const php_hash_ops php_hash_crc32_ops = {
4, /* what to say here? */
4,
sizeof(PHP_CRC32_CTX),
+ 0,
0
};
@@ -115,6 +116,7 @@ const php_hash_ops php_hash_crc32b_ops = {
4, /* what to say here? */
4,
sizeof(PHP_CRC32_CTX),
+ 0,
0
};
@@ -130,5 +132,6 @@ const php_hash_ops php_hash_crc32c_ops = {
4, /* what to say here? */
4,
sizeof(PHP_CRC32_CTX),
+ 0,
0
};
diff --git a/ext/hash/hash_fnv.c b/ext/hash/hash_fnv.c
index 58101c4f2e6c..7859e5908870 100644
--- a/ext/hash/hash_fnv.c
+++ b/ext/hash/hash_fnv.c
@@ -30,6 +30,7 @@ const php_hash_ops php_hash_fnv132_ops = {
4,
4,
sizeof(PHP_FNV132_CTX),
+ 0,
0
};
@@ -45,6 +46,7 @@ const php_hash_ops php_hash_fnv1a32_ops = {
4,
4,
sizeof(PHP_FNV132_CTX),
+ 0,
0
};
@@ -60,6 +62,7 @@ const php_hash_ops php_hash_fnv164_ops = {
8,
4,
sizeof(PHP_FNV164_CTX),
+ 0,
0
};
@@ -75,6 +78,7 @@ const php_hash_ops php_hash_fnv1a64_ops = {
8,
4,
sizeof(PHP_FNV164_CTX),
+ 0,
0
};
diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c
index ad87754970b9..91edbd50834f 100644
--- a/ext/hash/hash_gost.c
+++ b/ext/hash/hash_gost.c
@@ -327,7 +327,8 @@ const php_hash_ops php_hash_gost_ops = {
32,
32,
sizeof(PHP_GOST_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_gost_crypto_ops = {
@@ -342,5 +343,6 @@ const php_hash_ops php_hash_gost_crypto_ops = {
32,
32,
sizeof(PHP_GOST_CTX),
- 1
+ 1,
+ 0
};
diff --git a/ext/hash/hash_haval.c b/ext/hash/hash_haval.c
index 2adafdb189e2..b326142cc7ef 100644
--- a/ext/hash/hash_haval.c
+++ b/ext/hash/hash_haval.c
@@ -250,7 +250,7 @@ const php_hash_ops php_hash_##p##haval##b##_ops = { \
php_hash_serialize, \
php_hash_unserialize, \
PHP_HAVAL_SPEC, \
- ((b) / 8), 128, sizeof(PHP_HAVAL_CTX), 1 }; \
+ ((b) / 8), 128, sizeof(PHP_HAVAL_CTX), 1, 0 }; \
PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *context, ZEND_ATTRIBUTE_UNUSED HashTable *args) \
{ int i; context->count[0] = context->count[1] = 0; \
for(i = 0; i < 8; i++) context->state[i] = D0[i]; \
diff --git a/ext/hash/hash_joaat.c b/ext/hash/hash_joaat.c
index 0d7b64092f47..0550af18dce7 100644
--- a/ext/hash/hash_joaat.c
+++ b/ext/hash/hash_joaat.c
@@ -31,6 +31,7 @@ const php_hash_ops php_hash_joaat_ops = {
4,
4,
sizeof(PHP_JOAAT_CTX),
+ 0,
0
};
diff --git a/ext/hash/hash_md.c b/ext/hash/hash_md.c
index 0bd48a9c823c..44d43e16777f 100644
--- a/ext/hash/hash_md.c
+++ b/ext/hash/hash_md.c
@@ -27,7 +27,8 @@ const php_hash_ops php_hash_md5_ops = {
16,
64,
sizeof(PHP_MD5_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_md4_ops = {
@@ -42,7 +43,8 @@ const php_hash_ops php_hash_md4_ops = {
16,
64,
sizeof(PHP_MD4_CTX),
- 1
+ 1,
+ 0
};
static hash_spec_result php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv);
@@ -59,7 +61,8 @@ const php_hash_ops php_hash_md2_ops = {
16,
16,
sizeof(PHP_MD2_CTX),
- 1
+ 1,
+ 0
};
/* MD common stuff */
diff --git a/ext/hash/hash_murmur.c b/ext/hash/hash_murmur.c
index cd5d5f4be520..1e63262c20ed 100644
--- a/ext/hash/hash_murmur.c
+++ b/ext/hash/hash_murmur.c
@@ -31,6 +31,7 @@ const php_hash_ops php_hash_murmur3a_ops = {
4,
4,
sizeof(PHP_MURMUR3A_CTX),
+ 0,
0
};
@@ -93,6 +94,7 @@ const php_hash_ops php_hash_murmur3c_ops = {
16,
4,
sizeof(PHP_MURMUR3C_CTX),
+ 0,
0
};
@@ -172,6 +174,7 @@ const php_hash_ops php_hash_murmur3f_ops = {
16,
8,
sizeof(PHP_MURMUR3F_CTX),
+ 0,
0
};
diff --git a/ext/hash/hash_ripemd.c b/ext/hash/hash_ripemd.c
index 1b76f58ff098..c6396ba2a60a 100644
--- a/ext/hash/hash_ripemd.c
+++ b/ext/hash/hash_ripemd.c
@@ -31,7 +31,8 @@ const php_hash_ops php_hash_ripemd128_ops = {
16,
64,
sizeof(PHP_RIPEMD128_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_ripemd160_ops = {
@@ -46,7 +47,8 @@ const php_hash_ops php_hash_ripemd160_ops = {
20,
64,
sizeof(PHP_RIPEMD160_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_ripemd256_ops = {
@@ -61,7 +63,8 @@ const php_hash_ops php_hash_ripemd256_ops = {
32,
64,
sizeof(PHP_RIPEMD256_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_ripemd320_ops = {
@@ -76,7 +79,8 @@ const php_hash_ops php_hash_ripemd320_ops = {
40,
64,
sizeof(PHP_RIPEMD320_CTX),
- 1
+ 1,
+ 0
};
/* {{{ PHP_RIPEMD128Init
diff --git a/ext/hash/hash_sha.c b/ext/hash/hash_sha.c
index fd4d8ce5a36a..3a7729e31fc0 100644
--- a/ext/hash/hash_sha.c
+++ b/ext/hash/hash_sha.c
@@ -73,7 +73,8 @@ const php_hash_ops php_hash_sha1_ops = {
20,
64,
sizeof(PHP_SHA1_CTX),
- 1
+ 1,
+ 0
};
/* sha224/sha256 */
@@ -90,7 +91,8 @@ const php_hash_ops php_hash_sha256_ops = {
32,
64,
sizeof(PHP_SHA256_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_sha224_ops = {
@@ -105,7 +107,8 @@ const php_hash_ops php_hash_sha224_ops = {
28,
64,
sizeof(PHP_SHA224_CTX),
- 1
+ 1,
+ 0
};
#define ROTR32(b,x) ((x >> b) | (x << (32 - b)))
@@ -622,7 +625,8 @@ const php_hash_ops php_hash_sha384_ops = {
48,
128,
sizeof(PHP_SHA384_CTX),
- 1
+ 1,
+ 0
};
/* {{{ PHP_SHA512InitArgs
@@ -801,7 +805,8 @@ const php_hash_ops php_hash_sha512_ops = {
64,
128,
sizeof(PHP_SHA512_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_sha512_256_ops = {
@@ -816,7 +821,8 @@ const php_hash_ops php_hash_sha512_256_ops = {
32,
128,
sizeof(PHP_SHA512_CTX),
- 1
+ 1,
+ 0
};
const php_hash_ops php_hash_sha512_224_ops = {
@@ -831,5 +837,6 @@ const php_hash_ops php_hash_sha512_224_ops = {
28,
128,
sizeof(PHP_SHA512_CTX),
- 1
+ 1,
+ 0
};
diff --git a/ext/hash/hash_sha3.c b/ext/hash/hash_sha3.c
index d82840e81de6..3f5d966820cd 100644
--- a/ext/hash/hash_sha3.c
+++ b/ext/hash/hash_sha3.c
@@ -249,7 +249,8 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \
bits >> 3, \
(1600 - (2 * bits)) >> 3, \
sizeof(PHP_SHA3_##bits##_CTX), \
- 1 \
+ 1, \
+ 0 \
}
#else
@@ -337,7 +338,8 @@ const php_hash_ops php_hash_sha3_##bits##_ops = { \
bits >> 3, \
(1600 - (2 * bits)) >> 3, \
sizeof(PHP_SHA3_CTX), \
- 1 \
+ 1, \
+ 0 \
}
#endif
diff --git a/ext/hash/hash_snefru.c b/ext/hash/hash_snefru.c
index 5f08eb088229..3fe16b4398a3 100644
--- a/ext/hash/hash_snefru.c
+++ b/ext/hash/hash_snefru.c
@@ -212,5 +212,6 @@ const php_hash_ops php_hash_snefru_ops = {
32,
32,
sizeof(PHP_SNEFRU_CTX),
- 1
+ 1,
+ 0
};
diff --git a/ext/hash/hash_tiger.c b/ext/hash/hash_tiger.c
index 1153711d85d4..f9b4dc737581 100644
--- a/ext/hash/hash_tiger.c
+++ b/ext/hash/hash_tiger.c
@@ -263,7 +263,8 @@ static hash_spec_result php_tiger_unserialize(php_hashcontext_object *hash, zend
b/8, \
64, \
sizeof(PHP_TIGER_CTX), \
- 1 \
+ 1, \
+ 0 \
}
PHP_HASH_TIGER_OPS(3, 128);
diff --git a/ext/hash/hash_whirlpool.c b/ext/hash/hash_whirlpool.c
index 2a5b220d3a18..9d895efa06e7 100644
--- a/ext/hash/hash_whirlpool.c
+++ b/ext/hash/hash_whirlpool.c
@@ -455,5 +455,6 @@ const php_hash_ops php_hash_whirlpool_ops = {
64,
64,
sizeof(PHP_WHIRLPOOL_CTX),
- 1
+ 1,
+ 0
};
diff --git a/ext/hash/hash_xxhash.c b/ext/hash/hash_xxhash.c
index b6177905e691..e0f400fc517e 100644
--- a/ext/hash/hash_xxhash.c
+++ b/ext/hash/hash_xxhash.c
@@ -32,6 +32,7 @@ const php_hash_ops php_hash_xxh32_ops = {
4,
4,
sizeof(PHP_XXH32_CTX),
+ 0,
0
};
@@ -99,6 +100,7 @@ const php_hash_ops php_hash_xxh64_ops = {
8,
8,
sizeof(PHP_XXH64_CTX),
+ 0,
0
};
@@ -150,7 +152,8 @@ const php_hash_ops php_hash_xxh3_64_ops = {
8,
8,
sizeof(PHP_XXH3_64_CTX),
- 0
+ 0,
+ 64
};
typedef XXH_errorcode (*xxh3_reset_with_secret_func_t)(XXH3_state_t*, const void*, size_t);
@@ -255,7 +258,8 @@ const php_hash_ops php_hash_xxh3_128_ops = {
16,
8,
sizeof(PHP_XXH3_128_CTX),
- 0
+ 0,
+ 64
};
PHP_HASH_API void PHP_XXH3_128_Init(PHP_XXH3_128_CTX *ctx, HashTable *args)
diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h
index 9eac5da78c8d..f89bee8ab010 100644
--- a/ext/hash/php_hash.h
+++ b/ext/hash/php_hash.h
@@ -58,6 +58,7 @@ typedef struct _php_hash_ops {
size_t block_size;
size_t context_size;
unsigned is_crypto: 1;
+ size_t context_align;
} php_hash_ops;
struct _php_hashcontext_object {
@@ -161,9 +162,26 @@ PHP_HASH_API hash_spec_result php_hash_unserialize_spec(php_hashcontext_object *
static inline void *php_hash_alloc_context(const php_hash_ops *ops) {
/* Zero out context memory so serialization doesn't expose internals */
+ if (ops->context_align > 0) {
+ size_t align = ops->context_align;
+ char *base = ecalloc(1, ops->context_size + align);
+ size_t offset = align - ((uintptr_t)base & (align - 1));
+ char *ptr = base + offset;
+ ptr[-1] = (char)offset;
+ return ptr;
+ }
return ecalloc(1, ops->context_size);
}
+static inline void php_hash_free_context(const php_hash_ops *ops, void *ctx) {
+ if (ops->context_align > 0) {
+ unsigned char offset = ((unsigned char *)ctx)[-1];
+ efree((char *)ctx - offset);
+ return;
+ }
+ efree(ctx);
+}
+
static inline void php_hash_bin2hex(char *out, const unsigned char *in, size_t in_len)
{
static const char hexits[17] = "0123456789abcdef";