summaryrefslogtreecommitdiff
path: root/src/sp_utils.c
diff options
context:
space:
mode:
authorjvoisin2022-07-13 01:11:44 +0200
committerjvoisin2022-07-13 01:21:45 +0200
commit3dbb2f3feeec54c4ab6b2efc53b5c5635dbd9129 (patch)
treeda7fafe6c25eba2e28f20158d2bd9d78bb9740a6 /src/sp_utils.c
parenteaba9e0e7421fec0bc7a0cd8745dc3fb4e2e72f1 (diff)
Mix the stacktrace in the sha256 for the filename of .dump()
This should make it easier to fuzz using Snuffleupagus.
Diffstat (limited to 'src/sp_utils.c')
-rw-r--r--src/sp_utils.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/src/sp_utils.c b/src/sp_utils.c
index 2ec1750..fdcdc99 100644
--- a/src/sp_utils.c
+++ b/src/sp_utils.c
@@ -93,32 +93,12 @@ int compute_hash(const char* const restrict filename,
93static int construct_filename(char* filename, 93static int construct_filename(char* filename,
94 const zend_string* restrict folder, 94 const zend_string* restrict folder,
95 const zend_string* restrict textual) { 95 const zend_string* restrict textual) {
96 PHP_SHA256_CTX context;
97 unsigned char digest[SHA256_SIZE] = {0};
98 char strhash[65] = {0};
99
100 if (-1 == mkdir(ZSTR_VAL(folder), 0700) && errno != EEXIST) {
101 sp_log_warn("request_logging", "Unable to create the folder '%s'",
102 ZSTR_VAL(folder));
103 return -1;
104 }
105
106 /* We're using the sha256 sum of the rule's textual representation
107 * as filename, in order to only have one dump per rule, to mitigate
108 * DoS attacks. */
109 PHP_SHA256Init(&context);
110 PHP_SHA256Update(&context, (const unsigned char*)ZSTR_VAL(textual),
111 ZSTR_LEN(textual));
112 PHP_SHA256Final(digest, &context);
113 make_digest_ex(strhash, digest, SHA256_SIZE);
114 snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", ZSTR_VAL(folder), strhash);
115
116 return 0; 96 return 0;
117} 97}
118 98
119int sp_log_request(const zend_string* restrict folder, const zend_string* restrict text_repr) { 99int sp_log_request(const zend_string* restrict folder, const zend_string* restrict text_repr) {
120 FILE* file; 100 FILE* file;
121 const char* current_filename = zend_get_executed_filename(TSRMLS_C); 101 char const* const current_filename = zend_get_executed_filename(TSRMLS_C);
122 const int current_line = zend_get_executed_lineno(TSRMLS_C); 102 const int current_line = zend_get_executed_lineno(TSRMLS_C);
123 char filename[PATH_MAX] = {0}; 103 char filename[PATH_MAX] = {0};
124 const struct { 104 const struct {
@@ -128,9 +108,41 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
128 {"COOKIE", TRACK_VARS_COOKIE}, {"SERVER", TRACK_VARS_SERVER}, 108 {"COOKIE", TRACK_VARS_COOKIE}, {"SERVER", TRACK_VARS_SERVER},
129 {"ENV", TRACK_VARS_ENV}, {NULL, 0}}; 109 {"ENV", TRACK_VARS_ENV}, {NULL, 0}};
130 110
131 if (0 != construct_filename(filename, folder, text_repr)) { 111 PHP_SHA256_CTX context;
112 unsigned char digest[SHA256_SIZE] = {0};
113 char strhash[65] = {0};
114
115 if (-1 == mkdir(ZSTR_VAL(folder), 0700) && errno != EEXIST) {
116 sp_log_warn("request_logging", "Unable to create the folder '%s'",
117 ZSTR_VAL(folder));
132 return -1; 118 return -1;
133 } 119 }
120
121 /* We're using the sha256 sum of the rule's textual representation, as well
122 * as the stacktrace as filename, in order to only have one dump per rule, to
123 * mitigate DoS attacks. We're doing the walk-the-execution-context dance
124 * twice because it's easier than to cache it in a linked-list. It doesn't
125 * really matter, since this is a super-cold path anyway.
126 */
127 PHP_SHA256Init(&context);
128 PHP_SHA256Update(&context, (const unsigned char*)ZSTR_VAL(text_repr), ZSTR_LEN(text_repr));
129 zend_execute_data* orig_execute_data = EG(current_execute_data);
130 zend_execute_data* current = EG(current_execute_data);
131 while (current) {
132 EG(current_execute_data) = current;
133 char* const complete_path_function = get_complete_function_path(current);
134 if (complete_path_function) {
135 const int current_line = zend_get_executed_lineno(TSRMLS_C);
136 PHP_SHA256Update(&context, (const unsigned char*)complete_path_function, strlen(complete_path_function));
137 efree(complete_path_function);
138 }
139 current = current->prev_execute_data;
140 }
141 EG(current_execute_data) = orig_execute_data;
142 PHP_SHA256Final(digest, &context);
143 make_digest_ex(strhash, digest, SHA256_SIZE);
144 snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", ZSTR_VAL(folder), strhash);
145
134 if (NULL == (file = fopen(filename, "w+"))) { 146 if (NULL == (file = fopen(filename, "w+"))) {
135 sp_log_warn("request_logging", "Unable to open %s: %s", filename, 147 sp_log_warn("request_logging", "Unable to open %s: %s", filename,
136 strerror(errno)); 148 strerror(errno));
@@ -141,8 +153,8 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri
141 153
142 fprintf(file, "FILE: %s:%d\n", current_filename, current_line); 154 fprintf(file, "FILE: %s:%d\n", current_filename, current_line);
143 155
144 zend_execute_data* orig_execute_data = EG(current_execute_data); 156 orig_execute_data = EG(current_execute_data);
145 zend_execute_data* current = EG(current_execute_data); 157 current = EG(current_execute_data);
146 while (current) { 158 while (current) {
147 EG(current_execute_data) = current; 159 EG(current_execute_data) = current;
148 char* const complete_path_function = get_complete_function_path(current); 160 char* const complete_path_function = get_complete_function_path(current);