diff options
author | Lennart Poettering <lennart@poettering.net> | 2021-05-26 10:39:33 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2021-05-26 10:40:57 +0200 |
commit | 3b085db3b67d72065defa94a823b8ac62131a0b7 (patch) | |
tree | ceff98d982f84d1648f4d4f852760cd67b1d3e6e /src | |
parent | networkd: add bus property exposing network namepace ID we run in (diff) | |
download | systemd-3b085db3b67d72065defa94a823b8ac62131a0b7.tar.xz systemd-3b085db3b67d72065defa94a823b8ac62131a0b7.zip |
networkctl: politely refuse being called from a different netns than the networkd instance we talk to
Otherwise things get very confusing since we mix up netens data from our
client side and from the data we retrieve from networkd.
In the long run we should teach networkctl some switch to operate safely
on other netns, and in that case also determine the right networkd
instance for that namespace.
Fixes: #19236
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkctl.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/network/networkctl.c b/src/network/networkctl.c index 9d3e3f033b..619ef91288 100644 --- a/src/network/networkctl.c +++ b/src/network/networkctl.c @@ -2993,6 +2993,45 @@ static int networkctl_main(int argc, char *argv[]) { return dispatch_verb(argc, argv, verbs, NULL); } +static int check_netns_match(void) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + struct stat st; + uint64_t id; + int r; + + r = sd_bus_open_system(&bus); + if (r < 0) + return log_error_errno(r, "Failed to connect system bus: %m"); + + r = sd_bus_get_property_trivial( + bus, + "org.freedesktop.network1", + "/org/freedesktop/network1", + "org.freedesktop.network1.Manager", + "NamespaceId", + &error, + 't', + &id); + if (r < 0) { + log_debug_errno(r, "Failed to query network namespace of networkd, ignoring: %s", bus_error_message(&error, r)); + return 0; + } + if (id == 0) { + log_debug("systemd-networkd.service not running in a network namespace (?), skipping netns check."); + return 0; + } + + if (stat("/proc/self/ns/net", &st) < 0) + return log_error_errno(r, "Failed to determine our own network namespace ID: %m"); + + if (id != st.st_ino) + return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), + "networkctl must be invoked in same network namespace as systemd-networkd.service."); + + return 0; +} + static void warn_networkd_missing(void) { if (access("/run/systemd/netif/state", F_OK) >= 0) @@ -3010,6 +3049,10 @@ static int run(int argc, char* argv[]) { if (r <= 0) return r; + r = check_netns_match(); + if (r < 0) + return r; + warn_networkd_missing(); return networkctl_main(argc, argv); |