Skip to content

Commit

Permalink
Merge branch 'master' into curl_file_protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
jvoisin authored Jun 8, 2024
2 parents 3ea7ce2 + cf534c8 commit 13fb2df
Show file tree
Hide file tree
Showing 36 changed files with 89 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
container:
- php:8.3-rc
- php:8.3
- php:8.2
- php:8.1
- php:8.0
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/distributions_php8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- cron: '0 16 * * 5'

jobs:
alpine_81:
alpine_82:
runs-on: ubuntu-latest
container: alpine:edge
steps:
Expand All @@ -17,7 +17,7 @@ jobs:
- name: Remove tests failing on alpine for wathever reason
run: rm -rf src/tests/*session*/ src/tests/broken_configuration/ src/tests/*cookie* src/tests/upload_validation/
- name: Install dependencies
run: apk add php81-dev php81-cgi php81-simplexml php81-xml pcre-dev build-base php81-pear php81-openssl re2c
run: apk add php82-dev php82-cgi php82-simplexml php82-xml pcre-dev build-base php82-pear php82-openssl re2c
- name: Install pecl
continue-on-error: true
run: pecl install vld-beta
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ linked-clone:
cp -r $$SRCDIR/tests .
@echo -e "==> DONE. <==\nCompile a debug build with\n make compile_debug SRC=src-$(CLONE)"

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

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

coverage: ## compile snuffleugpaus, and run the testsuite with coverage
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 debian/rules
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export DEB_BUILD_MAINT_OPTIONS = hardening=+all
%:
dh $@ --sourcedirectory src --with php

override_dh_auto_clean:
execute_after_dh_auto_clean:
cd ./src; phpize --clean

override_dh_auto_configure:
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
7 changes: 6 additions & 1 deletion scripts/generate_rules.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ function help($name) {
'posix_kill', 'posix_mkfifo', 'posix_setpgid', 'posix_setsid', 'posix_setuid',
'posix_setgid', 'posix_uname', 'proc_close', 'proc_nice', 'proc_open',
'proc_terminate', 'proc_open', 'proc_get_status', 'dl', 'pnctl_exec',
'pnctl_fork', 'assert', 'system', 'curl_exec', 'curl_multi_exec', 'function_exists'];
'pnctl_fork', 'system', 'curl_exec', 'curl_multi_exec', 'function_exists'];

// In PHP < 8.0x you could execute code using assert()
if (PHP_VERSION_ID < 80000) {
$functions_blacklist[] = 'assert';
}

$extensions = ['php', 'php7', 'php5', 'inc'];

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
8 changes: 4 additions & 4 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 @@ -327,7 +327,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 @@ -387,7 +387,7 @@ static void dump_config() {
add_assoc_long(&arr, SP_TOKEN_SESSION_ENCRYPTION "." SP_TOKEN_SID_MAX_LENGTH, SPCFG(session).sid_max_length);
add_assoc_bool(&arr, SP_TOKEN_SLOPPY_COMPARISON "." SP_TOKEN_ENABLE, SPCFG(sloppy).enable);

ADD_ASSOC_SPLIST(&arr, SP_TOKEN_ALLOW_WRAPPERS, SPCFG(wrapper).whitelist);
ADD_ASSOC_SPLIST(&arr, SP_TOKEN_ALLOW_WRAPPERS "." SP_TOKEN_LIST, SPCFG(wrapper).whitelist);

#undef ADD_ASSOC_SPLIST

Expand Down Expand Up @@ -619,7 +619,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
4 changes: 2 additions & 2 deletions 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 Expand Up @@ -217,7 +217,7 @@ SP_PARSEKW_FN(parse_cidr) {
CHECK_DUPLICATE_KEYWORD(retval);
SP_PARSE_ARG(value);

sp_cidr *cidr = pecalloc(sizeof(sp_cidr), 1, 1);
sp_cidr *cidr = pecalloc(1, sizeof(sp_cidr), 1);

if (0 != get_ip_and_cidr(ZSTR_VAL(value), cidr)) {
pefree(cidr, 1);
Expand Down
2 changes: 1 addition & 1 deletion src/sp_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,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_keywords.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ SP_PARSE_FN(parse_wrapper_whitelist) {

SP_PARSE_FN(parse_cookie) {
zend_string *samesite = NULL;
sp_cookie *cookie = pecalloc(sizeof(sp_cookie), 1, 1);
sp_cookie *cookie = pecalloc(1, sizeof(sp_cookie), 1);

sp_config_keyword config_keywords[] = {
{parse_str, SP_TOKEN_NAME, &(cookie->name)},
Expand Down Expand Up @@ -302,7 +302,7 @@ SP_PARSE_FN(parse_disabled_functions) {
int ret = SP_PARSER_ERROR;
bool enable = false, disable = false, allow = false, drop = false;
zend_string *var = NULL, *param = NULL;
sp_disabled_function *df = pecalloc(sizeof(*df), 1, 1);
sp_disabled_function *df = pecalloc(1, sizeof(*df), 1);
df->pos = -1;

sp_config_keyword config_keywords[] = {
Expand Down Expand Up @@ -507,7 +507,7 @@ SP_PARSE_FN(parse_ini_protection) {
}

SP_PARSE_FN(parse_ini_entry) {
sp_ini_entry *entry = pecalloc(sizeof(sp_ini_entry), 1, 1);
sp_ini_entry *entry = pecalloc(1, sizeof(sp_ini_entry), 1);
bool rw = false, ro = false;

sp_config_keyword config_keywords[] = {
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
Loading

0 comments on commit 13fb2df

Please sign in to comment.