LCOV - code coverage report
Current view: top level - test - test-execute.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 11 482 2.3 %
Date: 2019-08-23 13:36:53 Functions: 1 49 2.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1 388 0.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <grp.h>
       4                 :            : #include <pwd.h>
       5                 :            : #include <stdio.h>
       6                 :            : #include <sys/prctl.h>
       7                 :            : #include <sys/types.h>
       8                 :            : 
       9                 :            : #include "capability-util.h"
      10                 :            : #include "cpu-set-util.h"
      11                 :            : #include "errno-list.h"
      12                 :            : #include "fileio.h"
      13                 :            : #include "fs-util.h"
      14                 :            : #include "macro.h"
      15                 :            : #include "manager.h"
      16                 :            : #include "missing_prctl.h"
      17                 :            : #include "mkdir.h"
      18                 :            : #include "path-util.h"
      19                 :            : #include "rm-rf.h"
      20                 :            : #if HAVE_SECCOMP
      21                 :            : #include "seccomp-util.h"
      22                 :            : #endif
      23                 :            : #include "service.h"
      24                 :            : #include "stat-util.h"
      25                 :            : #include "test-helper.h"
      26                 :            : #include "tests.h"
      27                 :            : #include "unit.h"
      28                 :            : #include "user-util.h"
      29                 :            : #include "util.h"
      30                 :            : #include "virt.h"
      31                 :            : 
      32                 :            : static bool can_unshare;
      33                 :            : 
      34                 :            : typedef void (*test_function_t)(Manager *m);
      35                 :            : 
      36                 :          0 : static int cld_dumped_to_killed(int code) {
      37                 :            :         /* Depending on the system, seccomp version, … some signals might result in dumping, others in plain
      38                 :            :          * killing. Let's ignore the difference here, and map both cases to CLD_KILLED */
      39         [ #  # ]:          0 :         return code == CLD_DUMPED ? CLD_KILLED : code;
      40                 :            : }
      41                 :            : 
      42                 :          0 : static void wait_for_service_finish(Manager *m, Unit *unit) {
      43                 :          0 :         Service *service = NULL;
      44                 :            :         usec_t ts;
      45                 :          0 :         usec_t timeout = 2 * USEC_PER_MINUTE;
      46                 :            : 
      47         [ #  # ]:          0 :         assert_se(m);
      48         [ #  # ]:          0 :         assert_se(unit);
      49                 :            : 
      50                 :          0 :         service = SERVICE(unit);
      51                 :          0 :         printf("%s\n", unit->id);
      52                 :          0 :         exec_context_dump(&service->exec_context, stdout, "\t");
      53                 :          0 :         ts = now(CLOCK_MONOTONIC);
      54   [ #  #  #  # ]:          0 :         while (!IN_SET(service->state, SERVICE_DEAD, SERVICE_FAILED)) {
      55                 :            :                 int r;
      56                 :            :                 usec_t n;
      57                 :            : 
      58                 :          0 :                 r = sd_event_run(m->event, 100 * USEC_PER_MSEC);
      59         [ #  # ]:          0 :                 assert_se(r >= 0);
      60                 :            : 
      61                 :          0 :                 n = now(CLOCK_MONOTONIC);
      62         [ #  # ]:          0 :                 if (ts + timeout < n) {
      63         [ #  # ]:          0 :                         log_error("Test timeout when testing %s", unit->id);
      64                 :          0 :                         r = unit_kill(unit, KILL_ALL, SIGKILL, NULL);
      65         [ #  # ]:          0 :                         if (r < 0)
      66         [ #  # ]:          0 :                                 log_error_errno(r, "Failed to kill %s: %m", unit->id);
      67                 :          0 :                         exit(EXIT_FAILURE);
      68                 :            :                 }
      69                 :            :         }
      70                 :          0 : }
      71                 :            : 
      72                 :          0 : static void check_main_result(const char *func, Manager *m, Unit *unit, int status_expected, int code_expected) {
      73                 :          0 :         Service *service = NULL;
      74                 :            : 
      75         [ #  # ]:          0 :         assert_se(m);
      76         [ #  # ]:          0 :         assert_se(unit);
      77                 :            : 
      78                 :          0 :         wait_for_service_finish(m, unit);
      79                 :            : 
      80                 :          0 :         service = SERVICE(unit);
      81                 :          0 :         exec_status_dump(&service->main_exec_status, stdout, "\t");
      82                 :            : 
      83         [ #  # ]:          0 :         if (cld_dumped_to_killed(service->main_exec_status.code) != cld_dumped_to_killed(code_expected)) {
      84         [ #  # ]:          0 :                 log_error("%s: %s: exit code %d, expected %d",
      85                 :            :                           func, unit->id,
      86                 :            :                           service->main_exec_status.code, code_expected);
      87                 :          0 :                 abort();
      88                 :            :         }
      89                 :            : 
      90         [ #  # ]:          0 :         if (service->main_exec_status.status != status_expected) {
      91         [ #  # ]:          0 :                 log_error("%s: %s: exit status %d, expected %d",
      92                 :            :                           func, unit->id,
      93                 :            :                           service->main_exec_status.status, status_expected);
      94                 :          0 :                 abort();
      95                 :            :         }
      96                 :          0 : }
      97                 :            : 
      98                 :          0 : static void check_service_result(const char *func, Manager *m, Unit *unit, ServiceResult result_expected) {
      99                 :          0 :         Service *service = NULL;
     100                 :            : 
     101         [ #  # ]:          0 :         assert_se(m);
     102         [ #  # ]:          0 :         assert_se(unit);
     103                 :            : 
     104                 :          0 :         wait_for_service_finish(m, unit);
     105                 :            : 
     106                 :          0 :         service = SERVICE(unit);
     107                 :            : 
     108         [ #  # ]:          0 :         if (service->result != result_expected) {
     109         [ #  # ]:          0 :                 log_error("%s: %s: service end result %s, expected %s",
     110                 :            :                           func, unit->id,
     111                 :            :                           service_result_to_string(service->result),
     112                 :            :                           service_result_to_string(result_expected));
     113                 :          0 :                 abort();
     114                 :            :         }
     115                 :          0 : }
     116                 :            : 
     117                 :          0 : static bool check_nobody_user_and_group(void) {
     118                 :            :         static int cache = -1;
     119                 :            :         struct passwd *p;
     120                 :            :         struct group *g;
     121                 :            : 
     122         [ #  # ]:          0 :         if (cache >= 0)
     123                 :          0 :                 return !!cache;
     124                 :            : 
     125         [ #  # ]:          0 :         if (!synthesize_nobody())
     126                 :          0 :                 goto invalid;
     127                 :            : 
     128                 :          0 :         p = getpwnam(NOBODY_USER_NAME);
     129         [ #  # ]:          0 :         if (!p ||
     130         [ #  # ]:          0 :             !streq(p->pw_name, NOBODY_USER_NAME) ||
     131         [ #  # ]:          0 :             p->pw_uid != UID_NOBODY ||
     132         [ #  # ]:          0 :             p->pw_gid != GID_NOBODY)
     133                 :          0 :                 goto invalid;
     134                 :            : 
     135                 :          0 :         p = getpwuid(UID_NOBODY);
     136         [ #  # ]:          0 :         if (!p ||
     137         [ #  # ]:          0 :             !streq(p->pw_name, NOBODY_USER_NAME) ||
     138         [ #  # ]:          0 :             p->pw_uid != UID_NOBODY ||
     139         [ #  # ]:          0 :             p->pw_gid != GID_NOBODY)
     140                 :          0 :                 goto invalid;
     141                 :            : 
     142                 :          0 :         g = getgrnam(NOBODY_GROUP_NAME);
     143         [ #  # ]:          0 :         if (!g ||
     144         [ #  # ]:          0 :             !streq(g->gr_name, NOBODY_GROUP_NAME) ||
     145         [ #  # ]:          0 :             g->gr_gid != GID_NOBODY)
     146                 :          0 :                 goto invalid;
     147                 :            : 
     148                 :          0 :         g = getgrgid(GID_NOBODY);
     149         [ #  # ]:          0 :         if (!g ||
     150         [ #  # ]:          0 :             !streq(g->gr_name, NOBODY_GROUP_NAME) ||
     151         [ #  # ]:          0 :             g->gr_gid != GID_NOBODY)
     152                 :          0 :                 goto invalid;
     153                 :            : 
     154                 :          0 :         cache = 1;
     155                 :          0 :         return true;
     156                 :            : 
     157                 :          0 : invalid:
     158                 :          0 :         cache = 0;
     159                 :          0 :         return false;
     160                 :            : }
     161                 :            : 
     162                 :          0 : static bool check_user_has_group_with_same_name(const char *name) {
     163                 :            :         struct passwd *p;
     164                 :            :         struct group *g;
     165                 :            : 
     166         [ #  # ]:          0 :         assert(name);
     167                 :            : 
     168                 :          0 :         p = getpwnam(name);
     169         [ #  # ]:          0 :         if (!p ||
     170         [ #  # ]:          0 :             !streq(p->pw_name, name))
     171                 :          0 :                 return false;
     172                 :            : 
     173                 :          0 :         g = getgrgid(p->pw_gid);
     174         [ #  # ]:          0 :         if (!g ||
     175         [ #  # ]:          0 :             !streq(g->gr_name, name))
     176                 :          0 :                 return false;
     177                 :            : 
     178                 :          0 :         return true;
     179                 :            : }
     180                 :            : 
     181                 :          0 : static bool is_inaccessible_available(void) {
     182                 :            :         const char *p;
     183                 :            : 
     184         [ #  # ]:          0 :         FOREACH_STRING(p,
     185                 :            :                 "/run/systemd/inaccessible/reg",
     186                 :            :                 "/run/systemd/inaccessible/dir",
     187                 :            :                 "/run/systemd/inaccessible/chr",
     188                 :            :                 "/run/systemd/inaccessible/blk",
     189                 :            :                 "/run/systemd/inaccessible/fifo",
     190                 :            :                 "/run/systemd/inaccessible/sock"
     191                 :            :         ) {
     192         [ #  # ]:          0 :                 if (access(p, F_OK) < 0)
     193                 :          0 :                         return false;
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         return true;
     197                 :            : }
     198                 :            : 
     199                 :          0 : static void test(const char *func, Manager *m, const char *unit_name, int status_expected, int code_expected) {
     200                 :            :         Unit *unit;
     201                 :            : 
     202         [ #  # ]:          0 :         assert_se(unit_name);
     203                 :            : 
     204         [ #  # ]:          0 :         assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0);
     205         [ #  # ]:          0 :         assert_se(unit_start(unit) >= 0);
     206                 :          0 :         check_main_result(func, m, unit, status_expected, code_expected);
     207                 :          0 : }
     208                 :            : 
     209                 :          0 : static void test_service(const char *func, Manager *m, const char *unit_name, ServiceResult result_expected) {
     210                 :            :         Unit *unit;
     211                 :            : 
     212         [ #  # ]:          0 :         assert_se(unit_name);
     213                 :            : 
     214         [ #  # ]:          0 :         assert_se(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit) >= 0);
     215         [ #  # ]:          0 :         assert_se(unit_start(unit) >= 0);
     216                 :          0 :         check_service_result(func, m, unit, result_expected);
     217                 :          0 : }
     218                 :            : 
     219                 :          0 : static void test_exec_bindpaths(Manager *m) {
     220         [ #  # ]:          0 :         assert_se(mkdir_p("/tmp/test-exec-bindpaths", 0755) >= 0);
     221         [ #  # ]:          0 :         assert_se(mkdir_p("/tmp/test-exec-bindreadonlypaths", 0755) >= 0);
     222                 :            : 
     223         [ #  # ]:          0 :         test(__func__, m, "exec-bindpaths.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     224                 :            : 
     225                 :          0 :         (void) rm_rf("/tmp/test-exec-bindpaths", REMOVE_ROOT|REMOVE_PHYSICAL);
     226                 :          0 :         (void) rm_rf("/tmp/test-exec-bindreadonlypaths", REMOVE_ROOT|REMOVE_PHYSICAL);
     227                 :          0 : }
     228                 :            : 
     229                 :          0 : static void test_exec_cpuaffinity(Manager *m) {
     230         [ #  # ]:          0 :         _cleanup_(cpu_set_reset) CPUSet c = {};
     231                 :            : 
     232         [ #  # ]:          0 :         assert_se(cpu_set_realloc(&c, 8192) >= 0); /* just allocate the maximum possible size */
     233         [ #  # ]:          0 :         assert_se(sched_getaffinity(0, c.allocated, c.set) >= 0);
     234                 :            : 
     235   [ #  #  #  #  :          0 :         if (!CPU_ISSET_S(0, c.allocated, c.set)) {
                   #  # ]
     236         [ #  # ]:          0 :                 log_notice("Cannot use CPU 0, skipping %s", __func__);
     237                 :          0 :                 return;
     238                 :            :         }
     239                 :            : 
     240                 :          0 :         test(__func__, m, "exec-cpuaffinity1.service", 0, CLD_EXITED);
     241                 :          0 :         test(__func__, m, "exec-cpuaffinity2.service", 0, CLD_EXITED);
     242                 :            : 
     243   [ #  #  #  #  :          0 :         if (!CPU_ISSET_S(1, c.allocated, c.set) ||
                   #  # ]
     244   [ #  #  #  #  :          0 :             !CPU_ISSET_S(2, c.allocated, c.set)) {
                   #  # ]
     245         [ #  # ]:          0 :                 log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__);
     246                 :          0 :                 return;
     247                 :            :         }
     248                 :            : 
     249                 :          0 :         test(__func__, m, "exec-cpuaffinity3.service", 0, CLD_EXITED);
     250                 :            : }
     251                 :            : 
     252                 :          0 : static void test_exec_workingdirectory(Manager *m) {
     253         [ #  # ]:          0 :         assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0);
     254                 :            : 
     255                 :          0 :         test(__func__, m, "exec-workingdirectory.service", 0, CLD_EXITED);
     256                 :          0 :         test(__func__, m, "exec-workingdirectory-trailing-dot.service", 0, CLD_EXITED);
     257                 :            : 
     258                 :          0 :         (void) rm_rf("/tmp/test-exec_workingdirectory", REMOVE_ROOT|REMOVE_PHYSICAL);
     259                 :          0 : }
     260                 :            : 
     261                 :          0 : static void test_exec_personality(Manager *m) {
     262                 :            : #if defined(__x86_64__)
     263                 :          0 :         test(__func__, m, "exec-personality-x86-64.service", 0, CLD_EXITED);
     264                 :            : 
     265                 :            : #elif defined(__s390__)
     266                 :            :         test(__func__, m, "exec-personality-s390.service", 0, CLD_EXITED);
     267                 :            : 
     268                 :            : #elif defined(__powerpc64__)
     269                 :            : #  if __BYTE_ORDER == __BIG_ENDIAN
     270                 :            :         test(__func__, m, "exec-personality-ppc64.service", 0, CLD_EXITED);
     271                 :            : #  else
     272                 :            :         test(__func__, m, "exec-personality-ppc64le.service", 0, CLD_EXITED);
     273                 :            : #  endif
     274                 :            : 
     275                 :            : #elif defined(__aarch64__)
     276                 :            :         test(__func__, m, "exec-personality-aarch64.service", 0, CLD_EXITED);
     277                 :            : 
     278                 :            : #elif defined(__i386__)
     279                 :            :         test(__func__, m, "exec-personality-x86.service", 0, CLD_EXITED);
     280                 :            : #else
     281                 :            :         log_notice("Unknown personality, skipping %s", __func__);
     282                 :            : #endif
     283                 :          0 : }
     284                 :            : 
     285                 :          0 : static void test_exec_ignoresigpipe(Manager *m) {
     286                 :          0 :         test(__func__, m, "exec-ignoresigpipe-yes.service", 0, CLD_EXITED);
     287                 :          0 :         test(__func__, m, "exec-ignoresigpipe-no.service", SIGPIPE, CLD_KILLED);
     288                 :          0 : }
     289                 :            : 
     290                 :          0 : static void test_exec_privatetmp(Manager *m) {
     291         [ #  # ]:          0 :         assert_se(touch("/tmp/test-exec_privatetmp") >= 0);
     292                 :            : 
     293                 :          0 :         test(__func__, m, "exec-privatetmp-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     294                 :          0 :         test(__func__, m, "exec-privatetmp-no.service", 0, CLD_EXITED);
     295                 :            : 
     296                 :          0 :         unlink("/tmp/test-exec_privatetmp");
     297                 :          0 : }
     298                 :            : 
     299                 :          0 : static void test_exec_privatedevices(Manager *m) {
     300                 :            :         int r;
     301                 :            : 
     302         [ #  # ]:          0 :         if (detect_container() > 0) {
     303         [ #  # ]:          0 :                 log_notice("Testing in container, skipping %s", __func__);
     304                 :          0 :                 return;
     305                 :            :         }
     306         [ #  # ]:          0 :         if (!is_inaccessible_available()) {
     307         [ #  # ]:          0 :                 log_notice("Testing without inaccessible, skipping %s", __func__);
     308                 :          0 :                 return;
     309                 :            :         }
     310                 :            : 
     311                 :          0 :         test(__func__, m, "exec-privatedevices-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     312                 :          0 :         test(__func__, m, "exec-privatedevices-no.service", 0, CLD_EXITED);
     313                 :          0 :         test(__func__, m, "exec-privatedevices-disabled-by-prefix.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     314                 :            : 
     315                 :            :         /* We use capsh to test if the capabilities are
     316                 :            :          * properly set, so be sure that it exists */
     317                 :          0 :         r = find_binary("capsh", NULL);
     318         [ #  # ]:          0 :         if (r < 0) {
     319         [ #  # ]:          0 :                 log_notice_errno(r, "Could not find capsh binary, skipping remaining tests in %s: %m", __func__);
     320                 :          0 :                 return;
     321                 :            :         }
     322                 :            : 
     323                 :          0 :         test(__func__, m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED);
     324                 :          0 :         test(__func__, m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED);
     325                 :          0 :         test(__func__, m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED);
     326                 :          0 :         test(__func__, m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED);
     327                 :            : }
     328                 :            : 
     329                 :          0 : static void test_exec_protecthome(Manager *m) {
     330         [ #  # ]:          0 :         if (!can_unshare) {
     331         [ #  # ]:          0 :                 log_notice("Cannot reliably unshare, skipping %s", __func__);
     332                 :          0 :                 return;
     333                 :            :         }
     334                 :            : 
     335                 :          0 :         test(__func__, m, "exec-protecthome-tmpfs-vs-protectsystem-strict.service", 0, CLD_EXITED);
     336                 :            : }
     337                 :            : 
     338                 :          0 : static void test_exec_protectkernelmodules(Manager *m) {
     339                 :            :         int r;
     340                 :            : 
     341         [ #  # ]:          0 :         if (detect_container() > 0) {
     342         [ #  # ]:          0 :                 log_notice("Testing in container, skipping %s", __func__);
     343                 :          0 :                 return;
     344                 :            :         }
     345         [ #  # ]:          0 :         if (!is_inaccessible_available()) {
     346         [ #  # ]:          0 :                 log_notice("Testing without inaccessible, skipping %s", __func__);
     347                 :          0 :                 return;
     348                 :            :         }
     349                 :            : 
     350                 :          0 :         r = find_binary("capsh", NULL);
     351         [ #  # ]:          0 :         if (r < 0) {
     352         [ #  # ]:          0 :                 log_notice_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
     353                 :          0 :                 return;
     354                 :            :         }
     355                 :            : 
     356                 :          0 :         test(__func__, m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
     357                 :          0 :         test(__func__, m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
     358                 :          0 :         test(__func__, m, "exec-protectkernelmodules-yes-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     359                 :            : }
     360                 :            : 
     361                 :          0 : static void test_exec_readonlypaths(Manager *m) {
     362                 :            : 
     363                 :          0 :         test(__func__, m, "exec-readonlypaths-simple.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     364                 :            : 
     365         [ #  # ]:          0 :         if (path_is_read_only_fs("/var") > 0) {
     366         [ #  # ]:          0 :                 log_notice("Directory /var is readonly, skipping remaining tests in %s", __func__);
     367                 :          0 :                 return;
     368                 :            :         }
     369                 :            : 
     370                 :          0 :         test(__func__, m, "exec-readonlypaths.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     371         [ #  # ]:          0 :         test(__func__, m, "exec-readonlypaths-with-bindpaths.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     372                 :          0 :         test(__func__, m, "exec-readonlypaths-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     373                 :            : }
     374                 :            : 
     375                 :          0 : static void test_exec_readwritepaths(Manager *m) {
     376                 :            : 
     377         [ #  # ]:          0 :         if (path_is_read_only_fs("/") > 0) {
     378         [ #  # ]:          0 :                 log_notice("Root directory is readonly, skipping %s", __func__);
     379                 :          0 :                 return;
     380                 :            :         }
     381                 :            : 
     382                 :          0 :         test(__func__, m, "exec-readwritepaths-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     383                 :            : }
     384                 :            : 
     385                 :          0 : static void test_exec_inaccessiblepaths(Manager *m) {
     386                 :            : 
     387         [ #  # ]:          0 :         if (!is_inaccessible_available()) {
     388         [ #  # ]:          0 :                 log_notice("Testing without inaccessible, skipping %s", __func__);
     389                 :          0 :                 return;
     390                 :            :         }
     391                 :            : 
     392                 :          0 :         test(__func__, m, "exec-inaccessiblepaths-sys.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     393                 :            : 
     394         [ #  # ]:          0 :         if (path_is_read_only_fs("/") > 0) {
     395         [ #  # ]:          0 :                 log_notice("Root directory is readonly, skipping remaining tests in %s", __func__);
     396                 :          0 :                 return;
     397                 :            :         }
     398                 :            : 
     399                 :          0 :         test(__func__, m, "exec-inaccessiblepaths-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     400                 :            : }
     401                 :            : 
     402                 :          0 : static void test_exec_temporaryfilesystem(Manager *m) {
     403                 :            : 
     404         [ #  # ]:          0 :         test(__func__, m, "exec-temporaryfilesystem-options.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     405         [ #  # ]:          0 :         test(__func__, m, "exec-temporaryfilesystem-ro.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     406         [ #  # ]:          0 :         test(__func__, m, "exec-temporaryfilesystem-rw.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     407         [ #  # ]:          0 :         test(__func__, m, "exec-temporaryfilesystem-usr.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     408                 :          0 : }
     409                 :            : 
     410                 :          0 : static void test_exec_systemcallfilter(Manager *m) {
     411                 :            : #if HAVE_SECCOMP
     412                 :            :         int r;
     413                 :            : 
     414         [ #  # ]:          0 :         if (!is_seccomp_available()) {
     415         [ #  # ]:          0 :                 log_notice("Seccomp not available, skipping %s", __func__);
     416                 :          0 :                 return;
     417                 :            :         }
     418                 :            : 
     419                 :          0 :         test(__func__, m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
     420                 :          0 :         test(__func__, m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
     421                 :          0 :         test(__func__, m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
     422                 :          0 :         test(__func__, m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
     423                 :            : 
     424                 :          0 :         r = find_binary("python3", NULL);
     425         [ #  # ]:          0 :         if (r < 0) {
     426         [ #  # ]:          0 :                 log_notice_errno(r, "Skipping remaining tests in %s, could not find python3 binary: %m", __func__);
     427                 :          0 :                 return;
     428                 :            :         }
     429                 :            : 
     430                 :          0 :         test(__func__, m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED);
     431                 :          0 :         test(__func__, m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED);
     432                 :          0 :         test(__func__, m, "exec-systemcallfilter-with-errno-multi.service", errno_from_name("EILSEQ"), CLD_EXITED);
     433                 :            : #endif
     434                 :            : }
     435                 :            : 
     436                 :          0 : static void test_exec_systemcallerrornumber(Manager *m) {
     437                 :            : #if HAVE_SECCOMP
     438                 :            :         int r;
     439                 :            : 
     440         [ #  # ]:          0 :         if (!is_seccomp_available()) {
     441         [ #  # ]:          0 :                 log_notice("Seccomp not available, skipping %s", __func__);
     442                 :          0 :                 return;
     443                 :            :         }
     444                 :            : 
     445                 :          0 :         r = find_binary("python3", NULL);
     446         [ #  # ]:          0 :         if (r < 0) {
     447         [ #  # ]:          0 :                 log_notice_errno(r, "Skipping %s, could not find python3 binary: %m", __func__);
     448                 :          0 :                 return;
     449                 :            :         }
     450                 :            : 
     451                 :          0 :         test(__func__, m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED);
     452                 :          0 :         test(__func__, m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED);
     453                 :            : #endif
     454                 :            : }
     455                 :            : 
     456                 :          0 : static void test_exec_restrictnamespaces(Manager *m) {
     457                 :            : #if HAVE_SECCOMP
     458         [ #  # ]:          0 :         if (!is_seccomp_available()) {
     459         [ #  # ]:          0 :                 log_notice("Seccomp not available, skipping %s", __func__);
     460                 :          0 :                 return;
     461                 :            :         }
     462                 :            : 
     463                 :          0 :         test(__func__, m, "exec-restrictnamespaces-no.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     464                 :          0 :         test(__func__, m, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED);
     465                 :          0 :         test(__func__, m, "exec-restrictnamespaces-mnt.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     466                 :          0 :         test(__func__, m, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED);
     467                 :          0 :         test(__func__, m, "exec-restrictnamespaces-merge-and.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     468                 :          0 :         test(__func__, m, "exec-restrictnamespaces-merge-or.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     469                 :          0 :         test(__func__, m, "exec-restrictnamespaces-merge-all.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
     470                 :            : #endif
     471                 :            : }
     472                 :            : 
     473                 :          0 : static void test_exec_systemcallfilter_system(Manager *m) {
     474                 :            : /* Skip this particular test case when running under ASan, as
     475                 :            :  * LSan intermittently segfaults when accessing memory right
     476                 :            :  * after the test finishes. Generally, ASan & LSan don't like
     477                 :            :  * the seccomp stuff.
     478                 :            :  */
     479                 :            : #if HAVE_SECCOMP && !HAS_FEATURE_ADDRESS_SANITIZER
     480         [ #  # ]:          0 :         if (!is_seccomp_available()) {
     481         [ #  # ]:          0 :                 log_notice("Seccomp not available, skipping %s", __func__);
     482                 :          0 :                 return;
     483                 :            :         }
     484                 :            : 
     485                 :          0 :         test(__func__, m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
     486                 :            : 
     487         [ #  # ]:          0 :         if (!check_nobody_user_and_group()) {
     488         [ #  # ]:          0 :                 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
     489                 :          0 :                 return;
     490                 :            :         }
     491                 :            : 
     492         [ #  # ]:          0 :         if (!STR_IN_SET(NOBODY_USER_NAME, "nobody", "nfsnobody")) {
     493         [ #  # ]:          0 :                 log_notice("Unsupported nobody user name '%s', skipping remaining tests in %s", NOBODY_USER_NAME, __func__);
     494                 :          0 :                 return;
     495                 :            :         }
     496                 :            : 
     497                 :          0 :         test(__func__, m, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
     498                 :            : #endif
     499                 :            : }
     500                 :            : 
     501                 :          0 : static void test_exec_user(Manager *m) {
     502                 :          0 :         test(__func__, m, "exec-user.service", 0, CLD_EXITED);
     503                 :            : 
     504         [ #  # ]:          0 :         if (!check_nobody_user_and_group()) {
     505         [ #  # ]:          0 :                 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
     506                 :          0 :                 return;
     507                 :            :         }
     508                 :            : 
     509         [ #  # ]:          0 :         if (!STR_IN_SET(NOBODY_USER_NAME, "nobody", "nfsnobody")) {
     510         [ #  # ]:          0 :                 log_notice("Unsupported nobody user name '%s', skipping remaining tests in %s", NOBODY_USER_NAME, __func__);
     511                 :          0 :                 return;
     512                 :            :         }
     513                 :            : 
     514                 :          0 :         test(__func__, m, "exec-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
     515                 :            : }
     516                 :            : 
     517                 :          0 : static void test_exec_group(Manager *m) {
     518                 :          0 :         test(__func__, m, "exec-group.service", 0, CLD_EXITED);
     519                 :            : 
     520         [ #  # ]:          0 :         if (!check_nobody_user_and_group()) {
     521         [ #  # ]:          0 :                 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
     522                 :          0 :                 return;
     523                 :            :         }
     524                 :            : 
     525         [ #  # ]:          0 :         if (!STR_IN_SET(NOBODY_GROUP_NAME, "nobody", "nfsnobody", "nogroup")) {
     526         [ #  # ]:          0 :                 log_notice("Unsupported nobody group name '%s', skipping remaining tests in %s", NOBODY_GROUP_NAME, __func__);
     527                 :          0 :                 return;
     528                 :            :         }
     529                 :            : 
     530                 :          0 :         test(__func__, m, "exec-group-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED);
     531                 :            : }
     532                 :            : 
     533                 :          0 : static void test_exec_supplementarygroups(Manager *m) {
     534                 :          0 :         test(__func__, m, "exec-supplementarygroups.service", 0, CLD_EXITED);
     535                 :          0 :         test(__func__, m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
     536                 :          0 :         test(__func__, m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
     537                 :          0 :         test(__func__, m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
     538                 :          0 :         test(__func__, m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
     539                 :          0 :         test(__func__, m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
     540                 :          0 : }
     541                 :            : 
     542                 :          0 : static void test_exec_dynamicuser(Manager *m) {
     543                 :            : 
     544         [ #  # ]:          0 :         test(__func__, m, "exec-dynamicuser-fixeduser.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     545         [ #  # ]:          0 :         if (check_user_has_group_with_same_name("adm"))
     546         [ #  # ]:          0 :                 test(__func__, m, "exec-dynamicuser-fixeduser-adm.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     547         [ #  # ]:          0 :         if (check_user_has_group_with_same_name("games"))
     548         [ #  # ]:          0 :                 test(__func__, m, "exec-dynamicuser-fixeduser-games.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     549         [ #  # ]:          0 :         test(__func__, m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     550         [ #  # ]:          0 :         test(__func__, m, "exec-dynamicuser-supplementarygroups.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     551         [ #  # ]:          0 :         test(__func__, m, "exec-dynamicuser-statedir.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     552                 :            : 
     553                 :          0 :         (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
     554                 :          0 :         (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
     555                 :          0 :         (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
     556                 :          0 :         (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
     557                 :            : 
     558                 :          0 :         test(__func__, m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
     559         [ #  # ]:          0 :         test(__func__, m, "exec-dynamicuser-statedir-migrate-step2.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
     560                 :            : 
     561                 :          0 :         (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
     562                 :          0 :         (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
     563                 :          0 :         (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
     564                 :          0 :         (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
     565                 :          0 : }
     566                 :            : 
     567                 :          0 : static void test_exec_environment(Manager *m) {
     568                 :          0 :         test(__func__, m, "exec-environment-no-substitute.service", 0, CLD_EXITED);
     569                 :          0 :         test(__func__, m, "exec-environment.service", 0, CLD_EXITED);
     570                 :          0 :         test(__func__, m, "exec-environment-multiple.service", 0, CLD_EXITED);
     571                 :          0 :         test(__func__, m, "exec-environment-empty.service", 0, CLD_EXITED);
     572                 :          0 : }
     573                 :            : 
     574                 :          0 : static void test_exec_environmentfile(Manager *m) {
     575                 :            :         static const char e[] =
     576                 :            :                 "VAR1='word1 word2'\n"
     577                 :            :                 "VAR2=word3 \n"
     578                 :            :                 "# comment1\n"
     579                 :            :                 "\n"
     580                 :            :                 "; comment2\n"
     581                 :            :                 " ; # comment3\n"
     582                 :            :                 "line without an equal\n"
     583                 :            :                 "VAR3='$word 5 6'\n"
     584                 :            :                 "VAR4='new\nline'\n"
     585                 :            :                 "VAR5=password\\with\\backslashes";
     586                 :            :         int r;
     587                 :            : 
     588                 :          0 :         r = write_string_file("/tmp/test-exec_environmentfile.conf", e, WRITE_STRING_FILE_CREATE);
     589         [ #  # ]:          0 :         assert_se(r == 0);
     590                 :            : 
     591                 :          0 :         test(__func__, m, "exec-environmentfile.service", 0, CLD_EXITED);
     592                 :            : 
     593                 :          0 :         (void) unlink("/tmp/test-exec_environmentfile.conf");
     594                 :          0 : }
     595                 :            : 
     596                 :          0 : static void test_exec_passenvironment(Manager *m) {
     597                 :            :         /* test-execute runs under MANAGER_USER which, by default, forwards all
     598                 :            :          * variables present in the environment, but only those that are
     599                 :            :          * present _at the time it is created_!
     600                 :            :          *
     601                 :            :          * So these PassEnvironment checks are still expected to work, since we
     602                 :            :          * are ensuring the variables are not present at manager creation (they
     603                 :            :          * are unset explicitly in main) and are only set here.
     604                 :            :          *
     605                 :            :          * This is still a good approximation of how a test for MANAGER_SYSTEM
     606                 :            :          * would work.
     607                 :            :          */
     608         [ #  # ]:          0 :         assert_se(setenv("VAR1", "word1 word2", 1) == 0);
     609         [ #  # ]:          0 :         assert_se(setenv("VAR2", "word3", 1) == 0);
     610         [ #  # ]:          0 :         assert_se(setenv("VAR3", "$word 5 6", 1) == 0);
     611         [ #  # ]:          0 :         assert_se(setenv("VAR4", "new\nline", 1) == 0);
     612         [ #  # ]:          0 :         assert_se(setenv("VAR5", "passwordwithbackslashes", 1) == 0);
     613                 :          0 :         test(__func__, m, "exec-passenvironment.service", 0, CLD_EXITED);
     614                 :          0 :         test(__func__, m, "exec-passenvironment-repeated.service", 0, CLD_EXITED);
     615                 :          0 :         test(__func__, m, "exec-passenvironment-empty.service", 0, CLD_EXITED);
     616         [ #  # ]:          0 :         assert_se(unsetenv("VAR1") == 0);
     617         [ #  # ]:          0 :         assert_se(unsetenv("VAR2") == 0);
     618         [ #  # ]:          0 :         assert_se(unsetenv("VAR3") == 0);
     619         [ #  # ]:          0 :         assert_se(unsetenv("VAR4") == 0);
     620         [ #  # ]:          0 :         assert_se(unsetenv("VAR5") == 0);
     621                 :          0 :         test(__func__, m, "exec-passenvironment-absent.service", 0, CLD_EXITED);
     622                 :          0 : }
     623                 :            : 
     624                 :          0 : static void test_exec_umask(Manager *m) {
     625                 :          0 :         test(__func__, m, "exec-umask-default.service", 0, CLD_EXITED);
     626                 :          0 :         test(__func__, m, "exec-umask-0177.service", 0, CLD_EXITED);
     627                 :          0 : }
     628                 :            : 
     629                 :          0 : static void test_exec_runtimedirectory(Manager *m) {
     630                 :          0 :         test(__func__, m, "exec-runtimedirectory.service", 0, CLD_EXITED);
     631                 :          0 :         test(__func__, m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
     632                 :          0 :         test(__func__, m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
     633                 :            : 
     634         [ #  # ]:          0 :         if (!check_nobody_user_and_group()) {
     635         [ #  # ]:          0 :                 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
     636                 :          0 :                 return;
     637                 :            :         }
     638                 :            : 
     639         [ #  # ]:          0 :         if (!STR_IN_SET(NOBODY_GROUP_NAME, "nobody", "nfsnobody", "nogroup")) {
     640         [ #  # ]:          0 :                 log_notice("Unsupported nobody group name '%s', skipping remaining tests in %s", NOBODY_GROUP_NAME, __func__);
     641                 :          0 :                 return;
     642                 :            :         }
     643                 :            : 
     644                 :          0 :         test(__func__, m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED);
     645                 :            : }
     646                 :            : 
     647                 :          0 : static void test_exec_capabilityboundingset(Manager *m) {
     648                 :            :         int r;
     649                 :            : 
     650                 :          0 :         r = find_binary("capsh", NULL);
     651         [ #  # ]:          0 :         if (r < 0) {
     652         [ #  # ]:          0 :                 log_notice_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
     653                 :          0 :                 return;
     654                 :            :         }
     655                 :            : 
     656   [ #  #  #  # ]:          0 :         if (have_effective_cap(CAP_CHOWN) <= 0 ||
     657         [ #  # ]:          0 :             have_effective_cap(CAP_FOWNER) <= 0 ||
     658                 :          0 :             have_effective_cap(CAP_KILL) <= 0) {
     659         [ #  # ]:          0 :                 log_notice("Skipping %s, this process does not have enough capabilities", __func__);
     660                 :          0 :                 return;
     661                 :            :         }
     662                 :            : 
     663                 :          0 :         test(__func__, m, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED);
     664                 :          0 :         test(__func__, m, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED);
     665                 :          0 :         test(__func__, m, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED);
     666                 :          0 :         test(__func__, m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED);
     667                 :            : }
     668                 :            : 
     669                 :          0 : static void test_exec_basic(Manager *m) {
     670                 :          0 :         test(__func__, m, "exec-basic.service", 0, CLD_EXITED);
     671                 :          0 : }
     672                 :            : 
     673                 :          0 : static void test_exec_ambientcapabilities(Manager *m) {
     674                 :            :         int r;
     675                 :            : 
     676                 :            :         /* Check if the kernel has support for ambient capabilities. Run
     677                 :            :          * the tests only if that's the case. Clearing all ambient
     678                 :            :          * capabilities is fine, since we are expecting them to be unset
     679                 :            :          * in the first place for the tests. */
     680                 :          0 :         r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
     681   [ #  #  #  #  :          0 :         if (r < 0 && IN_SET(errno, EINVAL, EOPNOTSUPP, ENOSYS)) {
                   #  # ]
     682         [ #  # ]:          0 :                 log_notice("Skipping %s, the kernel does not support ambient capabilities", __func__);
     683                 :          0 :                 return;
     684                 :            :         }
     685                 :            : 
     686   [ #  #  #  # ]:          0 :         if (have_effective_cap(CAP_CHOWN) <= 0 ||
     687                 :          0 :             have_effective_cap(CAP_NET_RAW) <= 0) {
     688         [ #  # ]:          0 :                 log_notice("Skipping %s, this process does not have enough capabilities", __func__);
     689                 :          0 :                 return;
     690                 :            :         }
     691                 :            : 
     692                 :          0 :         test(__func__, m, "exec-ambientcapabilities.service", 0, CLD_EXITED);
     693                 :          0 :         test(__func__, m, "exec-ambientcapabilities-merge.service", 0, CLD_EXITED);
     694                 :            : 
     695         [ #  # ]:          0 :         if (!check_nobody_user_and_group()) {
     696         [ #  # ]:          0 :                 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
     697                 :          0 :                 return;
     698                 :            :         }
     699                 :            : 
     700         [ #  # ]:          0 :         if (!STR_IN_SET(NOBODY_USER_NAME, "nobody", "nfsnobody")) {
     701         [ #  # ]:          0 :                 log_notice("Unsupported nobody user name '%s', skipping remaining tests in %s", NOBODY_USER_NAME, __func__);
     702                 :          0 :                 return;
     703                 :            :         }
     704                 :            : 
     705                 :          0 :         test(__func__, m, "exec-ambientcapabilities-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
     706                 :          0 :         test(__func__, m, "exec-ambientcapabilities-merge-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
     707                 :            : }
     708                 :            : 
     709                 :          0 : static void test_exec_privatenetwork(Manager *m) {
     710                 :            :         int r;
     711                 :            : 
     712                 :          0 :         r = find_binary("ip", NULL);
     713         [ #  # ]:          0 :         if (r < 0) {
     714         [ #  # ]:          0 :                 log_notice_errno(r, "Skipping %s, could not find ip binary: %m", __func__);
     715                 :          0 :                 return;
     716                 :            :         }
     717                 :            : 
     718         [ #  # ]:          0 :         test(__func__, m, "exec-privatenetwork-yes.service", can_unshare ? 0 : EXIT_NETWORK, CLD_EXITED);
     719                 :            : }
     720                 :            : 
     721                 :          0 : static void test_exec_oomscoreadjust(Manager *m) {
     722                 :          0 :         test(__func__, m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED);
     723                 :            : 
     724         [ #  # ]:          0 :         if (detect_container() > 0) {
     725         [ #  # ]:          0 :                 log_notice("Testing in container, skipping remaining tests in %s", __func__);
     726                 :          0 :                 return;
     727                 :            :         }
     728                 :          0 :         test(__func__, m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED);
     729                 :            : }
     730                 :            : 
     731                 :          0 : static void test_exec_ioschedulingclass(Manager *m) {
     732                 :          0 :         test(__func__, m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED);
     733                 :          0 :         test(__func__, m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED);
     734                 :          0 :         test(__func__, m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED);
     735                 :            : 
     736         [ #  # ]:          0 :         if (detect_container() > 0) {
     737         [ #  # ]:          0 :                 log_notice("Testing in container, skipping remaining tests in %s", __func__);
     738                 :          0 :                 return;
     739                 :            :         }
     740                 :          0 :         test(__func__, m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
     741                 :            : }
     742                 :            : 
     743                 :          0 : static void test_exec_unsetenvironment(Manager *m) {
     744                 :          0 :         test(__func__, m, "exec-unsetenvironment.service", 0, CLD_EXITED);
     745                 :          0 : }
     746                 :            : 
     747                 :          0 : static void test_exec_specifier(Manager *m) {
     748                 :          0 :         test(__func__, m, "exec-specifier.service", 0, CLD_EXITED);
     749                 :          0 :         test(__func__, m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
     750                 :          0 :         test(__func__, m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
     751                 :          0 : }
     752                 :            : 
     753                 :          0 : static void test_exec_standardinput(Manager *m) {
     754                 :          0 :         test(__func__, m, "exec-standardinput-data.service", 0, CLD_EXITED);
     755                 :          0 :         test(__func__, m, "exec-standardinput-file.service", 0, CLD_EXITED);
     756                 :          0 : }
     757                 :            : 
     758                 :          0 : static void test_exec_standardoutput(Manager *m) {
     759                 :          0 :         test(__func__, m, "exec-standardoutput-file.service", 0, CLD_EXITED);
     760                 :          0 : }
     761                 :            : 
     762                 :          0 : static void test_exec_standardoutput_append(Manager *m) {
     763                 :          0 :         test(__func__, m, "exec-standardoutput-append.service", 0, CLD_EXITED);
     764                 :          0 : }
     765                 :            : 
     766                 :          0 : static void test_exec_condition(Manager *m) {
     767                 :          0 :         test_service(__func__, m, "exec-condition-failed.service", SERVICE_FAILURE_EXIT_CODE);
     768                 :          0 :         test_service(__func__, m, "exec-condition-skip.service", SERVICE_SKIP_CONDITION);
     769                 :          0 : }
     770                 :            : 
     771                 :            : typedef struct test_entry {
     772                 :            :         test_function_t f;
     773                 :            :         const char *name;
     774                 :            : } test_entry;
     775                 :            : 
     776                 :            : #define entry(x) {x, #x}
     777                 :            : 
     778                 :          0 : static int run_tests(UnitFileScope scope, const test_entry tests[], char **patterns) {
     779                 :          0 :         const test_entry *test = NULL;
     780                 :          0 :         _cleanup_(manager_freep) Manager *m = NULL;
     781                 :            :         int r;
     782                 :            : 
     783         [ #  # ]:          0 :         assert_se(tests);
     784                 :            : 
     785                 :          0 :         r = manager_new(scope, MANAGER_TEST_RUN_BASIC, &m);
     786   [ #  #  #  # ]:          0 :         if (MANAGER_SKIP_TEST(r))
     787                 :          0 :                 return log_tests_skipped_errno(r, "manager_new");
     788         [ #  # ]:          0 :         assert_se(r >= 0);
     789         [ #  # ]:          0 :         assert_se(manager_startup(m, NULL, NULL) >= 0);
     790                 :            : 
     791   [ #  #  #  # ]:          0 :         for (test = tests; test && test->f; test++)
     792         [ #  # ]:          0 :                 if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE))
     793                 :          0 :                         test->f(m);
     794                 :            :                 else
     795         [ #  # ]:          0 :                         log_info("Skipping %s because it does not match any pattern.", test->name);
     796                 :            : 
     797                 :          0 :         return 0;
     798                 :            : }
     799                 :            : 
     800                 :          4 : int main(int argc, char *argv[]) {
     801                 :          4 :         _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
     802                 :          4 :         _cleanup_free_ char *test_execute_path = NULL;
     803                 :            : 
     804                 :            :         static const test_entry user_tests[] = {
     805                 :            :                 entry(test_exec_basic),
     806                 :            :                 entry(test_exec_ambientcapabilities),
     807                 :            :                 entry(test_exec_bindpaths),
     808                 :            :                 entry(test_exec_capabilityboundingset),
     809                 :            :                 entry(test_exec_condition),
     810                 :            :                 entry(test_exec_cpuaffinity),
     811                 :            :                 entry(test_exec_environment),
     812                 :            :                 entry(test_exec_environmentfile),
     813                 :            :                 entry(test_exec_group),
     814                 :            :                 entry(test_exec_ignoresigpipe),
     815                 :            :                 entry(test_exec_inaccessiblepaths),
     816                 :            :                 entry(test_exec_ioschedulingclass),
     817                 :            :                 entry(test_exec_oomscoreadjust),
     818                 :            :                 entry(test_exec_passenvironment),
     819                 :            :                 entry(test_exec_personality),
     820                 :            :                 entry(test_exec_privatedevices),
     821                 :            :                 entry(test_exec_privatenetwork),
     822                 :            :                 entry(test_exec_privatetmp),
     823                 :            :                 entry(test_exec_protecthome),
     824                 :            :                 entry(test_exec_protectkernelmodules),
     825                 :            :                 entry(test_exec_readonlypaths),
     826                 :            :                 entry(test_exec_readwritepaths),
     827                 :            :                 entry(test_exec_restrictnamespaces),
     828                 :            :                 entry(test_exec_runtimedirectory),
     829                 :            :                 entry(test_exec_standardinput),
     830                 :            :                 entry(test_exec_standardoutput),
     831                 :            :                 entry(test_exec_standardoutput_append),
     832                 :            :                 entry(test_exec_supplementarygroups),
     833                 :            :                 entry(test_exec_systemcallerrornumber),
     834                 :            :                 entry(test_exec_systemcallfilter),
     835                 :            :                 entry(test_exec_temporaryfilesystem),
     836                 :            :                 entry(test_exec_umask),
     837                 :            :                 entry(test_exec_unsetenvironment),
     838                 :            :                 entry(test_exec_user),
     839                 :            :                 entry(test_exec_workingdirectory),
     840                 :            :                 {},
     841                 :            :         };
     842                 :            :         static const test_entry system_tests[] = {
     843                 :            :                 entry(test_exec_dynamicuser),
     844                 :            :                 entry(test_exec_specifier),
     845                 :            :                 entry(test_exec_systemcallfilter_system),
     846                 :            :                 {},
     847                 :            :         };
     848                 :            :         int r;
     849                 :            : 
     850                 :          4 :         test_setup_logging(LOG_DEBUG);
     851                 :            : 
     852                 :            : #if HAS_FEATURE_ADDRESS_SANITIZER
     853                 :            :         if (is_run_on_travis_ci()) {
     854                 :            :                 log_notice("Running on TravisCI under ASan, skipping, see https://github.com/systemd/systemd/issues/10696");
     855                 :            :                 return EXIT_TEST_SKIP;
     856                 :            :         }
     857                 :            : #endif
     858                 :            : 
     859                 :          4 :         (void) unsetenv("USER");
     860                 :          4 :         (void) unsetenv("LOGNAME");
     861                 :          4 :         (void) unsetenv("SHELL");
     862                 :          4 :         (void) unsetenv("HOME");
     863                 :            : 
     864                 :          4 :         can_unshare = have_namespaces();
     865                 :            : 
     866                 :            :         /* It is needed otherwise cgroup creation fails */
     867         [ +  - ]:          4 :         if (getuid() != 0)
     868                 :          4 :                 return log_tests_skipped("not root");
     869                 :            : 
     870                 :          0 :         r = enter_cgroup_subroot();
     871         [ #  # ]:          0 :         if (r == -ENOMEDIUM)
     872                 :          0 :                 return log_tests_skipped("cgroupfs not available");
     873                 :            : 
     874         [ #  # ]:          0 :         assert_se(runtime_dir = setup_fake_runtime_dir());
     875                 :          0 :         test_execute_path = path_join(get_testdata_dir(), "test-execute");
     876         [ #  # ]:          0 :         assert_se(set_unit_path(test_execute_path) >= 0);
     877                 :            : 
     878                 :            :         /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
     879                 :            :          * cases, otherwise (and if they are present in the environment),
     880                 :            :          * `manager_default_environment` will copy them into the default
     881                 :            :          * environment which is passed to each created job, which will make the
     882                 :            :          * tests that expect those not to be present to fail.
     883                 :            :          */
     884         [ #  # ]:          0 :         assert_se(unsetenv("VAR1") == 0);
     885         [ #  # ]:          0 :         assert_se(unsetenv("VAR2") == 0);
     886         [ #  # ]:          0 :         assert_se(unsetenv("VAR3") == 0);
     887                 :            : 
     888                 :          0 :         r = run_tests(UNIT_FILE_USER, user_tests, argv + 1);
     889         [ #  # ]:          0 :         if (r != 0)
     890                 :          0 :                 return r;
     891                 :            : 
     892                 :          0 :         r = run_tests(UNIT_FILE_SYSTEM, system_tests, argv + 1);
     893         [ #  # ]:          0 :         if (r != 0)
     894                 :          0 :                 return r;
     895                 :            : 
     896                 :            : #if HAVE_SECCOMP
     897                 :            :         /* The following tests are for 1beab8b0d0ff2d7d1436b52d4a0c3d56dc908962. */
     898         [ #  # ]:          0 :         if (!is_seccomp_available()) {
     899         [ #  # ]:          0 :                 log_notice("Seccomp not available, skipping unshare() filtered tests.");
     900                 :          0 :                 return 0;
     901                 :            :         }
     902                 :            : 
     903                 :          0 :         _cleanup_hashmap_free_ Hashmap *s = NULL;
     904         [ #  # ]:          0 :         assert_se(s = hashmap_new(NULL));
     905                 :          0 :         r = seccomp_syscall_resolve_name("unshare");
     906         [ #  # ]:          0 :         assert_se(r != __NR_SCMP_ERROR);
     907         [ #  # ]:          0 :         assert_se(hashmap_put(s, UINT32_TO_PTR(r + 1), INT_TO_PTR(-1)) >= 0);
     908         [ #  # ]:          0 :         assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EOPNOTSUPP), true) >= 0);
     909         [ #  # ]:          0 :         assert_se(unshare(CLONE_NEWNS) < 0);
     910         [ #  # ]:          0 :         assert_se(errno == EOPNOTSUPP);
     911                 :            : 
     912                 :          0 :         can_unshare = false;
     913                 :            : 
     914                 :          0 :         r = run_tests(UNIT_FILE_USER, user_tests, argv + 1);
     915         [ #  # ]:          0 :         if (r != 0)
     916                 :          0 :                 return r;
     917                 :            : 
     918                 :          0 :         return run_tests(UNIT_FILE_SYSTEM, system_tests, argv + 1);
     919                 :            : #else
     920                 :            :         return 0;
     921                 :            : #endif
     922                 :            : }

Generated by: LCOV version 1.14