]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkctl-config-file: validate args are valid filenames
authorMike Yuan <me@yhndnzj.com>
Wed, 23 Jul 2025 08:30:18 +0000 (10:30 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 4 Aug 2025 18:50:36 +0000 (19:50 +0100)
... as opposed to full paths

Fixes #38288

(cherry picked from commit a6da6c9050e9965c1459efc231f0595c76bb41f0)

src/network/networkctl-config-file.c
test/units/TEST-74-AUX-UTILS.networkctl.sh

index 7ef7668f30573f5d875f9af01274ecffb451336c..eababf41a2f1f44641216b1d66f472beaf3ce6f2 100644 (file)
@@ -58,7 +58,7 @@ static int get_config_files_by_name(
         _cleanup_free_ char *path = NULL;
         int r;
 
-        assert(name);
+        assert(filename_is_valid(name));
         assert(ret_path);
 
         STRV_FOREACH(i, NETWORK_DIRS) {
@@ -512,12 +512,15 @@ int verb_edit(int argc, char *argv[], void *userdata) {
                         continue;
                 }
 
+                if (!filename_is_valid(*name))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid config filename: %s", *name);
+
                 if (ENDSWITH_SET(*name, ".network", ".netdev"))
                         reload |= RELOAD_NETWORKD;
                 else if (endswith(*name, ".link"))
                         reload |= RELOAD_UDEVD;
                 else
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid network config name '%s'.", *name);
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Network config of unknown type: %s", *name);
 
                 r = get_config_files_by_name(*name, /* allow_masked = */ false, &path, &dropins);
                 if (r == -ERFKILL)
@@ -634,6 +637,9 @@ int verb_cat(int argc, char *argv[], void *userdata) {
                         continue;
                 }
 
+                if (!filename_is_valid(*name) || !ENDSWITH_SET(*name, ".network", ".netdev", ".link"))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid network config name: %s", *name);
+
                 _cleanup_strv_free_ char **dropins = NULL;
                 _cleanup_free_ char *path = NULL;
 
@@ -674,13 +680,16 @@ int verb_mask(int argc, char *argv[], void *userdata) {
                 _cleanup_free_ char *config_path = NULL, *symlink_path = NULL;
                 ReloadFlags reload;
 
+                if (!filename_is_valid(*name))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid config filename: %s", *name);
+
                 /* We update the real 'flags' at last, since the operation can be skipped. */
                 if (ENDSWITH_SET(*name, ".network", ".netdev"))
                         reload = RELOAD_NETWORKD;
                 else if (endswith(*name, ".link"))
                         reload = RELOAD_UDEVD;
                 else
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid network config name '%s'.", *name);
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Network config of unknown type: %s", *name);
 
                 r = get_config_files_by_name(*name, /* allow_masked = */ true, &config_path, /* ret_dropins = */ NULL);
                 if (r == -ENOENT)
@@ -731,12 +740,15 @@ int verb_unmask(int argc, char *argv[], void *userdata) {
                 _cleanup_free_ char *path = NULL;
                 ReloadFlags reload;
 
+                if (!filename_is_valid(*name))
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid config filename: %s", *name);
+
                 if (ENDSWITH_SET(*name, ".network", ".netdev"))
                         reload = RELOAD_NETWORKD;
                 else if (endswith(*name, ".link"))
                         reload = RELOAD_UDEVD;
                 else
-                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid network config name '%s'.", *name);
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Network config of unknown type: %s", *name);
 
                 r = get_config_files_by_name(*name, /* allow_masked = */ true, &path, /* ret_dropins = */ NULL);
                 if (r == -ENOENT) {
index 3d402a7182f6b7f241e48515d4e673bce180e424..53674b92ea0544ab83a1cfc44ecd28baa2a6c045 100755 (executable)
@@ -43,6 +43,7 @@ touch /usr/lib/systemd/network/donotexist.network
 (! networkctl unmask "donotexist.network")
 rm /usr/lib/systemd/network/donotexist.network
 
+(! networkctl cat "/usr/lib/systemd/network/$NETWORK_NAME")
 networkctl cat "$NETWORK_NAME" | tail -n +2 | cmp - "/usr/lib/systemd/network/$NETWORK_NAME"
 
 cat >new <<EOF
@@ -50,6 +51,7 @@ cat >new <<EOF
 Name=test2
 EOF
 
+(! networkctl edit "/usr/lib/systemd/network/$NETWORK_NAME")
 EDITOR='mv new' script -ec 'networkctl edit --runtime "$NETWORK_NAME"' /dev/null
 (! networkctl mask --runtime "$NETWORK_NAME")
 printf '%s\n' '[Match]' 'Name=test2' | cmp - "/run/systemd/network/$NETWORK_NAME"