From 07d46372fe19e58614906800690c8e0e4a75dc58 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 7 Aug 2017 23:40:25 +0900 Subject: [PATCH] securebits-util: add secure_bits_{from_string,to_string_alloc}() --- src/basic/meson.build | 2 ++ src/basic/securebits-util.c | 84 +++++++++++++++++++++++++++++++++++++++++++++ src/basic/securebits-util.h | 28 +++++++++++++++ src/core/execute.c | 17 +++++---- src/core/load-fragment.c | 42 ++++++----------------- 5 files changed, 133 insertions(+), 40 deletions(-) create mode 100644 src/basic/securebits-util.c create mode 100644 src/basic/securebits-util.h diff --git a/src/basic/meson.build b/src/basic/meson.build index 065f0ac..67cc272 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -139,6 +139,8 @@ basic_sources_plain = files(''' rm-rf.c rm-rf.h securebits.h + securebits-util.c + securebits-util.h selinux-util.c selinux-util.h set.h diff --git a/src/basic/securebits-util.c b/src/basic/securebits-util.c new file mode 100644 index 0000000..011ec36 --- /dev/null +++ b/src/basic/securebits-util.c @@ -0,0 +1,84 @@ +/*** + This file is part of systemd. + + Copyright 2017 Yu Watanabe + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include + +#include "alloc-util.h" +#include "extract-word.h" +#include "securebits.h" +#include "securebits-util.h" +#include "string-util.h" + +int secure_bits_to_string_alloc(int i, char **s) { + _cleanup_free_ char *str = NULL; + size_t len; + int r; + + assert(s); + + r = asprintf(&str, "%s%s%s%s%s%s", + (i & (1 << SECURE_KEEP_CAPS)) ? "keep-caps " : "", + (i & (1 << SECURE_KEEP_CAPS_LOCKED)) ? "keep-caps-locked " : "", + (i & (1 << SECURE_NO_SETUID_FIXUP)) ? "no-setuid-fixup " : "", + (i & (1 << SECURE_NO_SETUID_FIXUP_LOCKED)) ? "no-setuid-fixup-locked " : "", + (i & (1 << SECURE_NOROOT)) ? "noroot " : "", + (i & (1 << SECURE_NOROOT_LOCKED)) ? "noroot-locked " : ""); + if (r < 0) + return -ENOMEM; + + len = strlen(str); + if (len != 0) + str[len - 1] = '\0'; + + *s = str; + str = NULL; + + return 0; +} + +int secure_bits_from_string(const char *s) { + int secure_bits = 0; + const char *p; + int r; + + for (p = s;;) { + _cleanup_free_ char *word = NULL; + + r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); + if (r == -ENOMEM) + return r; + if (r <= 0) + break; + + if (streq(word, "keep-caps")) + secure_bits |= 1 << SECURE_KEEP_CAPS; + else if (streq(word, "keep-caps-locked")) + secure_bits |= 1 << SECURE_KEEP_CAPS_LOCKED; + else if (streq(word, "no-setuid-fixup")) + secure_bits |= 1 << SECURE_NO_SETUID_FIXUP; + else if (streq(word, "no-setuid-fixup-locked")) + secure_bits |= 1 << SECURE_NO_SETUID_FIXUP_LOCKED; + else if (streq(word, "noroot")) + secure_bits |= 1 << SECURE_NOROOT; + else if (streq(word, "noroot-locked")) + secure_bits |= 1 << SECURE_NOROOT_LOCKED; + } + + return secure_bits; +} diff --git a/src/basic/securebits-util.h b/src/basic/securebits-util.h new file mode 100644 index 0000000..b4d970c --- /dev/null +++ b/src/basic/securebits-util.h @@ -0,0 +1,28 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2017 Yu Watanabe + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see . +***/ + +#include "securebits.h" + +int secure_bits_to_string_alloc(int i, char **s); +int secure_bits_from_string(const char *s); +static inline bool secure_bits_is_valid(int i) { + return ((SECURE_ALL_BITS | SECURE_ALL_LOCKS) & i) == i; +} diff --git a/src/core/execute.c b/src/core/execute.c index ca17942..55f9aab 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -90,6 +90,7 @@ #include "seccomp-util.h" #endif #include "securebits.h" +#include "securebits-util.h" #include "selinux-util.h" #include "signal-util.h" #include "smack-util.h" @@ -3599,15 +3600,13 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { fprintf(f, "%sSyslogLevel: %s\n", prefix, lvl_str); } - if (c->secure_bits) - fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n", - prefix, - (c->secure_bits & 1<secure_bits & 1<secure_bits & 1<secure_bits & 1<secure_bits & 1<secure_bits & 1<secure_bits) { + _cleanup_free_ char *str = NULL; + + r = secure_bits_to_string_alloc(c->secure_bits, &str); + if (r >= 0) + fprintf(f, "%sSecure Bits: %s\n", prefix, str); + } if (c->capability_bounding_set != CAP_ALL) { _cleanup_free_ char *str = NULL; diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 63144c4..d9da1a4 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -58,6 +58,7 @@ #include "seccomp-util.h" #endif #include "securebits.h" +#include "securebits-util.h" #include "signal-util.h" #include "stat-util.h" #include "string-util.h" @@ -1094,7 +1095,6 @@ int config_parse_exec_secure_bits(const char *unit, void *userdata) { ExecContext *c = data; - const char *p; int r; assert(filename); @@ -1108,38 +1108,18 @@ int config_parse_exec_secure_bits(const char *unit, return 0; } - for (p = rvalue;;) { - _cleanup_free_ char *word = NULL; + r = secure_bits_from_string(rvalue); + if (r == -ENOMEM) + return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Invalid syntax, ignoring: %s", rvalue); + return 0; + } - r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES); - if (r == 0) - return 0; - if (r == -ENOMEM) - return log_oom(); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Invalid syntax, ignoring: %s", rvalue); - return 0; - } + c->secure_bits = r; - if (streq(word, "keep-caps")) - c->secure_bits |= 1<secure_bits |= 1<secure_bits |= 1<secure_bits |= 1<secure_bits |= 1<secure_bits |= 1<