From 6480850ee27e302897a2894778d04e00a68434d9 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Sat, 30 Dec 2017 21:03:23 +0100 Subject: [PATCH] Enforce *no networking* in single-user mode, runlevel 1 This is a quite intrusive change. In addition to the already reserved runlevels 0 and 6, halt and reboot, respectively, this patch reserves runlevel 1 as *no networking*, like the traditional SysV init did. One of the reasons for this change is the new 'single' user mode, introduced earlier. Most users when entering 'S' or 'single' on the kernel cmdline expect the single user mode (runlevel 1) to be without networking. This leaves 2, 3, 4, 5, and 7, 8, 9 as fully user-configurable runlevels with networking. Of course, networking can still be enabled in runlevel 1 using ifconfig or ifupdown, or change runlevel. Signed-off-by: Joachim Nilsson --- src/finit.c | 62 +------------------------------------------- src/helpers.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/helpers.h | 1 + src/service.c | 6 +++++ 4 files changed, 79 insertions(+), 61 deletions(-) diff --git a/src/finit.c b/src/finit.c index 94f42ca2..bed491e1 100644 --- a/src/finit.c +++ b/src/finit.c @@ -157,54 +157,6 @@ static int fsck(int pass) return 0; } -static void networking(void) -{ - FILE *fp; - - /* Run user network start script if enabled */ - if (network) { - run_interactive(network, "Starting networking: %s", network); - goto done; - } - - /* Debian/Ubuntu/Busybox/RH/Suse */ - if (!whichp("ifup")) - goto done; - - fp = fopen("/etc/network/interfaces", "r"); - if (fp) { - int i = 0; - char buf[160]; - - /* Bring up all 'auto' interfaces */ - while (fgets(buf, sizeof(buf), fp)) { - char cmd[80]; - char *line, *ifname = NULL; - - chomp(buf); - line = strip_line(buf); - - if (!strncmp(line, "auto", 4)) - ifname = &line[5]; - if (!strncmp(line, "allow-hotplug", 13)) - ifname = &line[14]; - - if (!ifname) - continue; - - snprintf(cmd, 80, "ifup %s", ifname); - run_interactive(cmd, "Bringing up interface %s", ifname); - i++; - } - - fclose(fp); - } - -done: - /* Fall back to bring up at least loopback */ - ifconfig("lo", "127.0.0.1", "255.0.0.0", 1); -} - /* * If everything goes south we can use this to give the operator an * emergency shell to debug the problem -- Finit should not crash! @@ -261,19 +213,6 @@ static void emergency_shell(void) */ static void finalize(void) { - /* - * Network stuff - */ - if (!rescue) { - _d("Setting up networking ..."); - networking(); - - /* Hooks that rely on loopback, or basic networking being up. */ - _d("Calling all network up hooks ..."); - plugin_run_hooks(HOOK_NETWORK_UP); - } - umask(022); - /* * Run startup scripts in the runparts directory, if any. */ @@ -535,6 +474,7 @@ int main(int argc, char* argv[]) /* Start new initctl API responder */ api_init(&loop); + umask(022); /* * Wait for all SVC_TYPE_RUNTASK to have completed their work in diff --git a/src/helpers.c b/src/helpers.c index dacb1881..f433652f 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -212,6 +212,77 @@ done: sethostname(*hostname, strlen(*hostname)); } +static void ifup(char *ifname, int updown) +{ + char cmd[80]; + + if (updown) { + snprintf(cmd, sizeof(cmd), "ifup %s", ifname); + run_interactive(cmd, "Bringing up interface %s", ifname); + } else { + snprintf(cmd, sizeof(cmd), "ifdown -f %s", ifname); + run_interactive(cmd, "Taking down interface %s", ifname); + } +} + +/* + * Bring up networking, but only if not single-user or rescue mode + */ +void networking(int updown) +{ + FILE *fp; + + if (updown) + _d("Setting up networking ..."); + else + _d("Taking down networking ..."); + + /* Run user network start script if enabled */ + if (updown && network) { + run_interactive(network, "Starting networking: %s", network); + goto done; + } + + /* Debian/Ubuntu/Busybox/RH/Suse */ + if (!whichp("ifup")) + goto done; + + fp = fopen("/etc/network/interfaces", "r"); + if (fp) { + char buf[160]; + + /* Bring up, or down, all 'auto' interfaces */ + while (fgets(buf, sizeof(buf), fp)) { + char *line, *ifname = NULL; + + chomp(buf); + line = strip_line(buf); + + if (!strncmp(line, "auto", 4)) + ifname = &line[5]; + if (!strncmp(line, "allow-hotplug", 13)) + ifname = &line[14]; + + if (!ifname) + continue; + + ifup(ifname, updown); + } + + fclose(fp); + } + +done: + /* Fall back to bring up at least loopback */ + ifconfig("lo", "127.0.0.1", "255.0.0.0", updown); + + /* Hooks that rely on loopback, or basic networking being up. */ + if (updown) { + _d("Calling all network up hooks ..."); + plugin_run_hooks(HOOK_NETWORK_UP); + } +} + #ifndef HAVE_GETFSENT static lfile_t *fstab = NULL; diff --git a/src/helpers.h b/src/helpers.h index a3fd0c69..ee15f87b 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -68,6 +68,7 @@ int print_result (int fail); int getuser (char *username, char **home); int getgroup (char *group); void set_hostname (char **hostname); +void networking (int updown); int complete (char *cmd, int pid); int run (char *cmd); diff --git a/src/service.c b/src/service.c index 9f73224b..6620d492 100644 --- a/src/service.c +++ b/src/service.c @@ -468,8 +468,14 @@ void service_reload_dynamic(void) */ void service_runlevel(int newlevel) { + if (!rescue && runlevel <= 1 && newlevel > 1) + networking(1); + sm_set_runlevel(&sm, newlevel); sm_step(&sm); + + if (!rescue && runlevel <= 1) + networking(0); } /**