capabilities: Add support for securebits flags

This adds securebits flags for start-stop-daemon and supervise-daemon
by adding --secbits option. As a result, the user can specify
securebits the program should run with. see capabilities(7)
This commit is contained in:
LinkTed 2022-01-03 17:41:57 +02:00 committed by Mike Frysinger
parent e045591845
commit 79e5edc1a3
6 changed files with 55 additions and 0 deletions

View File

@ -164,6 +164,10 @@ log it or send it to another location.
.It Fl -capabilities Ar cap-list .It Fl -capabilities Ar cap-list
Start the daemon with the listed inheritable, ambient and bounding capabilities. Start the daemon with the listed inheritable, ambient and bounding capabilities.
The format is the same as in cap_iab(3). The format is the same as in cap_iab(3).
.It Fl -secbits Ar sec-bits
Set the security-bits for the program.
The numeric value of the security-bits can be found in <sys/secbits.h> header file.
The format is the same as in strtoul(3).
.It Fl w , -wait Ar milliseconds .It Fl w , -wait Ar milliseconds
Wait Wait
.Ar milliseconds .Ar milliseconds

View File

@ -161,6 +161,10 @@ but with the standard error output.
.It Fl -capabilities Ar cap-list .It Fl -capabilities Ar cap-list
Start the daemon with the listed inheritable, ambient and bounding capabilities. Start the daemon with the listed inheritable, ambient and bounding capabilities.
The format is the same as in cap_iab(3). The format is the same as in cap_iab(3).
.It Fl -secbits Ar sec-bits
Set the security-bits for the program.
The numeric value of the security-bits can be found in <sys/secbits.h> header file.
The format is the same as in strtoul(3).
.El .El
.Sh ENVIRONMENT .Sh ENVIRONMENT
.Va SSD_IONICELEVEL .Va SSD_IONICELEVEL

View File

@ -54,6 +54,7 @@ ssd_start()
${output_logger_arg} \ ${output_logger_arg} \
${error_logger_arg} \ ${error_logger_arg} \
${capabilities+--capabilities} "$capabilities" \ ${capabilities+--capabilities} "$capabilities" \
${secbits:+--secbits} "$secbits" \
${procname:+--name} $procname \ ${procname:+--name} $procname \
${pidfile:+--pidfile} $pidfile \ ${pidfile:+--pidfile} $pidfile \
${command_user+--user} $command_user \ ${command_user+--user} $command_user \

View File

@ -37,6 +37,7 @@ supervise_start()
${healthcheck_delay:+--healthcheck-delay} $healthcheck_delay \ ${healthcheck_delay:+--healthcheck-delay} $healthcheck_delay \
${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \ ${healthcheck_timer:+--healthcheck-timer} $healthcheck_timer \
${capabilities+--capabilities} "$capabilities" \ ${capabilities+--capabilities} "$capabilities" \
${secbits:+--secbits} "$secbits" \
${command_user+--user} $command_user \ ${command_user+--user} $command_user \
${umask+--umask} $umask \ ${umask+--umask} $umask \
${supervise_daemon_args:-${start_stop_daemon_args}} \ ${supervise_daemon_args:-${start_stop_daemon_args}} \

View File

@ -74,6 +74,7 @@ const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:3:4:" \
getoptstring_COMMON; getoptstring_COMMON;
const struct option longopts[] = { const struct option longopts[] = {
{ "capabilities", 1, NULL, 0x100}, { "capabilities", 1, NULL, 0x100},
{ "secbits", 1, NULL, 0x101},
{ "ionice", 1, NULL, 'I'}, { "ionice", 1, NULL, 'I'},
{ "stop", 0, NULL, 'K'}, { "stop", 0, NULL, 'K'},
{ "nicelevel", 1, NULL, 'N'}, { "nicelevel", 1, NULL, 'N'},
@ -107,6 +108,7 @@ const struct option longopts[] = {
}; };
const char * const longopts_help[] = { const char * const longopts_help[] = {
"Set the inheritable, ambient and bounding capabilities", "Set the inheritable, ambient and bounding capabilities",
"Set the security-bits for the program",
"Set an ionice class:data when starting", "Set an ionice class:data when starting",
"Stop daemon", "Stop daemon",
"Set a nicelevel when starting", "Set a nicelevel when starting",
@ -315,6 +317,7 @@ int main(int argc, char **argv)
unsigned int start_wait = 0; unsigned int start_wait = 0;
#ifdef HAVE_CAP #ifdef HAVE_CAP
cap_iab_t cap_iab = NULL; cap_iab_t cap_iab = NULL;
unsigned secbits = 0;
#endif #endif
applet = basename_c(argv[0]); applet = basename_c(argv[0]);
@ -372,6 +375,21 @@ int main(int argc, char **argv)
#endif #endif
break; break;
case 0x101:
#ifdef HAVE_CAP
if (*optarg == '\0')
eerrorx("Secbits are empty");
tmp = NULL;
secbits = strtoul(optarg, &tmp, 0);
if (*tmp != '\0')
eerrorx("Could not parse secbits: invalid char %c", *tmp);
#else
eerrorx("Capabilities support not enabled");
#endif
break;
case 'I': /* --ionice */ case 'I': /* --ionice */
if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0) if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
eerrorx("%s: invalid ionice `%s'", eerrorx("%s: invalid ionice `%s'",
@ -890,6 +908,11 @@ int main(int argc, char **argv)
if (i != 0) if (i != 0)
eerrorx("Could not set iab: %s", strerror(errno)); eerrorx("Could not set iab: %s", strerror(errno));
} }
if (secbits != 0) {
if (cap_set_secbits(secbits) < 0)
eerrorx("Could not set securebits to 0x%x: %s", secbits, strerror(errno));
}
#endif #endif
#ifdef TIOCNOTTY #ifdef TIOCNOTTY

View File

@ -78,6 +78,7 @@ const struct option longopts[] = {
{ "healthcheck-timer", 1, NULL, 'a'}, { "healthcheck-timer", 1, NULL, 'a'},
{ "healthcheck-delay", 1, NULL, 'A'}, { "healthcheck-delay", 1, NULL, 'A'},
{ "capabilities", 1, NULL, 0x100}, { "capabilities", 1, NULL, 0x100},
{ "secbits", 1, NULL, 0x101},
{ "respawn-delay", 1, NULL, 'D'}, { "respawn-delay", 1, NULL, 'D'},
{ "chdir", 1, NULL, 'd'}, { "chdir", 1, NULL, 'd'},
{ "env", 1, NULL, 'e'}, { "env", 1, NULL, 'e'},
@ -104,6 +105,7 @@ const char * const longopts_help[] = {
"set an initial health check delay", "set an initial health check delay",
"set a health check timer", "set a health check timer",
"Set the inheritable, ambient and bounding capabilities", "Set the inheritable, ambient and bounding capabilities",
"Set the security-bits for the program",
"Set a respawn delay", "Set a respawn delay",
"Change the PWD", "Change the PWD",
"Set an environment string", "Set an environment string",
@ -160,6 +162,7 @@ static char *svcname = NULL;
static bool verbose = false; static bool verbose = false;
#ifdef HAVE_CAP #ifdef HAVE_CAP
static cap_iab_t cap_iab = NULL; static cap_iab_t cap_iab = NULL;
static unsigned secbits = 0;
#endif #endif
extern char **environ; extern char **environ;
@ -427,6 +430,11 @@ static void child_process(char *exec, char **argv)
if (i != 0) if (i != 0)
eerrorx("Could not set iab: %s", strerror(errno)); eerrorx("Could not set iab: %s", strerror(errno));
} }
if (secbits != 0) {
if (cap_set_secbits(secbits) < 0)
eerrorx("Could not set securebits to 0x%x: %s", secbits, strerror(errno));
}
#endif #endif
/* remove the controlling tty */ /* remove the controlling tty */
@ -832,6 +840,20 @@ int main(int argc, char **argv)
#endif #endif
break; break;
case 0x101:
#ifdef HAVE_CAP
if (*optarg == '\0')
eerrorx("Secbits are empty");
tmp = NULL;
secbits = strtoul(optarg, &tmp, 0);
if (*tmp != '\0')
eerrorx("Could not parse secbits: invalid char %c", *tmp);
#else
eerrorx("Capabilities support not enabled");
#endif
break;
case 'D': /* --respawn-delay time */ case 'D': /* --respawn-delay time */
n = sscanf(optarg, "%d", &respawn_delay); n = sscanf(optarg, "%d", &respawn_delay);
if (n != 1 || respawn_delay < 1) if (n != 1 || respawn_delay < 1)