1 #include "first.h" 2 3 #undef NDEBUG 4 #include <assert.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 9 #include "mod_alias.c" 10 11 static void test_mod_alias_check(void) { 12 request_st r; 13 memset(&r, 0, sizeof(request_st)); 14 array * const aliases = array_init(3); 15 16 /*(empty list; should not happen in practice)*/ 17 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 18 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/")); 19 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 20 21 /* Use-after-free bug in mod_alias 22 * https://redmine.lighttpd.net/issues/3114 */ 23 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 24 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/")); 25 array_reset_data_strings(aliases); 26 array_set_key_value(aliases, CONST_STR_LEN("/"), CONST_STR_LEN( 27 "/very-long-path/longer-than-64/intended-to-trigger-str-reallocation/")); 28 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 29 assert(0 == strcmp(r.physical.basedir.ptr, 30 "/very-long-path/longer-than-64/intended-to-trigger-str-reallocation/")); 31 assert(0 == strcmp(r.physical.path.ptr, 32 "/very-long-path/longer-than-64/intended-to-trigger-str-reallocation/")); 33 34 /*(admin should prefer to match dirs with trailing '/', but test w/o)*/ 35 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp/")); 36 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/")); 37 array_reset_data_strings(aliases); 38 array_set_key_value(aliases, CONST_STR_LEN("/"), CONST_STR_LEN("/var/tmp")); 39 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 40 assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp")); 41 assert(0 == strcmp(r.physical.path.ptr, "/var/tmp")); 42 43 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 44 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo")); 45 array_reset_data_strings(aliases); 46 array_set_key_value(aliases, CONST_STR_LEN("/foo"), 47 CONST_STR_LEN("/var/tmp/")); 48 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 49 assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp/")); 50 assert(0 == strcmp(r.physical.path.ptr, "/var/tmp/")); 51 52 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 53 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/fooddd")); 54 array_reset_data_strings(aliases); 55 array_set_key_value(aliases, CONST_STR_LEN("/foo"), 56 CONST_STR_LEN("/var/tmp/")); 57 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 58 assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp/")); 59 assert(0 == strcmp(r.physical.path.ptr, "/var/tmp/ddd")); 60 61 /* security: path traversal in mod_alias (in some use cases) 62 * https://redmine.lighttpd.net/issues/2898 */ 63 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 64 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo../bad")); 65 array_reset_data_strings(aliases); 66 array_set_key_value(aliases, CONST_STR_LEN("/foo"), 67 CONST_STR_LEN("/var/tmp/")); 68 assert(HANDLER_FINISHED == mod_alias_remap(&r, aliases)); 69 assert(403 == r.http_status); 70 r.http_status = 0; 71 72 /* replacement longer */ 73 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 74 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo/x")); 75 array_reset_data_strings(aliases); 76 array_set_key_value(aliases, CONST_STR_LEN("/foo/"), 77 CONST_STR_LEN("/opt/var/tmp/")); 78 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 79 assert(0 == strcmp(r.physical.basedir.ptr, "/opt/var/tmp/")); 80 assert(0 == strcmp(r.physical.path.ptr, "/opt/var/tmp/x")); 81 82 /* replacement shorter */ 83 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 84 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo/x")); 85 array_reset_data_strings(aliases); 86 array_set_key_value(aliases, CONST_STR_LEN("/foo/"), 87 CONST_STR_LEN("/ba/")); 88 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 89 assert(0 == strcmp(r.physical.basedir.ptr, "/ba/")); 90 assert(0 == strcmp(r.physical.path.ptr, "/ba/x")); 91 92 /* replacement same length */ 93 buffer_copy_string_len(&r.physical.basedir, CONST_STR_LEN("/tmp")); 94 buffer_copy_string_len(&r.physical.path, CONST_STR_LEN("/tmp/foo/x")); 95 array_reset_data_strings(aliases); 96 array_set_key_value(aliases, CONST_STR_LEN("/foo/"), 97 CONST_STR_LEN("/var/tmp/")); 98 assert(HANDLER_GO_ON == mod_alias_remap(&r, aliases)); 99 assert(0 == strcmp(r.physical.basedir.ptr, "/var/tmp/")); 100 assert(0 == strcmp(r.physical.path.ptr, "/var/tmp/x")); 101 102 array_free(aliases); 103 free(r.physical.path.ptr); 104 free(r.physical.basedir.ptr); 105 } 106 107 void test_mod_alias (void); 108 void test_mod_alias (void) 109 { 110 test_mod_alias_check(); 111 } 112