diff options
-rw-r--r-- | src/core/load-fragment.c | 2 | ||||
-rw-r--r-- | src/test/test-execute.c | 29 | ||||
-rw-r--r-- | src/test/test-unit-file.c | 46 | ||||
-rw-r--r-- | test/exec-capabilityboundingset-invert.service | 6 | ||||
-rw-r--r-- | test/exec-capabilityboundingset-merge.service | 7 | ||||
-rw-r--r-- | test/exec-capabilityboundingset-reset.service | 7 | ||||
-rw-r--r-- | test/exec-capabilityboundingset-simple.service | 6 |
7 files changed, 100 insertions, 3 deletions
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 8bd6a67538..333fca46c4 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -1023,7 +1023,7 @@ int config_parse_bounding_set(const char *unit, log_syntax(unit, LOG_ERR, filename, line, 0, "Trailing garbage, ignoring."); capability_bounding_set = invert ? ~sum : sum; - if (*capability_bounding_set_drop) + if (*capability_bounding_set_drop && capability_bounding_set) *capability_bounding_set_drop = ~(~*capability_bounding_set_drop | capability_bounding_set); else *capability_bounding_set_drop = ~capability_bounding_set; diff --git a/src/test/test-execute.c b/src/test/test-execute.c index dcd298d571..afbaa12e94 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -17,15 +17,16 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <stdio.h> -#include <sys/types.h> #include <grp.h> #include <pwd.h> +#include <stdio.h> +#include <sys/types.h> #include "fs-util.h" #include "macro.h" #include "manager.h" #include "mkdir.h" +#include "path-util.h" #include "rm-rf.h" #include "unit.h" #include "util.h" @@ -129,11 +130,15 @@ static void test_exec_systemcallerrornumber(Manager *m) { static void test_exec_user(Manager *m) { if (getpwnam("nobody")) test(m, "exec-user.service", 0, CLD_EXITED); + else + log_error_errno(errno, "Skipping test_exec_user, could not find nobody user: %m"); } static void test_exec_group(Manager *m) { if (getgrnam("nobody")) test(m, "exec-group.service", 0, CLD_EXITED); + else + log_error_errno(errno, "Skipping test_exec_group, could not find nobody group: %m"); } static void test_exec_environment(Manager *m) { @@ -152,6 +157,25 @@ static void test_exec_runtimedirectory(Manager *m) { test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED); if (getgrnam("nobody")) test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED); + else + log_error_errno(errno, "Skipping test_exec_runtimedirectory-owner, could not find nobody group: %m"); +} + +static void test_exec_capabilityboundingset(Manager *m) { + int r; + + /* We use capsh to test if the capabilities are + * properly set, so be sure that it exists */ + r = find_binary("capsh", NULL); + if (r < 0) { + log_error_errno(r, "Skipping test_exec_capabilityboundingset, could not find capsh binary: %m"); + return; + } + + test(m, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED); + test(m, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED); + test(m, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED); + test(m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED); } int main(int argc, char *argv[]) { @@ -168,6 +192,7 @@ int main(int argc, char *argv[]) { test_exec_environment, test_exec_umask, test_exec_runtimedirectory, + test_exec_capabilityboundingset, NULL, }; test_function_t *test = NULL; diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index c58c48af3c..a2ca391e1a 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -24,6 +24,7 @@ #include <stddef.h> #include <stdio.h> #include <string.h> +#include <sys/capability.h> #include <unistd.h> #include "alloc-util.h" @@ -629,6 +630,50 @@ static void test_install_printf(void) { expect(i4, "%U", "0"); } +static uint64_t make_cap(int cap) { + return ((uint64_t) 1ULL << (uint64_t) cap); +} + +static void test_config_parse_bounding_set(void) { + /* int config_parse_bounding_set( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) */ + int r; + uint64_t capability_bounding_set_drop = 0; + + r = config_parse_bounding_set(NULL, "fake", 1, "section", 1, + "CapabilityBoundingSet", 0, "CAP_NET_RAW", + &capability_bounding_set_drop, NULL); + assert_se(r >= 0); + assert_se(capability_bounding_set_drop == ~make_cap(CAP_NET_RAW)); + + r = config_parse_bounding_set(NULL, "fake", 1, "section", 1, + "CapabilityBoundingSet", 0, "CAP_NET_ADMIN", + &capability_bounding_set_drop, NULL); + assert_se(r >= 0); + assert_se(capability_bounding_set_drop == ~(make_cap(CAP_NET_RAW) | make_cap(CAP_NET_ADMIN))); + + r = config_parse_bounding_set(NULL, "fake", 1, "section", 1, + "CapabilityBoundingSet", 0, "", + &capability_bounding_set_drop, NULL); + assert_se(r >= 0); + assert_se(capability_bounding_set_drop == ~((uint64_t) 0ULL)); + + r = config_parse_bounding_set(NULL, "fake", 1, "section", 1, + "CapabilityBoundingSet", 0, "~", + &capability_bounding_set_drop, NULL); + assert_se(r >= 0); + assert_se(capability_bounding_set_drop == (uint64_t) 0ULL); +} + int main(int argc, char *argv[]) { int r; @@ -637,6 +682,7 @@ int main(int argc, char *argv[]) { r = test_unit_file_get_set(); test_config_parse_exec(); + test_config_parse_bounding_set(); test_load_env_file_1(); test_load_env_file_2(); test_load_env_file_3(); diff --git a/test/exec-capabilityboundingset-invert.service b/test/exec-capabilityboundingset-invert.service new file mode 100644 index 0000000000..e2b09e1550 --- /dev/null +++ b/test/exec-capabilityboundingset-invert.service @@ -0,0 +1,6 @@ +[Unit] +Description=Test for CapabilityBoundingSet + +[Service] +ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | grep "cap_chown"); echo $c; exit $(test -z $c)' +CapabilityBoundingSet=~CAP_CHOWN diff --git a/test/exec-capabilityboundingset-merge.service b/test/exec-capabilityboundingset-merge.service new file mode 100644 index 0000000000..b0f4732529 --- /dev/null +++ b/test/exec-capabilityboundingset-merge.service @@ -0,0 +1,7 @@ +[Unit] +Description=Test for CapabilityBoundingSet + +[Service] +ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | cut -f 2 -d "="); echo $c; exit $(test $c = "cap_chown,cap_fowner,cap_kill")' +CapabilityBoundingSet=CAP_FOWNER +CapabilityBoundingSet=CAP_KILL CAP_CHOWN diff --git a/test/exec-capabilityboundingset-reset.service b/test/exec-capabilityboundingset-reset.service new file mode 100644 index 0000000000..51092ab0d5 --- /dev/null +++ b/test/exec-capabilityboundingset-reset.service @@ -0,0 +1,7 @@ +[Unit] +Description=Test for CapabilityBoundingSet + +[Service] +ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | cut -f 2 -d "="); echo $c; exit $(test -z $c)' +CapabilityBoundingSet=CAP_FOWNER CAP_KILL +CapabilityBoundingSet= diff --git a/test/exec-capabilityboundingset-simple.service b/test/exec-capabilityboundingset-simple.service new file mode 100644 index 0000000000..b9037a0ddf --- /dev/null +++ b/test/exec-capabilityboundingset-simple.service @@ -0,0 +1,6 @@ +[Unit] +Description=Test for CapabilityBoundingSet + +[Service] +ExecStart=/bin/sh -c 'c=$(capsh --print | grep "Bounding set " | cut -f 2 -d "="); echo $c; exit $(test $c = "cap_fowner,cap_kill")' +CapabilityBoundingSet=CAP_FOWNER CAP_KILL |