Skip to content

Commit 5351baa

Browse files
committed
Remove ext/random dependency
1 parent a8f4827 commit 5351baa

File tree

10 files changed

+652
-247
lines changed

10 files changed

+652
-247
lines changed

Zend/zend.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "Optimizer/zend_optimizer.h"
4242
#include "php.h"
4343
#include "php_globals.h"
44+
#include "zend_random.h"
4445

4546
// FIXME: Breaks the declaration of the function below
4647
#undef zenderror
@@ -907,6 +908,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
907908
#endif
908909

909910
zend_cpu_startup();
911+
zend_random_startup();
910912

911913
#ifdef ZEND_WIN32
912914
php_win32_cp_set_by_id(65001);
@@ -1189,6 +1191,7 @@ void zend_shutdown(void) /* {{{ */
11891191
zend_unload_modules();
11901192

11911193
zend_optimizer_shutdown();
1194+
zend_random_shutdown();
11921195
startup_done = false;
11931196
}
11941197
/* }}} */

Zend/zend_alloc.c

Lines changed: 89 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@
5454
#include "zend.h"
5555
#include "zend_alloc.h"
5656
#include "zend_globals.h"
57+
#include "zend_hrtime.h"
5758
#include "zend_operators.h"
5859
#include "zend_multiply.h"
5960
#include "zend_bitset.h"
6061
#include "zend_mmap.h"
6162
#include "zend_portability.h"
62-
#include "ext/random/php_random_csprng.h"
63-
#include "ext/random/php_random.h"
63+
#include "zend_random.h"
6464
#include <signal.h>
6565

6666
#ifdef HAVE_UNISTD_H
@@ -246,6 +246,10 @@ typedef struct _zend_mm_huge_list zend_mm_huge_list;
246246

247247
static bool zend_mm_use_huge_pages = false;
248248

249+
typedef struct _zend_mm_rand_state {
250+
uint32_t state[4];
251+
} zend_mm_rand_state;
252+
249253
/*
250254
* Memory is retrieved from OS by chunks of fixed size 2MB.
251255
* Inside chunk it's managed by pages of fixed size 4096B.
@@ -321,7 +325,7 @@ struct _zend_mm_heap {
321325
HashTable *tracked_allocs;
322326
#endif
323327
pid_t pid;
324-
php_random_status_state_xoshiro256starstar random_state;
328+
zend_mm_rand_state rand_state;
325329
};
326330

327331
struct _zend_mm_chunk {
@@ -2016,30 +2020,102 @@ static void zend_mm_free_huge(zend_mm_heap *heap, void *ptr ZEND_FILE_LINE_DC ZE
20162020
#endif
20172021
}
20182022

2023+
/********/
2024+
/* Rand */
2025+
/********/
2026+
2027+
/* Xoshiro256** PRNG based on implementation from Go Kudo in
2028+
* ext/random/engine_xoshiro256starstar.c, based on code from David Blackman,
2029+
* Sebastiano Vigna. */
2030+
2031+
static inline uint64_t splitmix64(uint64_t *seed)
2032+
{
2033+
uint64_t r;
2034+
2035+
r = (*seed += 0x9e3779b97f4a7c15ULL);
2036+
r = (r ^ (r >> 30)) * 0xbf58476d1ce4e5b9ULL;
2037+
r = (r ^ (r >> 27)) * 0x94d049bb133111ebULL;
2038+
return (r ^ (r >> 31));
2039+
}
2040+
2041+
ZEND_ATTRIBUTE_CONST static inline uint64_t rotl(const uint64_t x, int k)
2042+
{
2043+
return (x << k) | (x >> (64 - k));
2044+
}
2045+
2046+
static inline uint64_t zend_mm_rand_generate(zend_mm_rand_state *s)
2047+
{
2048+
const uint64_t r = rotl(s->state[1] * 5, 7) * 9;
2049+
const uint64_t t = s->state[1] << 17;
2050+
2051+
s->state[2] ^= s->state[0];
2052+
s->state[3] ^= s->state[1];
2053+
s->state[1] ^= s->state[2];
2054+
s->state[0] ^= s->state[3];
2055+
2056+
s->state[2] ^= t;
2057+
2058+
s->state[3] = rotl(s->state[3], 45);
2059+
2060+
return r;
2061+
}
2062+
2063+
static inline void zend_mm_rand_seed256(zend_mm_rand_state *state, uint64_t s0, uint64_t s1, uint64_t s2, uint64_t s3)
2064+
{
2065+
state->state[0] = s0;
2066+
state->state[1] = s1;
2067+
state->state[2] = s2;
2068+
state->state[3] = s3;
2069+
}
2070+
2071+
static inline void zend_mm_rand_seed64(zend_mm_rand_state *state, uint64_t seed)
2072+
{
2073+
uint64_t s[4];
2074+
2075+
s[0] = splitmix64(&seed);
2076+
s[1] = splitmix64(&seed);
2077+
s[2] = splitmix64(&seed);
2078+
s[3] = splitmix64(&seed);
2079+
2080+
zend_mm_rand_seed256(state, s[0], s[1], s[2], s[3]);
2081+
}
2082+
20192083
/******************/
20202084
/* Initialization */
20212085
/******************/
20222086

20232087
static zend_result zend_mm_refresh_key(zend_mm_heap *heap)
20242088
{
2025-
php_random_result result = php_random_algo_xoshiro256starstar.generate(&heap->random_state);
2026-
ZEND_ASSERT(result.size == sizeof(uint64_t));
2027-
heap->shadow_key = (uintptr_t) result.result;
2089+
heap->shadow_key = (uintptr_t) zend_mm_rand_generate(&heap->rand_state);
2090+
20282091
return SUCCESS;
20292092
}
20302093

20312094
static zend_result zend_mm_init_key(zend_mm_heap *heap)
20322095
{
20332096
uint64_t seed[4];
2034-
if (php_random_bytes_silent(&seed, sizeof(seed)) != SUCCESS) {
2035-
for (int i = 0; i < sizeof(seed)/sizeof(seed[0]); i++) {
2036-
seed[i] = php_random_generate_fallback_seed();
2037-
}
2097+
char errstr[128];
2098+
if (zend_get_os_random_bytes_ex(&seed, sizeof(seed), errstr, sizeof(errstr)) == SUCCESS) {
2099+
zend_mm_rand_seed256(&heap->rand_state,
2100+
seed[0], seed[1], seed[2], seed[3]);
2101+
} else {
2102+
/* Fallback to weak seed generation */
2103+
#if ZEND_MM_ERROR
2104+
fprintf(stderr, "Could not generate secure random seed: %s\n", errstr);
2105+
#endif
2106+
zend_hrtime_t nanotime = zend_hrtime();
2107+
uint64_t v = 0;
2108+
v ^= (uint64_t) nanotime;
2109+
splitmix64(&v);
2110+
v ^= (uint64_t) getpid();
2111+
splitmix64(&v);
2112+
#ifdef ZTS
2113+
v ^= tsrm_thread_id();
2114+
splitmix64(&v);
2115+
#endif
2116+
zend_mm_rand_seed64(&heap->rand_state, v);
20382117
}
20392118

2040-
php_random_xoshiro256starstar_seed256(&heap->random_state,
2041-
seed[0], seed[1], seed[2], seed[3]);
2042-
20432119
return zend_mm_refresh_key(heap);
20442120
}
20452121

Zend/zend_atomic.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,56 @@
2020
* is also where the code will go.
2121
*/
2222

23-
/* Defined for FFI users; everyone else use ZEND_ATOMIC_BOOL_INIT.
23+
/* Defined for FFI users; everyone else use ZEND_ATOMIC_*_INIT.
2424
* This is NOT ATOMIC as it is meant for initialization.
2525
*/
2626
ZEND_API void zend_atomic_bool_init(zend_atomic_bool *obj, bool desired) {
2727
ZEND_ATOMIC_BOOL_INIT(obj, desired);
2828
}
2929

30+
ZEND_API void zend_atomic_int_init(zend_atomic_int *obj, int desired) {
31+
ZEND_ATOMIC_INT_INIT(obj, desired);
32+
}
33+
3034
ZEND_API bool zend_atomic_bool_exchange(zend_atomic_bool *obj, bool desired) {
3135
return zend_atomic_bool_exchange_ex(obj, desired);
3236
}
3337

38+
ZEND_API int zend_atomic_int_exchange(zend_atomic_int *obj, int desired) {
39+
return zend_atomic_int_exchange_ex(obj, desired);
40+
}
41+
42+
ZEND_API bool zend_atomic_bool_compare_exchange(zend_atomic_bool *obj, bool *expected, bool desired)
43+
{
44+
return zend_atomic_bool_compare_exchange_ex(obj, expected, desired);
45+
}
46+
47+
ZEND_API bool zend_atomic_int_compare_exchange(zend_atomic_int *obj, int *expected, int desired)
48+
{
49+
return zend_atomic_int_compare_exchange_ex(obj, expected, desired);
50+
}
51+
3452
ZEND_API void zend_atomic_bool_store(zend_atomic_bool *obj, bool desired) {
3553
zend_atomic_bool_store_ex(obj, desired);
3654
}
3755

56+
ZEND_API void zend_atomic_int_store(zend_atomic_int *obj, int desired) {
57+
zend_atomic_int_store_ex(obj, desired);
58+
}
59+
3860
#if defined(ZEND_WIN32) || defined(HAVE_SYNC_ATOMICS)
3961
/* On these platforms it is non-const due to underlying APIs. */
4062
ZEND_API bool zend_atomic_bool_load(zend_atomic_bool *obj) {
4163
return zend_atomic_bool_load_ex(obj);
4264
}
65+
ZEND_API int zend_atomic_int_load(zend_atomic_int *obj) {
66+
return zend_atomic_int_load_ex(obj);
67+
}
4368
#else
4469
ZEND_API bool zend_atomic_bool_load(const zend_atomic_bool *obj) {
4570
return zend_atomic_bool_load_ex(obj);
4671
}
72+
ZEND_API int zend_atomic_int_load(const zend_atomic_int *obj) {
73+
return zend_atomic_int_load_ex(obj);
74+
}
4775
#endif

0 commit comments

Comments
 (0)