From 6aebfec3a5b56f3f210a4b06bfb806089cbf95b7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 15 Sep 2021 09:19:04 +0200 Subject: [PATCH] sysctl-util: make sysctl_write_ip_property() a wrapper around sysctl_write() It does the same stuff, let's use the same codepaths as much as we can. And while we are at it, let's generate good error codes in case we are called with unsupported parameters/let's validate stuff more that might originate from user input. --- src/basic/socket-util.c | 2 +- src/basic/socket-util.h | 7 ++++--- src/basic/sysctl-util.c | 18 ++++++++++++------ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 1c353e86b0..9fc89a5f6e 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -793,7 +793,7 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) { /* Let's refuse "all" and "default" as interface name, to avoid collisions with the special sysctl * directories /proc/sys/net/{ipv4,ipv6}/conf/{all,default} */ - if (STR_IN_SET(p, "all", "default")) + if (!FLAGS_SET(flags, IFNAME_VALID_SPECIAL) && STR_IN_SET(p, "all", "default")) return false; for (const char *t = p; *t; t++) { diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 7fd591f6e2..0d76eace7d 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -135,9 +135,10 @@ int ip_tos_to_string_alloc(int i, char **s); int ip_tos_from_string(const char *s); typedef enum { - IFNAME_VALID_ALTERNATIVE = 1 << 0, - IFNAME_VALID_NUMERIC = 1 << 1, - _IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC, + IFNAME_VALID_ALTERNATIVE = 1 << 0, /* Allow "altnames" too */ + IFNAME_VALID_NUMERIC = 1 << 1, /* Allow decimal formatted ifindexes too */ + IFNAME_VALID_SPECIAL = 1 << 2, /* Allow the special names "all" and "default" */ + _IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC | IFNAME_VALID_SPECIAL, } IfnameValidFlags; bool ifname_valid_char(char a); bool ifname_valid_full(const char *p, IfnameValidFlags flags); diff --git a/src/basic/sysctl-util.c b/src/basic/sysctl-util.c index 60eec3dfec..a19f3e2649 100644 --- a/src/basic/sysctl-util.c +++ b/src/basic/sysctl-util.c @@ -5,11 +5,13 @@ #include #include +#include "af-list.h" #include "fd-util.h" #include "fileio.h" #include "log.h" #include "macro.h" #include "path-util.h" +#include "socket-util.h" #include "string-util.h" #include "sysctl-util.h" @@ -77,17 +79,21 @@ int sysctl_writef(const char *property, const char *format, ...) { int sysctl_write_ip_property(int af, const char *ifname, const char *property, const char *value) { const char *p; - assert(IN_SET(af, AF_INET, AF_INET6)); assert(property); assert(value); - p = strjoina("/proc/sys/net/ipv", af == AF_INET ? "4" : "6", - ifname ? "/conf/" : "", strempty(ifname), - property[0] == '/' ? "" : "/", property); + if (!IN_SET(af, AF_INET, AF_INET6)) + return -EAFNOSUPPORT; - log_debug("Setting '%s' to '%s'", p, value); + if (ifname) { + if (!ifname_valid_full(ifname, IFNAME_VALID_SPECIAL)) + return -EINVAL; - return write_string_file(p, value, WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_DISABLE_BUFFER); + p = strjoina("net/", af_to_ipv4_ipv6(af), "/conf/", ifname, "/", property); + } else + p = strjoina("net/", af_to_ipv4_ipv6(af), "/", property); + + return sysctl_write(p, value); } int sysctl_read(const char *property, char **ret) { -- 2.25.1