From 8115f3274eab06743603aec502ae311e3bf0724b Mon Sep 17 00:00:00 2001 From: LinkTed Date: Mon, 3 Jan 2022 20:30:46 +0200 Subject: linux: Add support for No New Privs flag This add No New Privs flag for start-stop-daemon and supervise-daemon by adding --no-new-privs flag. As a result, the user set the No New Privs flag for the program should run with. see PR_SET_NO_NEW_PRIVS prctl(2) --- src/rc/start-stop-daemon.c | 21 +++++++++++++++++++++ src/rc/supervise-daemon.c | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'src') diff --git a/src/rc/start-stop-daemon.c b/src/rc/start-stop-daemon.c index e1a520f5..007a9309 100644 --- a/src/rc/start-stop-daemon.c +++ b/src/rc/start-stop-daemon.c @@ -31,6 +31,7 @@ #ifdef __linux__ #include /* For io priority */ +#include /* For prctl */ #endif #include @@ -75,6 +76,7 @@ const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:3:4:" \ const struct option longopts[] = { { "capabilities", 1, NULL, 0x100}, { "secbits", 1, NULL, 0x101}, + { "no-new-privs", 0, NULL, 0x102}, { "ionice", 1, NULL, 'I'}, { "stop", 0, NULL, 'K'}, { "nicelevel", 1, NULL, 'N'}, @@ -109,6 +111,7 @@ const struct option longopts[] = { const char * const longopts_help[] = { "Set the inheritable, ambient and bounding capabilities", "Set the security-bits for the program", + "Set the No New Privs flag for the program", "Set an ionice class:data when starting", "Stop daemon", "Set a nicelevel when starting", @@ -319,6 +322,9 @@ int main(int argc, char **argv) cap_iab_t cap_iab = NULL; unsigned secbits = 0; #endif +#ifdef PR_SET_NO_NEW_PRIVS + bool no_new_privs = false; +#endif applet = basename_c(argv[0]); atexit(cleanup); @@ -389,6 +395,13 @@ int main(int argc, char **argv) #endif break; + case 0x102: +#ifdef PR_SET_NO_NEW_PRIVS + no_new_privs = true; +#else + eerrorx("The No New Privs flag is only supported by Linux (since 3.5)"); +#endif + break; case 'I': /* --ionice */ if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0) @@ -915,6 +928,14 @@ int main(int argc, char **argv) } #endif +#ifdef PR_SET_NO_NEW_PRIVS + if (no_new_privs) { + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) + eerrorx("Could not set No New Privs flag: %s", strerror(errno)); + } +#endif + + #ifdef TIOCNOTTY ioctl(tty_fd, TIOCNOTTY, 0); close(tty_fd); diff --git a/src/rc/supervise-daemon.c b/src/rc/supervise-daemon.c index 5c5c01fc..85d5efbb 100644 --- a/src/rc/supervise-daemon.c +++ b/src/rc/supervise-daemon.c @@ -32,6 +32,7 @@ #ifdef __linux__ #include /* For io priority */ +#include /* For prctl */ #endif #include @@ -79,6 +80,7 @@ const struct option longopts[] = { { "healthcheck-delay", 1, NULL, 'A'}, { "capabilities", 1, NULL, 0x100}, { "secbits", 1, NULL, 0x101}, + { "no-new-privs", 0, NULL, 0x102}, { "respawn-delay", 1, NULL, 'D'}, { "chdir", 1, NULL, 'd'}, { "env", 1, NULL, 'e'}, @@ -106,6 +108,7 @@ const char * const longopts_help[] = { "set a health check timer", "Set the inheritable, ambient and bounding capabilities", "Set the security-bits for the program", + "Set the No New Privs flag for the program", "Set a respawn delay", "Change the PWD", "Set an environment string", @@ -164,6 +167,9 @@ static bool verbose = false; static cap_iab_t cap_iab = NULL; static unsigned secbits = 0; #endif +#ifdef PR_SET_NO_NEW_PRIVS +static bool no_new_privs = false; +#endif extern char **environ; @@ -437,6 +443,13 @@ static void child_process(char *exec, char **argv) } #endif +#ifdef PR_SET_NO_NEW_PRIVS + if (no_new_privs) { + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) + eerrorx("Could not set No New Privs flag: %s", strerror(errno)); + } +#endif + /* remove the controlling tty */ #ifdef TIOCNOTTY ioctl(tty_fd, TIOCNOTTY, 0); @@ -854,6 +867,14 @@ int main(int argc, char **argv) #endif break; + case 0x102: +#ifdef PR_SET_NO_NEW_PRIVS + no_new_privs = true; +#else + eerrorx("The No New Privs flag is only supported by Linux (since 3.5)"); +#endif + break; + case 'D': /* --respawn-delay time */ n = sscanf(optarg, "%d", &respawn_delay); if (n != 1 || respawn_delay < 1) -- cgit v1.2.3