1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

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.
This commit is contained in:
Lennart Poettering 2021-01-25 19:41:59 +01:00
parent 0fb613000d
commit 2ef2376d83
2 changed files with 55 additions and 9 deletions

View File

@ -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) {

View File

@ -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<FILENAME_MAX+1; i++)
foo[i] = 'a';
foo[FILENAME_MAX+1] = '\0';
memset(foo, 'a', sizeof(foo) - 1);
char_array_0(foo);
assert_se(!filename_is_valid(foo));
@ -628,6 +626,38 @@ static void test_filename_is_valid(void) {
assert_se(filename_is_valid("o.o"));
}
static void test_path_is_valid(void) {
char foo[PATH_MAX+2];
const char *c;
log_info("/* %s */", __func__);
assert_se(!path_is_valid(""));
assert_se(path_is_valid("/bar/foo"));
assert_se(path_is_valid("/bar/foo/"));
assert_se(path_is_valid("/bar/foo/"));
assert_se(path_is_valid("//bar//foo//"));
assert_se(path_is_valid("/"));
assert_se(path_is_valid("/////"));
assert_se(path_is_valid("/////.///.////...///..//."));
assert_se(path_is_valid("."));
assert_se(path_is_valid(".."));
assert_se(path_is_valid("bar/foo"));
assert_se(path_is_valid("bar/foo/"));
assert_se(path_is_valid("bar//"));
memset(foo, 'a', sizeof(foo) -1);
char_array_0(foo);
assert_se(!path_is_valid(foo));
c = strjoina("/xxx/", foo, "/yyy");
assert_se(!path_is_valid(c));
assert_se(path_is_valid("foo_bar-333"));
assert_se(path_is_valid("o.o"));
}
static void test_hidden_or_backup_file(void) {
log_info("/* %s */", __func__);
@ -761,6 +791,7 @@ int main(int argc, char **argv) {
test_last_path_component();
test_path_extract_filename();
test_filename_is_valid();
test_path_is_valid();
test_hidden_or_backup_file();
test_skip_dev_prefix();
test_empty_or_root();