Skip to content

Commit 6fb20cd

Browse files
authored
random: Simplify implementation of php_random_generate_fallback_seed() (#13761)
As all the input bits and pieces are mixed with SHA-1, cross-architecture compatibility is not required and we can just mix in whatever they may look like in memory, instead of going through the `write_*()` helpers that were created for a previous in-development version that first filled a buffer that was then hashed (allowing for easy inspection of the input data, but making it harder to safely add values without checking for buffer overflows all the time). This change should also fix a build error on macOS ZTS: The thread ID is an opaque type and not guaranteed to be arithmetic as per IEEE Std 1003.1-2017. And indeed macOS defines it as a pointer to a structure, failing due to the implicit pointer to integer conversion.
1 parent 2e7c6e1 commit 6fb20cd

File tree

1 file changed

+28
-38
lines changed

1 file changed

+28
-38
lines changed

ext/random/random.c

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -614,30 +614,12 @@ PHP_FUNCTION(random_int)
614614
}
615615
/* }}} */
616616

617-
static void write_32(PHP_SHA1_CTX *c, uint32_t u)
618-
{
619-
unsigned char buf[4];
620-
unsigned char *p = buf;
621-
*(p++) = (u >> 0) & 0xff;
622-
*(p++) = (u >> 8) & 0xff;
623-
*(p++) = (u >> 16) & 0xff;
624-
*(p++) = (u >> 24) & 0xff;
625-
PHP_SHA1Update(c, buf, sizeof(buf));
626-
}
627-
628-
static void write_64(PHP_SHA1_CTX *c, uint64_t u)
629-
{
630-
write_32(c, u);
631-
write_32(c, u >> 32);
632-
}
633-
634-
static void write_p(PHP_SHA1_CTX *c, uintptr_t p)
635-
{
636-
if (sizeof(p) == 4) {
637-
write_32(c, p);
638-
} else {
639-
write_64(c, p);
640-
}
617+
static inline void fallback_seed_add(PHP_SHA1_CTX *c, void *p, size_t l){
618+
/* Wrapper around PHP_SHA1Update allowing to pass
619+
* arbitrary pointers without (unsigned char*) casts
620+
* everywhere.
621+
*/
622+
PHP_SHA1Update(c, p, l);
641623
}
642624

643625
uint64_t php_random_generate_fallback_seed(void)
@@ -650,47 +632,55 @@ uint64_t php_random_generate_fallback_seed(void)
650632
*/
651633
PHP_SHA1_CTX c;
652634
struct timeval tv;
635+
void *pointer;
636+
pid_t pid;
637+
#ifdef ZTS
638+
THREAD_T tid;
639+
#endif
653640
char buf[64 + 1];
654641

655642
PHP_SHA1Init(&c);
656643
if (!RANDOM_G(fallback_seed_initialized)) {
657644
/* Current time. */
658645
gettimeofday(&tv, NULL);
659-
write_32(&c, tv.tv_sec);
660-
write_32(&c, tv.tv_usec);
646+
fallback_seed_add(&c, &tv, sizeof(tv));
661647
/* Various PIDs. */
662-
write_32(&c, getpid());
648+
pid = getpid();
649+
fallback_seed_add(&c, &pid, sizeof(pid));
663650
#ifndef WIN32
664-
write_32(&c, getppid());
651+
pid = getppid();
652+
fallback_seed_add(&c, &pid, sizeof(pid));
665653
#endif
666654
#ifdef ZTS
667-
write_32(&c, tsrm_thread_id());
655+
tid = tsrm_thread_id();
656+
fallback_seed_add(&c, &tid, sizeof(tid));
668657
#endif
669658
/* Pointer values to benefit from ASLR. */
670-
write_p(&c, (uintptr_t)&RANDOM_G(fallback_seed_initialized));
671-
write_p(&c, (uintptr_t)&c);
659+
pointer = &RANDOM_G(fallback_seed_initialized);
660+
fallback_seed_add(&c, &pointer, sizeof(pointer));
661+
pointer = &c;
662+
fallback_seed_add(&c, &pointer, sizeof(pointer));
672663
/* Updated time. */
673664
gettimeofday(&tv, NULL);
674-
write_32(&c, tv.tv_usec);
665+
fallback_seed_add(&c, &tv, sizeof(tv));
675666
/* Hostname. */
676667
memset(buf, 0, sizeof(buf));
677668
if (gethostname(buf, sizeof(buf) - 1) == 0) {
678-
PHP_SHA1Update(&c, (unsigned char*)buf, strlen(buf));
669+
fallback_seed_add(&c, buf, strlen(buf));
679670
}
680671
/* CSPRNG. */
681672
if (php_random_bytes_silent(buf, 16) == SUCCESS) {
682-
PHP_SHA1Update(&c, (unsigned char*)buf, 16);
673+
fallback_seed_add(&c, buf, 16);
683674
}
684675
/* Updated time. */
685676
gettimeofday(&tv, NULL);
686-
write_32(&c, tv.tv_usec);
677+
fallback_seed_add(&c, &tv, sizeof(tv));
687678
} else {
688679
/* Current time. */
689680
gettimeofday(&tv, NULL);
690-
write_32(&c, tv.tv_sec);
691-
write_32(&c, tv.tv_usec);
681+
fallback_seed_add(&c, &tv, sizeof(tv));
692682
/* Previous state. */
693-
PHP_SHA1Update(&c, RANDOM_G(fallback_seed), 20);
683+
fallback_seed_add(&c, RANDOM_G(fallback_seed), 20);
694684
}
695685
PHP_SHA1Final(RANDOM_G(fallback_seed), &c);
696686
RANDOM_G(fallback_seed_initialized) = true;

0 commit comments

Comments
 (0)