From: Mike Yuan Date: Wed, 23 Jul 2025 08:30:18 +0000 (+0200) Subject: networkctl-config-file: validate args are valid filenames X-Git-Tag: v258-rc1~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6da6c9050e9965c1459efc231f0595c76bb41f0;p=thirdparty%2Fsystemd.git networkctl-config-file: validate args are valid filenames ... as opposed to full paths Fixes #38288 --- diff --git a/src/network/networkctl-config-file.c b/src/network/networkctl-config-file.c index a5e7b4da019..d82245d084d 100644 --- a/src/network/networkctl-config-file.c +++ b/src/network/networkctl-config-file.c @@ -66,7 +66,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) { @@ -520,12 +520,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) @@ -642,6 +645,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; @@ -682,13 +688,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) @@ -739,12 +748,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) { diff --git a/test/units/TEST-74-AUX-UTILS.networkctl.sh b/test/units/TEST-74-AUX-UTILS.networkctl.sh index 3d402a7182f..53674b92ea0 100755 --- a/test/units/TEST-74-AUX-UTILS.networkctl.sh +++ b/test/units/TEST-74-AUX-UTILS.networkctl.sh @@ -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 <new <