diff --git a/qrexec-lib/validator-test.c b/qrexec-lib/validator-test.c index e85319f9..614ce083 100644 --- a/qrexec-lib/validator-test.c +++ b/qrexec-lib/validator-test.c @@ -71,6 +71,54 @@ int main(int argc, char **argv) (void)argc; (void)argv; assert(qubes_pure_validate_file_name((uint8_t *)u8"simple_safe_filename.txt")); + + // Directory traversal checks + assert(!qubes_pure_validate_file_name((uint8_t *)"..")); + assert(!qubes_pure_validate_file_name((uint8_t *)"../..")); + assert(!qubes_pure_validate_file_name((uint8_t *)"a/..")); + assert(!qubes_pure_validate_file_name((uint8_t *)"a/../b")); + assert(!qubes_pure_validate_file_name((uint8_t *)"/")); + assert(!qubes_pure_validate_file_name((uint8_t *)"//")); + assert(!qubes_pure_validate_file_name((uint8_t *)"///")); + assert(!qubes_pure_validate_file_name((uint8_t *)"/a")); + assert(!qubes_pure_validate_file_name((uint8_t *)"//a")); + assert(!qubes_pure_validate_file_name((uint8_t *)"///a")); + + // No repeated slashes + assert(!qubes_pure_validate_file_name((uint8_t *)"a//b")); + + // No "." as a path component + assert(!qubes_pure_validate_file_name((uint8_t *)".")); + assert(!qubes_pure_validate_file_name((uint8_t *)"a/.")); + assert(!qubes_pure_validate_file_name((uint8_t *)"./a")); + assert(!qubes_pure_validate_file_name((uint8_t *)"a/./a")); + + // No ".." as a path component + assert(!qubes_pure_validate_file_name((uint8_t *)"..")); + assert(!qubes_pure_validate_file_name((uint8_t *)"a/..")); + assert(!qubes_pure_validate_file_name((uint8_t *)"../a")); + assert(!qubes_pure_validate_file_name((uint8_t *)"a/../a")); + + // Looks like "." or ".." but is not + assert(qubes_pure_validate_file_name((const uint8_t *)".a")); + assert(qubes_pure_validate_file_name((const uint8_t *)"..a")); + + // Symbolic links + // Top level cannot be symlink + assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a", (const uint8_t *)"b")); + // Symbolic links cannot escape + assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"../a")); + assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"../a/b/c")); + assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"../../a")); + assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"a")); + assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"../a")); + // Absolute symlinks are rejected + assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"/a")); + // Symlinks may end in "..". + assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"..")); + // Symlinks may end in "/". + assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"a/")); + // Greek letters are safe assert(qubes_pure_validate_file_name((uint8_t *)u8"\u03b2.txt")); assert(qubes_pure_validate_file_name((uint8_t *)u8"\u03b1.txt")); @@ -174,51 +222,4 @@ int main(int argc, char **argv) assert(j < 0x10FFFFE); } } - - // Directory traversal checks - assert(!qubes_pure_validate_file_name((uint8_t *)"..")); - assert(!qubes_pure_validate_file_name((uint8_t *)"../..")); - assert(!qubes_pure_validate_file_name((uint8_t *)"a/..")); - assert(!qubes_pure_validate_file_name((uint8_t *)"a/../b")); - assert(!qubes_pure_validate_file_name((uint8_t *)"/")); - assert(!qubes_pure_validate_file_name((uint8_t *)"//")); - assert(!qubes_pure_validate_file_name((uint8_t *)"///")); - assert(!qubes_pure_validate_file_name((uint8_t *)"/a")); - assert(!qubes_pure_validate_file_name((uint8_t *)"//a")); - assert(!qubes_pure_validate_file_name((uint8_t *)"///a")); - - // No repeated slashes - assert(!qubes_pure_validate_file_name((uint8_t *)"a//b")); - - // No "." as a path component - assert(!qubes_pure_validate_file_name((uint8_t *)".")); - assert(!qubes_pure_validate_file_name((uint8_t *)"a/.")); - assert(!qubes_pure_validate_file_name((uint8_t *)"./a")); - assert(!qubes_pure_validate_file_name((uint8_t *)"a/./a")); - - // No ".." as a path component - assert(!qubes_pure_validate_file_name((uint8_t *)"..")); - assert(!qubes_pure_validate_file_name((uint8_t *)"a/..")); - assert(!qubes_pure_validate_file_name((uint8_t *)"../a")); - assert(!qubes_pure_validate_file_name((uint8_t *)"a/../a")); - - // Looks like "." or ".." but is not - assert(qubes_pure_validate_file_name((const uint8_t *)".a")); - assert(qubes_pure_validate_file_name((const uint8_t *)"..a")); - - // Symbolic links - // Top level cannot be symlink - assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a", (const uint8_t *)"b")); - // Symbolic links cannot escape - assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"../a")); - assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"../a/b/c")); - assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"../../a")); - assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b", (const uint8_t *)"a")); - assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"../a")); - // Absolute symlinks are rejected - assert(!qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"/a")); - // Symlinks may end in "..". - assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"..")); - // Symlinks may end in "/". - assert(qubes_pure_validate_symbolic_link((const uint8_t *)"a/b/c", (const uint8_t *)"a/")); }