summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-11-12 17:32:47 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2021-11-15 11:59:18 -0500
commit251f97bf4f2e7bc45f2ab053c91668a6eb4c709f (patch)
tree818a690f59212ccbfa6dff5771d75b31b5ec5889 /src
parent9b3fa6eb2b70ad3075136c557e0f1384216e1b5c (diff)
downloadlighttpd-git-251f97bf4f2e7bc45f2ab053c91668a6eb4c709f.tar.gz
[tests] t/test_mod_alias.c
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/meson.build1
-rw-r--r--src/t/test_mod.c2
-rw-r--r--src/t/test_mod_alias.c111
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();
+}