xref: /PHP-8.3/sapi/fuzzer/fuzzer-function-jit.c (revision 9d5f2f13)
1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | https://www.php.net/license/3_01.txt                                 |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors: Nikita Popov <nikic@php.net>                                |
14    +----------------------------------------------------------------------+
15  */
16 
17 #include "fuzzer-execute-common.h"
18 
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)19 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
20 	if (Size > MAX_SIZE) {
21 		/* Large inputs have a large impact on fuzzer performance,
22 		 * but are unlikely to be necessary to reach new codepaths. */
23 		return 0;
24 	}
25 
26 	zend_string *jit_option = ZSTR_INIT_LITERAL("opcache.jit", 1);
27 
28 	/* First run without JIT to determine whether we bail out. We should not run JITed code if
29 	 * we bail out here, as the JIT code may loop infinitely. */
30 	steps_left = MAX_STEPS;
31 	bailed_out = false;
32 	zend_alter_ini_entry_chars(
33 		jit_option, "off", sizeof("off")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
34 	fuzzer_do_request_from_buffer(
35 		FILE_NAME, (const char *) Data, Size, /* execute */ 1, opcache_invalidate);
36 
37 	if (!bailed_out) {
38 		steps_left = MAX_STEPS;
39 		zend_alter_ini_entry_chars(jit_option,
40 			"function", sizeof("function")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
41 		zend_execute_ex = orig_execute_ex;
42 		fuzzer_do_request_from_buffer(
43 			FILE_NAME, (const char *) Data, Size, /* execute */ 1, opcache_invalidate);
44 		zend_execute_ex = fuzzer_execute_ex;
45 	}
46 
47 	zend_string_release(jit_option);
48 
49 	return 0;
50 }
51 
LLVMFuzzerInitialize(int * argc,char *** argv)52 int LLVMFuzzerInitialize(int *argc, char ***argv) {
53 	char *opcache_path = get_opcache_path();
54 	assert(opcache_path && "Failed to determine opcache path");
55 
56 	char ini_buf[512];
57 	snprintf(ini_buf, sizeof(ini_buf),
58 		"zend_extension=%s\n"
59 		"opcache.validate_timestamps=0\n"
60 		"opcache.file_update_protection=0\n"
61 		"opcache.jit_buffer_size=256M",
62 		opcache_path);
63 	free(opcache_path);
64 
65 	create_file();
66 	fuzzer_init_php_for_execute(ini_buf);
67 	return 0;
68 }
69