Skip to content

Commit 030ae67

Browse files
DemiMariemarmarek
authored andcommitted
Improve symlink tests
Instead of crashing on the first failed test, log an error message for each failed test that points to the location of the error. (cherry picked from commit 5dcc596)
1 parent acfa2b6 commit 030ae67

File tree

1 file changed

+48
-17
lines changed

1 file changed

+48
-17
lines changed

qrexec-lib/validator-test.c

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -119,23 +119,54 @@ int main(int argc, char **argv)
119119
(always_forbidden || bad_unicode ? -EILSEQ : 0));
120120
}
121121

122-
// Symbolic links
123-
// Top level cannot be symlink
124-
assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a", (const uint8_t *)"b"));
125-
// Symbolic links cannot escape
126-
assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"../a"));
127-
assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"../a/b/c"));
128-
assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"../../a"));
129-
assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"a"));
130-
assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"../a"));
131-
// Absolute symlinks are rejected
132-
assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"/a"));
133-
// Symlinks may end in "..".
134-
assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)".."));
135-
// Symlinks may end in "/".
136-
assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"a/"));
137-
// Symlinks reject invalid paths.
138-
assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"..", (const uint8_t *)"a/"));
122+
struct p {
123+
const char *const path, *const target, *const file;
124+
int const line, flags;
125+
bool const allowed;
126+
} symlink_checks[] = {
127+
#define TEST(path_, target_, flags_, allowed_) \
128+
{ .path = (path_) \
129+
, .target = (target_) \
130+
, .file = __FILE__ \
131+
, .line = __LINE__ \
132+
, .flags = (flags_) \
133+
, .allowed = (allowed_) \
134+
}
135+
// Symbolic links
136+
// Top level cannot be symlink
137+
TEST("a", "b", 0, false),
138+
TEST("a/b", "../a", 0, false),
139+
TEST("a", "b", 0, false),
140+
// Symbolic links cannot escape
141+
TEST("a/b", "../a", 0, false),
142+
TEST("a/b", "../a", 0, false),
143+
TEST("a/b", "../a/b/c", 0, false),
144+
TEST("a/b", "../a/b/c", 0, false),
145+
TEST("a/b/c", "../../a", 0, false),
146+
TEST("a/b/c", "../../a", 0, false),
147+
TEST("a/b", "a", 0, true),
148+
TEST("a/b/c", "../a", 0, true),
149+
// Absolute symlinks are rejected
150+
TEST("a/b/c", "/a", 0, false),
151+
TEST("a/b/c", "/a", 0, false),
152+
// Symlinks may end in "..".
153+
TEST("a/b/c", "..", 0, true),
154+
// Symlinks may end in "/".
155+
TEST("a/b/c", "a/", 0, true),
156+
// Invalid paths are rejected.
157+
TEST("..", "a/", 0, false),
158+
};
159+
bool failed = false;
160+
for (size_t i = 0; i < sizeof(symlink_checks)/sizeof(symlink_checks[0]); ++i) {
161+
const struct p *p = symlink_checks + i;
162+
if ((qubes_pure_validate_symbolic_link_v2((const unsigned char *)p->path,
163+
(const unsigned char *)p->target,
164+
p->flags) == 0) != p->allowed) {
165+
failed = true;
166+
fprintf(stderr, "%s:%d:Test failure\n", p->file, p->line);
167+
}
168+
}
169+
assert(!failed);
139170

140171
// Greek letters are safe
141172
assert(qubes_pure_validate_file_name((uint8_t *)u8"\u03b2.txt"));

0 commit comments

Comments
 (0)