Skip to content

Commit

Permalink
Merge branch 'master' into stream_php
Browse files Browse the repository at this point in the history
  • Loading branch information
jvoisin authored Jun 6, 2024
2 parents 57e65f7 + 849252c commit 6cd73c4
Show file tree
Hide file tree
Showing 28 changed files with 65 additions and 56 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ linked-clone:

tests: release tests-incremental ## compile a release build and run the testsuite

tests-incremental:
tests-incremental: ## perform an incremental build and run the testsuite
make -C $(SRC)
TEST_PHP_ARGS='-q' REPORT_EXIT_STATUS=1 SP_SKIP_OLD_PHP_CHECK=1 make -C $(SRC) test

Expand Down
2 changes: 1 addition & 1 deletion config/xenforo.rules
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This is a sample configuration for Snuffleupagus to accomodate Xenforo v2.2.12 on PHP 8.1
# This is a sample configuration for Snuffleupagus to accommodate Xenforo v2.2.12 on PHP 8.1
# We keep the default configuration values commented out where they have been shown to be harmful

# Global configuration variables
Expand Down
2 changes: 1 addition & 1 deletion doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Breaking Changes
Bug fixes
^^^^^^^^^
* Make it actually possible to configure sloppy comparison on latests PHP7
* Allow file:// prefix in include() wich readonly_exec mode
* Allow file:// prefix in include() with readonly_exec mode
* Fix a possible crash when exporting function list
* Fix a minor memory leak when parsing cookie-related configuration

Expand Down
2 changes: 1 addition & 1 deletion doc/source/cookies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ It can either be set to ``strict`` or ``lax``:
- The ``lax`` attribute prevents cookies from being sent cross-domain for
"dangerous" methods, like ``POST``, ``PUT`` or ``DELETE``.

- The ``strict`` one prevents any cookies from beind sent cross-domain.
- The ``strict`` one prevents any cookies from being sent cross-domain.

::

Expand Down
2 changes: 1 addition & 1 deletion doc/source/debug.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Debugging crashes

.. _testsuite_fail:

The testsuite is failling
The testsuite is failing
-------------------------

We're using `php qa <https://qa.php.net/>`__ tests format for our testsuite,
Expand Down
2 changes: 1 addition & 1 deletion doc/source/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ to restrict execution to users on the LAN for example. There are a *lot*
of different filters, so make sure to read the :ref:`corresponding documentation <virtual-patching-config>`.

Furthermore, running the `following script <https://github.com/nbs-system/snuffleupagus/blob/master/scripts/generate_rules.php>`_ will generate an hash and line-based whitelist
of dangerous functions, droping them everywhere else:
of dangerous functions, dropping them everywhere else:


.. literalinclude:: ../../scripts/generate_rules.php
Expand Down
2 changes: 2 additions & 0 deletions src/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter"
CFLAGS="$CFLAGS -Wformat=2 -Wformat-security -D_FORTIFY_SOURCE=2"
CFLAGS="$CFLAGS -fstack-protector-strong"
CFLAGS="$CFLAGS -Wmissing-format-attribute -Wmissing-noreturn -Wpointer-arith"
CFLAGS="$CFLAGS -Wstrict-prototypes -Wunused -Wwrite-strings"

LDFLAGS="$LDFLAGS `pcre2-config --libs8`"

Expand Down
6 changes: 3 additions & 3 deletions src/snuffleupagus.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ ZEND_DLEXPORT zend_extension zend_extension_entry = {
NULL, /* op_array_dtor_func_t */
STANDARD_ZEND_EXTENSION_PROPERTIES};

static void sp_load_other_modules() {
static void sp_load_other_modules(void) {
// try to load other modules before initializing Snuffleupagus
zend_module_entry *module;
bool should_start = false;
Expand Down Expand Up @@ -329,7 +329,7 @@ static void add_df_to_arr(zval *arr, sp_disabled_function const *const df) {
add_next_index_zval(arr, &arr_df);
}

static void dump_config() {
static void dump_config(void) {
zval arr;
php_serialize_data_t var_hash;
smart_str buf = {0};
Expand Down Expand Up @@ -622,7 +622,7 @@ static PHP_INI_MH(OnUpdateConfiguration) {
return SUCCESS;
}

const zend_function_entry snuffleupagus_functions[] = {PHP_FE_END};
static const zend_function_entry snuffleupagus_functions[] = {PHP_FE_END};

zend_module_entry snuffleupagus_module_entry = {
STANDARD_MODULE_HEADER,
Expand Down
2 changes: 1 addition & 1 deletion src/sp_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyw

if (!found_kw) {
zend_string *kwname = zend_string_init(kw->kw, kw->kwlen, 0);
sp_log_err("config", "Unexpected keyword '%s' on line %d", ZSTR_VAL(kwname), kw->lineno);
sp_log_err("config", "Unexpected keyword '%s' on line %zu", ZSTR_VAL(kwname), kw->lineno);
zend_string_release_ex(kwname, 0);
return FAILURE;
}
Expand Down
2 changes: 1 addition & 1 deletion src/sp_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ typedef struct {

typedef struct {
SP_PARSE_FN((*func));
char *token;
const char *token;
void *retval;
} sp_config_keyword;

Expand Down
6 changes: 3 additions & 3 deletions src/sp_config_scanner.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ typedef enum {
} sp_argtype;

typedef struct {
char *kw; // keyword points directly to the parsed input text and as such is not null-terminated
const char *kw; // keyword points directly to the parsed input text and as such is not null-terminated
size_t kwlen;
char *arg; // optional argument / can be not null terminated
const char *arg; // optional argument / can be not null terminated
size_t arglen;
sp_argtype argtype;
long lineno;
size_t lineno;
} sp_parsed_keyword;

zend_result sp_config_scan(const char *data, zend_result (*process_rule)(sp_parsed_keyword*));
Expand Down
42 changes: 21 additions & 21 deletions src/sp_config_scanner.re
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ static void str_dtor(zval *zv) {

// sy_ functions and macros are helpers for the shunting yard algorithm
#define sy_res_push(val) \
if (cond_res_i >= MAX_CONDITIONS) { cs_log_error("condition too complex on line %d", lineno); goto out; } \
if (cond_res_i >= MAX_CONDITIONS) { cs_log_error("condition too complex on line %zu", lineno); goto out; } \
cond_res[cond_res_i++] = val;
#define sy_res_pop() cond_res[--cond_res_i]
#define sy_op_push(op) \
if (cond_op_i >= MAX_CONDITIONS) { cs_log_error("condition too complex on line %d", lineno); goto out; } \
if (cond_op_i >= MAX_CONDITIONS) { cs_log_error("condition too complex on line %zu", lineno); goto out; } \
cond_op[cond_op_i++] = op;
#define sy_op_pop() cond_op[--cond_op_i]
#define sy_op_peek() cond_op[cond_op_i-1]
Expand Down Expand Up @@ -138,7 +138,7 @@ static int sy_apply_op(const char op, const int a, const int b) {
#define SY_APPLY_OP_FROM_STACK() \
char op = sy_op_pop(); \
int unary = (op == '!'); \
if (cond_res_i < (2 - unary)) { cs_log_error("not enough input on line %d", lineno); goto out; } \
if (cond_res_i < (2 - unary)) { cs_log_error("not enough input on line %zu", lineno); goto out; } \
int a = sy_res_pop(); \
int b = unary ? 0 : sy_res_pop(); \
int res = sy_apply_op(op, a, b); \
Expand Down Expand Up @@ -169,7 +169,7 @@ zend_result sp_config_scan(const char *data, zend_result (*process_rule)(sp_pars
int cond_op_i = 0;

int cond = yycinit;
long lineno = 1;
size_t lineno = 1;

/*!stags:re2c format = 'const char *@@;\n'; */
/*!re2c
Expand All @@ -189,16 +189,16 @@ zend_result sp_config_scan(const char *data, zend_result (*process_rule)(sp_pars
keyword = [a-zA-Z][a-zA-Z0-9_]*;
string = ["] ("\\"["] | [^"\r\n\x00])* ["];
<init> * { cs_log_error("parser error on line %d", lineno); goto out; }
<init> * { cs_log_error("parser error on line %zu", lineno); goto out; }
<init> whitespace+ { goto yyc_init; }
<init> [;#] [^\r\n\x00]* { goto yyc_init; }
<init> newline { lineno++; goto yyc_init; }
<init> "sp" { kw_i = 0; goto yyc_rule; }
<init> end { ret = SUCCESS; goto out; }
<init> "@"? "set" whitespace+ @t1 keyword @t2 whitespace+ @t3 string @t4 whitespace* ";" {
if (!cond_res[0]) { goto yyc_init; }
char *key = (char*)t1;
int keylen = t2 - t1;
const char *key = t1;
size_t keylen = t2 - t1;
zend_string *tmp = zend_hash_str_find_ptr(&vars, key, keylen);
if (tmp) {
zend_hash_str_del(&vars, key, keylen);
Expand All @@ -212,19 +212,19 @@ zend_result sp_config_scan(const char *data, zend_result (*process_rule)(sp_pars
<init> ( "@log" | "@info" ) whitespace+ @t1 string @t2 ";" {
if (!cond_res[0]) { goto yyc_init; }
TMPSTR(tmpstr, t2, t1);
cs_log_info("[line %d]: %s", lineno, tmpstr);
cs_log_info("[line %zu]: %s", lineno, tmpstr);
goto yyc_init;
}
<init> ( "@warn" | "@warning" ) whitespace+ @t1 string @t2 ";" {
if (!cond_res[0]) { goto yyc_init; }
TMPSTR(tmpstr, t2, t1);
cs_log_warning("[line %d]: %s", lineno, tmpstr);
cs_log_warning("[line %zu]: %s", lineno, tmpstr);
goto yyc_init;
}
<init> ( "@err" | "@error" ) whitespace+ @t1 string @t2 ";" {
if (!cond_res[0]) { goto yyc_init; }
TMPSTR(tmpstr, t2, t1);
cs_log_error("[line %d]: %s", lineno, tmpstr);
cs_log_error("[line %zu]: %s", lineno, tmpstr);
goto out;
}
Expand All @@ -236,15 +236,15 @@ zend_result sp_config_scan(const char *data, zend_result (*process_rule)(sp_pars
int is_loaded = (zend_hash_str_find_ptr(&module_registry, t3+1, t4-t3-2) != NULL);
sy_res_push(is_loaded);
} else {
cs_log_error("unknown function in condition on line %d", lineno);
cs_log_error("unknown function in condition on line %zu", lineno);
goto out;
}
goto yyc_cond_op;
}
<cond> @t1 keyword @t2 {
zend_string *tmp = zend_hash_str_find_ptr(&vars, t1, t2-t1);
if (!tmp) {
cs_log_error("unknown variable in condition on line %d", lineno);
cs_log_error("unknown variable in condition on line %zu", lineno);
goto out;
}
sy_res_push(atoi(ZSTR_VAL(tmp)));
Expand Down Expand Up @@ -280,33 +280,33 @@ zend_result sp_config_scan(const char *data, zend_result (*process_rule)(sp_pars
SY_APPLY_OP_FROM_STACK();
}
if (cond_op_i == 0 || sy_op_peek() != '(') {
cs_log_error("unbalanced parenthesis on line %d", lineno); goto out;
cs_log_error("unbalanced parenthesis on line %zu", lineno); goto out;
}
cond_op_i--;
goto yyc_cond_op;
}
<cond_op> ";" {
while (cond_op_i) {
if (sy_op_peek() == '(') { cs_log_error("unbalanced parenthesis on line %d", lineno); goto out; }
if (sy_op_peek() == '(') { cs_log_error("unbalanced parenthesis on line %zu", lineno); goto out; }
SY_APPLY_OP_FROM_STACK();
}
if (cond_res_i > 1) { cs_log_error("invalid condition on line %d", lineno); goto out; }
if (cond_res_i > 1) { cs_log_error("invalid condition on line %zu", lineno); goto out; }
goto yyc_init;
}
<cond, cond_op> * { cs_log_error("syntax error in condition on line %d", lineno); goto out; }
<cond, cond_op> * { cs_log_error("syntax error in condition on line %zu", lineno); goto out; }
<rule> whitespace+ { goto yyc_rule; }
<rule> newline / ( newline | whitespace )* "." { lineno++; goto yyc_rule; }
<rule> "." @t1 keyword @t2 ( "(" @t3 ( string? | keyword ) @t4 ")" )? {
if (!cond_res[0]) { goto yyc_rule; }
if (kw_i == MAX_KEYWORDS) {
cs_log_error("too many keywords in rule (more than %d) on line %d", MAX_KEYWORDS, lineno);
cs_log_error("too many keywords in rule (more than %d) on line %zu", MAX_KEYWORDS, lineno);
goto out;
}
sp_parsed_keyword kw = {
.kw = (char*)t1,
.kw = t1,
.kwlen = t2-t1,
.arg = (char*)t3,
.arg = t3,
.arglen = t4-t3,
.argtype = SP_ARGTYPE_UNKNOWN,
.lineno = lineno
Expand All @@ -315,13 +315,13 @@ zend_result sp_config_scan(const char *data, zend_result (*process_rule)(sp_pars
if (t3 == t4) {
kw.argtype = SP_ARGTYPE_EMPTY;
} else if (t4-t3 >= 2 && *t3 == '"') {
kw.arg = (char*)t3 + 1;
kw.arg = t3 + 1;
kw.arglen = t4 - t3 - 2;
kw.argtype = SP_ARGTYPE_STR;
} else {
zend_string *tmp = zend_hash_str_find_ptr(&vars, t3, t4-t3);
if (!tmp) {
cs_log_error("unknown variable on line %d", lineno);
cs_log_error("unknown variable on line %zu", lineno);
goto out;
}
kw.arg = ZSTR_VAL(tmp);
Expand Down
2 changes: 1 addition & 1 deletion src/sp_cookie_encryption.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ PHP_FUNCTION(sp_setcookie) {
zval *expires_or_options = NULL;
zend_bool secure = 0, httponly = 0;
const sp_cookie *cookie_node = NULL;
char *cookie_samesite;
const char *cookie_samesite;

// LCOV_EXCL_BR_START
ZEND_PARSE_PARAMETERS_START(1, 7)
Expand Down
4 changes: 2 additions & 2 deletions src/sp_crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ void generate_key(unsigned char *key) {
PHP_SHA256Init(&ctx);

if (user_agent) {
PHP_SHA256Update(&ctx, (unsigned char *)user_agent, strlen(user_agent));
PHP_SHA256Update(&ctx, (const unsigned char *)user_agent, strlen(user_agent));
}

if (env_var) {
PHP_SHA256Update(&ctx, (unsigned char *)env_var, strlen(env_var));
PHP_SHA256Update(&ctx, (const unsigned char *)env_var, strlen(env_var));
} else {
sp_log_warn("cookie_encryption",
"The environment variable '%s' "
Expand Down
1 change: 1 addition & 0 deletions src/sp_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ static inline void sp_execute_handler(INTERNAL_FUNCTION_PARAMETERS, bool interna
bool is_hooked = (zend_hash_str_find(SPG(disabled_functions_hook), VAR_AND_LEN(function_name)) || zend_hash_str_find(SPG(disabled_functions_hook), VAR_AND_LEN(function_name)));
if (is_hooked) {
sp_call_orig_execute(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal);
efree(function_name);
return;
}

Expand Down
4 changes: 2 additions & 2 deletions src/sp_ifilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static const char sp_is_dangerous_char[256] = {
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

static void sp_server_strip(HashTable *svars, char *key, int keylen) {
static void sp_server_strip(HashTable *svars, const char *key, size_t keylen) {
zval *value = zend_hash_str_find(svars, key, keylen);
if (!value || Z_TYPE_P(value) != IS_STRING) { return; }

Expand All @@ -39,7 +39,7 @@ static void sp_server_strip(HashTable *svars, char *key, int keylen) {
}
}

static void sp_server_encode(HashTable *svars, char *key, int keylen) {
static void sp_server_encode(HashTable *svars, const char *key, size_t keylen) {
zval *value = zend_hash_str_find(svars, key, keylen);
if (!value || Z_TYPE_P(value) != IS_STRING) { return; }

Expand Down
2 changes: 1 addition & 1 deletion src/sp_ifilter.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#pragma once

void sp_hook_register_server_variables();
void sp_hook_register_server_variables(void);
2 changes: 1 addition & 1 deletion src/sp_ini.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ static bool /* success */ sp_ini_check(zend_string *const restrict varname, zend
if (entry->msg) {
sp_log_ini_check_violation("%s", ZSTR_VAL(entry->msg));
} else {
sp_log_ini_check_violation("INI value %lld for `%s` out of range", lvalue, ZSTR_VAL(entry->key));
sp_log_ini_check_violation("INI value " ZEND_LONG_FMT " for `%s` out of range", lvalue, ZSTR_VAL(entry->key));
}
return simulation;
}
Expand Down
4 changes: 2 additions & 2 deletions src/sp_ini.h
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
void sp_hook_ini();
void sp_unhook_ini();
void sp_hook_ini(void);
void sp_unhook_ini(void);
4 changes: 2 additions & 2 deletions src/sp_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static int sp_hook_s_write(PS_WRITE_ARGS) {
return old_s_write(mod_data, key, val, maxlifetime);
}

static void sp_hook_session_module() {
static void sp_hook_session_module(void) {
#if PHP_VERSION_ID < 70300
ps_module *old_mod = SESSION_G(mod);
#else
Expand Down Expand Up @@ -108,7 +108,7 @@ static void sp_hook_session_module() {

static PHP_INI_MH(sp_OnUpdateSaveHandler) {
#if PHP_VERSION_ID < 70100
/* PHP7.0 doesn't handle well recusively set session handlers */
/* PHP7.0 doesn't handle well recursively set session handlers */
if (stage == PHP_INI_STAGE_RUNTIME &&
SESSION_G(session_status) == php_session_none && s_original_mod &&
zend_string_equals_literal(new_value, "user") == 0 &&
Expand Down
2 changes: 2 additions & 0 deletions src/sp_unserialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ PHP_FUNCTION(sp_unserialize) {
}
} else { status = 1; }

#if ! (PHP_VERSION_ID >= 80300)
zif_handler orig_handler = zend_hash_str_find_ptr(SPG(sp_internal_functions_hook), ZEND_STRL("unserialize"));
#endif
if (0 == status) {
#if PHP_VERSION_ID >= 80300
// PHP8.3 gives a warning about trailing data in unserialize strings.
Expand Down
5 changes: 2 additions & 3 deletions src/sp_upload_validation.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#include "php_snuffleupagus.h"

int (*sp_rfc1867_orig_callback)(unsigned int event, void *event_data,
static int (*sp_rfc1867_orig_callback)(unsigned int event, void *event_data,
void **extra);
int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra);

#define EFREE_3(env) \
for (size_t i = 0; i < 4; i++) { \
Expand All @@ -23,7 +22,7 @@ int sp_rfc1867_callback_win(unsigned int event, void *event_data,

#else

int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra) {
static int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra) {
int retval = SUCCESS;

if (sp_rfc1867_orig_callback) {
Expand Down
2 changes: 1 addition & 1 deletion src/sp_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ bool sp_match_array_value(const zval* arr, const zend_string* to_match, const sp
return false;
}

bool /* success */ _hook_function(const char* original_name, HashTable* hook_table, zif_handler new_function) {
static bool /* success */ _hook_function(const char* original_name, HashTable* hook_table, zif_handler new_function) {
zend_function* func;
if ((func = zend_hash_str_find_ptr(CG(function_table), VAR_AND_LEN(original_name)))) {
if (func->type != ZEND_INTERNAL_FUNCTION) {
Expand Down
Loading

0 comments on commit 6cd73c4

Please sign in to comment.