xref: /lighttpd1.4/src/t/test_mod_alias.c (revision 251f97bf)
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