From d3834f3a7a434ae10b6b165ddb36ba7fa3d3557c Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Thu, 25 Apr 2024 16:11:56 -0400 Subject: [PATCH] Test that symbolic links can end in '/' This is obscure, but it is harmless. It simply means that the target of the symlink must be a directory (or symlink to a directory), otherwise opening the symlink will fail with ENOTDIR. Allowing non-symlink paths to end in '/' is also harmless: opendir_safe() will set the last path component to the empty string, and attempting to create a file, symlink, or directory with the empty string as a name will fail with ENOENT. (cherry picked from commit 9f78bc465b370b8973f5ad19c181c3e007bc48f1) --- qrexec-lib/unicode.c | 2 +- qrexec-lib/validator-test.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/qrexec-lib/unicode.c b/qrexec-lib/unicode.c index 5f39668b..fc4c56c0 100644 --- a/qrexec-lib/unicode.c +++ b/qrexec-lib/unicode.c @@ -137,7 +137,7 @@ static ssize_t validate_path(const uint8_t *const untrusted_name, size_t allowed if (i == 0 || untrusted_name[i - 1] == '/') { switch (untrusted_name[i]) { case '/': // repeated or initial slash - case '\0': // trailing slash or empty string + case '\0': // empty string return -1; case '.': if (untrusted_name[i + 1] == '\0' || untrusted_name[i + 1] == '/') diff --git a/qrexec-lib/validator-test.c b/qrexec-lib/validator-test.c index 372fb2d9..e85319f9 100644 --- a/qrexec-lib/validator-test.c +++ b/qrexec-lib/validator-test.c @@ -219,4 +219,6 @@ int main(int argc, char **argv) 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/")); }