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
test_mod_alias_check(void)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);
test_mod_alias(void)108 void test_mod_alias (void)
109 {
110 test_mod_alias_check();
111 }
112