From 2ef2376d833dca05ab32bba41fcf5c345b25916e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 25 Jan 2021 19:41:59 +0100 Subject: [PATCH] path-util: tighten path_is_valid() checks This tightens the path_is_valid() checking: it now tests whether each component in the path is bound by FILENAME_MAX in its size. --- src/basic/path-util.c | 23 ++++++++++++++++++---- src/test/test-path-util.c | 41 ++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 9 deletions(-) diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 3dff09b1519..f7498d01256 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -891,7 +891,7 @@ bool filename_is_valid(const char *p) { if (*e != 0) return false; - if (e - p > FILENAME_MAX) /* FILENAME_MAX is counted *without* the trailing NUL byte */ + if (e - p > NAME_MAX) /* NAME_MAX is counted *without* the trailing NUL byte */ return false; return true; @@ -902,10 +902,25 @@ bool path_is_valid(const char *p) { if (isempty(p)) return false; - if (strlen(p) >= PATH_MAX) /* PATH_MAX is counted *with* the trailing NUL byte */ - return false; + for (const char *e = p;;) { + size_t n; - return true; + /* Skip over slashes */ + e += strspn(e, "/"); + if (e - p >= PATH_MAX) /* Already reached the maximum length for a path? (PATH_MAX is counted + * *with* the trailing NUL byte) */ + return false; + if (*e == 0) /* End of string? Yay! */ + return true; + + /* Skip over one component */ + n = strcspn(e, "/"); + if (n > NAME_MAX) /* One component larger than NAME_MAX? (NAME_MAX is counted *without* the + * trailing NUL byte) */ + return false; + + e += n; + } } bool path_is_normalized(const char *p) { diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c index 206f5fd436d..58b185494df 100644 --- a/src/test/test-path-util.c +++ b/src/test/test-path-util.c @@ -604,8 +604,7 @@ static void test_path_extract_filename(void) { } static void test_filename_is_valid(void) { - char foo[FILENAME_MAX+2]; - int i; + char foo[NAME_MAX+2]; log_info("/* %s */", __func__); @@ -618,9 +617,8 @@ static void test_filename_is_valid(void) { assert_se(!filename_is_valid("bar/foo/")); assert_se(!filename_is_valid("bar//")); - for (i=0; i