summaryrefslogtreecommitdiff
path: root/Zend/zend_system_id.c
diff options
context:
space:
mode:
authorSammy Kaye Powers <sammyk@php.net>2020-07-16 16:31:10 -0700
committerSammy Kaye Powers <sammyk@php.net>2020-09-18 14:26:44 -0700
commit12306728c5f37dc371bc39f5fe2bf8e928368235 (patch)
treeeed1bf4671bc1c46e6a8e7a30b07bd4e9a7bc1d2 /Zend/zend_system_id.c
parent30bb15b24a266eae1577b68cd980241b1a5adf40 (diff)
downloadphp-git-12306728c5f37dc371bc39f5fe2bf8e928368235.tar.gz
Add system ID entropy API
The `zend_system_id` is a (true global) system ID that fingerprints a process state. When extensions add engine hooks during MINIT/startup, entropy is added the system ID for each hook. This allows extensions to identify that changes have been made to the engine since the last PHP process restart. Closes GH-5871
Diffstat (limited to 'Zend/zend_system_id.c')
-rw-r--r--Zend/zend_system_id.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/Zend/zend_system_id.c b/Zend/zend_system_id.c
new file mode 100644
index 0000000000..93bca57b0c
--- /dev/null
+++ b/Zend/zend_system_id.c
@@ -0,0 +1,91 @@
+/*
+ +----------------------------------------------------------------------+
+ | Copyright (c) The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Sammy Kaye Powers <sammyk@php.net> |
+ | Dmitry Stogov <dmitry@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "php.h"
+#include "zend_system_id.h"
+#include "zend_extensions.h"
+#include "ext/standard/md5.h"
+#include "ext/hash/php_hash.h"
+
+ZEND_API char zend_system_id[32];
+
+static PHP_MD5_CTX context;
+static int finalized = 0;
+
+ZEND_API ZEND_RESULT_CODE zend_add_system_entropy(const char *module_name, const char *hook_name, const void *data, size_t size)
+{
+ if (finalized == 0) {
+ PHP_MD5Update(&context, module_name, strlen(module_name));
+ PHP_MD5Update(&context, hook_name, strlen(hook_name));
+ if (size) {
+ PHP_MD5Update(&context, data, size);
+ }
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
+#define ZEND_BIN_ID "BIN_" ZEND_TOSTR(SIZEOF_INT) ZEND_TOSTR(SIZEOF_LONG) ZEND_TOSTR(SIZEOF_SIZE_T) ZEND_TOSTR(SIZEOF_ZEND_LONG) ZEND_TOSTR(ZEND_MM_ALIGNMENT)
+
+void zend_startup_system_id(void)
+{
+ PHP_MD5Init(&context);
+ PHP_MD5Update(&context, PHP_VERSION, sizeof(PHP_VERSION)-1);
+ PHP_MD5Update(&context, ZEND_EXTENSION_BUILD_ID, sizeof(ZEND_EXTENSION_BUILD_ID)-1);
+ PHP_MD5Update(&context, ZEND_BIN_ID, sizeof(ZEND_BIN_ID)-1);
+ if (strstr(PHP_VERSION, "-dev") != 0) {
+ /* Development versions may be changed from build to build */
+ PHP_MD5Update(&context, __DATE__, sizeof(__DATE__)-1);
+ PHP_MD5Update(&context, __TIME__, sizeof(__TIME__)-1);
+ }
+ zend_system_id[0] = '\0';
+}
+
+#define ZEND_HOOK_AST_PROCESS (1 << 0)
+#define ZEND_HOOK_COMPILE_FILE (1 << 1)
+#define ZEND_HOOK_EXECUTE_EX (1 << 2)
+#define ZEND_HOOK_EXECUTE_INTERNAL (1 << 3)
+
+void zend_finalize_system_id(void)
+{
+ unsigned char digest[16];
+ zend_uchar hooks = 0;
+
+ if (zend_ast_process) {
+ hooks |= ZEND_HOOK_AST_PROCESS;
+ }
+ if (zend_compile_file != compile_file) {
+ hooks |= ZEND_HOOK_COMPILE_FILE;
+ }
+ if (zend_execute_ex != execute_ex) {
+ hooks |= ZEND_HOOK_EXECUTE_EX;
+ }
+ if (zend_execute_internal) {
+ hooks |= ZEND_HOOK_EXECUTE_INTERNAL;
+ }
+ PHP_MD5Update(&context, &hooks, sizeof hooks);
+
+ for (int16_t i = 0; i < 256; i++) {
+ if (zend_get_user_opcode_handler((zend_uchar) i) != NULL) {
+ PHP_MD5Update(&context, &i, sizeof i);
+ }
+ }
+
+ PHP_MD5Final(digest, &context);
+ php_hash_bin2hex(zend_system_id, digest, sizeof digest);
+ finalized = 1;
+}