6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier This file is part of systemd
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier Copyright 2014 Ronny Chevalier
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier systemd is free software; you can redistribute it and/or modify it
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier under the terms of the GNU Lesser General Public License as published by
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier the Free Software Foundation; either version 2.1 of the License, or
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier (at your option) any later version.
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier systemd is distributed in the hope that it will be useful, but
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier WITHOUT ANY WARRANTY; without even the implied warranty of
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier Lesser General Public License for more details.
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier You should have received a copy of the GNU Lesser General Public License
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering/* We keep CAP_DAC_OVERRIDE to avoid errors with gcov when doing test coverage */
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalierstatic uint64_t test_flags = 1ULL << CAP_DAC_OVERRIDE;
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalierstatic void fork_test(void (*test_func)(void)) {
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier } else if (pid > 0) {
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier assert_se(WIFEXITED(status) && WEXITSTATUS(status) == 0);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_error_errno(errno, "Could not find nobody user: %m");
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen /* There's support for PR_CAP_AMBIENT if the prctl() call
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen * succeeded or error code was something else than EINVAL. The
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen * EINVAL check should be good enough to rule out false
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen * positives. */
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalierstatic void test_drop_privileges_keep_net_raw(void) {
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier assert_se(drop_privileges(test_uid, test_gid, test_flags | (1ULL << CAP_NET_RAW)) >= 0);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalierstatic void test_drop_privileges_dontkeep_net_raw(void) {
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier assert_se(drop_privileges(test_uid, test_gid, test_flags) >= 0);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier sock = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalierstatic void test_drop_privileges_fail(void) {
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier assert_se(drop_privileges(test_uid, test_gid, test_flags) >= 0);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier assert_se(drop_privileges(test_uid, test_gid, test_flags) < 0);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier assert_se(drop_privileges(0, 0, test_flags) < 0);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier fork_test(test_drop_privileges_keep_net_raw);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier fork_test(test_drop_privileges_dontkeep_net_raw);
6160e473fc2c52ab7c06f1d884a8901d2a5b6b73Ronny Chevalier assert_se(drop_privileges(test_uid, test_gid, test_flags | (1ULL << CAP_KILL)) >= 0);
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv));
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen assert_se(!capability_update_inherited_set(caps, set));
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv));
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv));
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen assert_se(prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_CHOWN, 0, 0) == 0);
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen assert_se(!capability_ambient_set_apply(set, true));
70d7aea5c7270764ee71d6828e76402001afed13Ismo Puustinen assert_se(!cap_get_flag(caps, CAP_CHOWN, CAP_INHERITABLE, &fv));