[tests] t/test_mod_alias.c

master
Glenn Strauss 1 year ago
parent 9b3fa6eb2b
commit 251f97bf4f

@ -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

@ -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 \

@ -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',

@ -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();

@ -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();
}
Loading…
Cancel
Save