From 6e7c7586b1399a113971ef81cb47d416bb3fa430 Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Thu, 25 Apr 2024 16:20:06 -0400 Subject: [PATCH] Move path validation tests before charset tests The charset validation tests do exhaustive loops over all possible codepoints. This is very useful for ensuring correct behavior on all inputs, but is slow enough (several seconds) to be annoying during development. Moving the path validation tests (which are very fast) before the charset validation tests allows developers to conclude that they have passed much sooner, since if they fail the code will crash quickly. (cherry picked from commit a656698185d4654037387f28eb1be6c87ae97bf0) --- qrexec-lib/validator-test.c | 95 +++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 47 deletions(-) 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/")); }