From 9d5acfab20c5f1177d877d0bec18063c0a6c5929 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Jun 2021 19:43:55 +0200 Subject: [PATCH 1/3] unit-name: generate a clear error code when converting an overly long fs path to a unit name --- src/basic/unit-name.c | 6 ++++++ src/test/test-unit-name.c | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index 29ffd81ea9..284a773483 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -528,6 +528,9 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) { if (!s) return -ENOMEM; + if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */ + return -ENAMETOOLONG; + /* Refuse this if this got too long or for some other reason didn't result in a valid name */ if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) return -EINVAL; @@ -559,6 +562,9 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha if (!s) return -ENOMEM; + if (strlen(s) >= UNIT_NAME_MAX) /* Return a slightly more descriptive error for this specific condition */ + return -ENAMETOOLONG; + /* Refuse this if this got too long or for some other reason didn't result in a valid name */ if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE)) return -EINVAL; diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index 0bce571fed..d737043220 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -130,7 +130,7 @@ static void test_unit_name_from_path(void) { test_unit_name_from_path_one("///", ".mount", "-.mount", 0); test_unit_name_from_path_one("/foo/../bar", ".mount", NULL, -EINVAL); test_unit_name_from_path_one("/foo/./bar", ".mount", "foo-bar.mount", 0); - test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount", NULL, -EINVAL); + test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount", NULL, -ENAMETOOLONG); } static void test_unit_name_from_path_instance_one(const char *pattern, const char *path, const char *suffix, const char *expected, int ret) { @@ -160,7 +160,7 @@ static void test_unit_name_from_path_instance(void) { test_unit_name_from_path_instance_one("waldo", "..", ".mount", NULL, -EINVAL); test_unit_name_from_path_instance_one("waldo", "/foo", ".waldi", NULL, -EINVAL); test_unit_name_from_path_instance_one("wa--ldo", "/--", ".mount", "wa--ldo@\\x2d\\x2d.mount", 0); - test_unit_name_from_path_instance_one("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "/waldo", ".mount", NULL, -EINVAL); + test_unit_name_from_path_instance_one("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "/waldo", ".mount", NULL, -ENAMETOOLONG); } static void test_unit_name_to_path_one(const char *unit, const char *path, int ret) { From 598a6a8491abd311d36b11caf262123fbbffb2c0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Jun 2021 22:20:55 +0200 Subject: [PATCH 2/3] core: when looping over mount/swap names, continue if we find one which doesn't translate to a valid unit name --- src/core/swap.c | 3 +++ src/core/unit.c | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/core/swap.c b/src/core/swap.c index 74da2428c2..ecf42ad119 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1448,6 +1448,9 @@ int swap_process_device_new(Manager *m, sd_device *dev) { int q; q = unit_name_from_path(devlink, ".swap", &n); + if (IN_SET(q, -EINVAL, -ENAMETOOLONG)) /* If name too long or otherwise not convertible to + * unit name, we can't manage it */ + continue; if (q < 0) return q; diff --git a/src/core/unit.c b/src/core/unit.c index dbdf7d9b37..4332263a9a 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1473,16 +1473,17 @@ static int unit_add_mount_dependencies(Unit *u) { Unit *m; r = unit_name_from_path(prefix, ".mount", &p); + if (IN_SET(r, -EINVAL, -ENAMETOOLONG)) + continue; /* If the path cannot be converted to a mount unit name, then it's + * not managable as a unit by systemd, and hence we don't need a + * dependency on it. Let's thus silently ignore the issue. */ if (r < 0) return r; m = manager_get_unit(u->manager, p); if (!m) { - /* Make sure to load the mount unit if - * it exists. If so the dependencies - * on this unit will be added later - * during the loading of the mount - * unit. */ + /* Make sure to load the mount unit if it exists. If so the dependencies on + * this unit will be added later during the loading of the mount unit. */ (void) manager_load_unit_prepare(u->manager, p, NULL, NULL, &m); continue; } From 3ebc9b9b30b04a3aeec55a11022b337ec5fdb5cf Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Jun 2021 22:26:49 +0200 Subject: [PATCH 3/3] mount: be more descriptive when logging about overly long mount point paths This is prompted by #17684: let's very explicitly say that the name is too long for us, and that we'll ignore it. --- src/core/mount.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/core/mount.c b/src/core/mount.c index 07d8e7b985..c1f36ac4f1 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1713,11 +1713,18 @@ static int mount_setup_unit( .burst = 1, }; + if (r == -ENAMETOOLONG) + return log_struct_errno( + ratelimit_below(&rate_limit) ? LOG_WARNING : LOG_DEBUG, r, + "MESSAGE_ID=" SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR, + "MOUNT_POINT=%s", where, + LOG_MESSAGE("Mount point path '%s' too long to fit into unit name, ignoring mount point.", where)); + return log_struct_errno( ratelimit_below(&rate_limit) ? LOG_WARNING : LOG_DEBUG, r, "MESSAGE_ID=" SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR, "MOUNT_POINT=%s", where, - LOG_MESSAGE("Failed to generate valid unit name from path '%s', ignoring mount point: %m", where)); + LOG_MESSAGE("Failed to generate valid unit name from mount point path '%s', ignoring mount point: %m", where)); } u = manager_get_unit(m, e);