diff options
| author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-11-12 17:32:47 -0500 |
|---|---|---|
| committer | Glenn Strauss <gstrauss@gluelogic.com> | 2021-11-15 11:59:18 -0500 |
| commit | 251f97bf4f2e7bc45f2ab053c91668a6eb4c709f (patch) | |
| tree | 818a690f59212ccbfa6dff5771d75b31b5ec5889 /src | |
| parent | 9b3fa6eb2b70ad3075136c557e0f1384216e1b5c (diff) | |
| download | lighttpd-git-251f97bf4f2e7bc45f2ab053c91668a6eb4c709f.tar.gz | |
[tests] t/test_mod_alias.c
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/Makefile.am | 1 | ||||
| -rw-r--r-- | src/meson.build | 1 | ||||
| -rw-r--r-- | src/t/test_mod.c | 2 | ||||
| -rw-r--r-- | src/t/test_mod_alias.c | 111 |
5 files changed, 116 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index df392141..5d4de88c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -911,6 +911,7 @@ add_executable(test_mod ${COMMON_SRC} t/test_mod.c t/test_mod_access.c + t/test_mod_alias.c t/test_mod_evhost.c t/test_mod_indexfile.c t/test_mod_simple_vhost.c diff --git a/src/Makefile.am b/src/Makefile.am index a8599501..8b20307c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -644,6 +644,7 @@ t_test_keyvalue_LDADD = $(PCRE_LIB) $(LIBUNWIND_LIBS) t_test_mod_SOURCES = $(common_src) t/test_mod.c \ t/test_mod_access.c \ + t/test_mod_alias.c \ t/test_mod_evhost.c \ t/test_mod_indexfile.c \ t/test_mod_simple_vhost.c \ diff --git a/src/meson.build b/src/meson.build index 22c142d2..21ef800e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -926,6 +926,7 @@ test('test_mod', executable('test_mod', common_src, 't/test_mod.c', 't/test_mod_access.c', + 't/test_mod_alias.c', 't/test_mod_evhost.c', 't/test_mod_indexfile.c', 't/test_mod_simple_vhost.c', diff --git a/src/t/test_mod.c b/src/t/test_mod.c index 09e6a433..19a58261 100644 --- a/src/t/test_mod.c +++ b/src/t/test_mod.c @@ -4,6 +4,7 @@ #include <assert.h> void test_mod_access (void); +void test_mod_alias (void); void test_mod_evhost (void); void test_mod_indexfile (void); void test_mod_simple_vhost (void); @@ -13,6 +14,7 @@ void test_mod_userdir (void); int main() { test_mod_access(); + test_mod_alias(); test_mod_evhost(); test_mod_indexfile(); test_mod_simple_vhost(); diff --git a/src/t/test_mod_alias.c b/src/t/test_mod_alias.c new file mode 100644 index 00000000..2510c96a --- /dev/null +++ b/src/t/test_mod_alias.c @@ -0,0 +1,111 @@ +#include "first.h" + +#undef NDEBUG +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "mod_alias.c" + +static void test_mod_alias_check(void) { + request_st r; + memset(&r, 0, sizeof(request_st)); + array * const aliases = array_init(3); + + /*(empty list; should not happen in practice)*/ + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + + /* Use-after-free bug in mod_alias + * https://redmine.lighttpd.net/issues/3114 */ + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/"), CONST_STR_LEN( + "/very-long-path/longer-than-64/intended-to-trigger-str-reallocation/")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + assert(0 == strcmp(r.physical.basedir.ptr, + "/very-long-path/longer-than-64/intended-to-trigger-str-reallocation/")); + assert(0 == strcmp(r.physical.path.ptr, + "/very-long-path/longer-than-64/intended-to-trigger-str-reallocation/")); + + /*(admin should prefer to match dirs with trailing '/', but test w/o)*/ + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp/")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/"), CONST_STR_LEN("/var/tmp")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp")); + assert(0 == strcmp(r.physical.path.ptr, "/var/tmp")); + + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/foo"), + CONST_STR_LEN("/var/tmp/")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp/")); + assert(0 == strcmp(r.physical.path.ptr, "/var/tmp/")); + + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/fooddd")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/foo"), + CONST_STR_LEN("/var/tmp/")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp/")); + assert(0 == strcmp(r.physical.path.ptr, "/var/tmp/ddd")); + + /* security: path traversal in mod_alias (in some use cases) + * https://redmine.lighttpd.net/issues/2898 */ + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo../bad")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/foo"), + CONST_STR_LEN("/var/tmp/")); + assert(HANDLER_FINISHED == mod_alias_remap(&r, aliases)); + assert(403 == r.http_status); + r.http_status = 0; + + /* replacement longer */ + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo/x")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/foo/"), + CONST_STR_LEN("/opt/var/tmp/")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + assert(0 == strcmp(r.physical.basedir.ptr, "/opt/var/tmp/")); + assert(0 == strcmp(r.physical.path.ptr, "/opt/var/tmp/x")); + + /* replacement shorter */ + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo/x")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/foo/"), + CONST_STR_LEN("/ba/")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + assert(0 == strcmp(r.physical.basedir.ptr, "/ba/")); + assert(0 == strcmp(r.physical.path.ptr, "/ba/x")); + + /* replacement same length */ + buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); + buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo/x")); + array_reset_data_strings(aliases); + array_set_key_value(aliases, CONST_STR_LEN("/foo/"), + CONST_STR_LEN("/var/tmp/")); + assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); + assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp/")); + assert(0 == strcmp(r.physical.path.ptr, "/var/tmp/x")); + + array_free(aliases); + free(r.physical.path.ptr); + free(r.physical.basedir.ptr); +} + +void test_mod_alias (void); +void test_mod_alias (void) +{ + test_mod_alias_check(); +} |
