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.
This commit is contained in:
Lennart Poettering
2021-09-15 16:32:40 +02:00
parent 13239c86e0
commit 6aebfec3a5
3 changed files with 17 additions and 10 deletions
+1 -1
View File
@@ -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++) {
+4 -3
View File
@@ -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);
+12 -6
View File
@@ -5,11 +5,13 @@
#include <stdio.h>
#include <unistd.h>
#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) {