diff --git a/debian/patches/apertis/0101-basic-cap-list-parse-print-numerical-capabilities.patch b/debian/patches/apertis/0101-basic-cap-list-parse-print-numerical-capabilities.patch new file mode 100644 index 0000000000000000000000000000000000000000..a9d505377a639f56757f399c3fc7b1b0bf6c5118 --- /dev/null +++ b/debian/patches/apertis/0101-basic-cap-list-parse-print-numerical-capabilities.patch @@ -0,0 +1,89 @@ +From 3b91f512b33f9b7a272cc1ff6fe3ad9e42269437 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Thu, 9 Jul 2020 23:15:47 +0200 +Subject: [PATCH 1/3] basic/cap-list: parse/print numerical capabilities + +We would refuse to print capabilities which were didn't have a name +for. The kernel adds new capabilities from time to time, most recently +cap_bpf. 'systmectl show -p CapabilityBoundingSet ...' would fail with +"Failed to parse bus message: Invalid argument" because +capability_set_to_string_alloc() would fail with -EINVAL. So let's +print such capabilities in hexadecimal: + +CapabilityBoundingSet=cap_chown cap_dac_override cap_dac_read_search + cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap + cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin + cap_net_raw cap_ipc_lock cap_ipc_owner 0x10 0x11 0x12 0x13 0x14 0x15 0x16 + 0x17 0x18 0x19 0x1a ... + +For symmetry, also allow capabilities that we don't know to be specified. + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1853736. +--- + src/basic/cap-list.c | 10 +++++++--- + src/test/test-cap-list.c | 4 +++- + 2 files changed, 10 insertions(+), 4 deletions(-) + +diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c +index 29a17d9..b72b037 100644 +--- a/src/basic/cap-list.c ++++ b/src/basic/cap-list.c +@@ -10,6 +10,7 @@ + #include "macro.h" + #include "missing.h" + #include "parse-util.h" ++#include "stdio-util.h" + #include "util.h" + + static const struct capability_name* lookup_capability(register const char *str, register GPERF_LEN_TYPE len); +@@ -37,7 +38,7 @@ int capability_from_name(const char *name) { + /* Try to parse numeric capability */ + r = safe_atoi(name, &i); + if (r >= 0) { +- if (i >= 0 && (size_t) i < ELEMENTSOF(capability_names)) ++ if (i >= 0 && i < 64) + return i; + else + return -EINVAL; +@@ -65,11 +66,14 @@ int capability_set_to_string_alloc(uint64_t set, char **s) { + for (i = 0; i < cap_last_cap(); i++) + if (set & (UINT64_C(1) << i)) { + const char *p; ++ char buf[2 + 16 + 1]; + size_t add; + + p = capability_to_name(i); +- if (!p) +- return -EINVAL; ++ if (!p) { ++ xsprintf(buf, "0x%lx", i); ++ p = buf; ++ } + + add = strlen(p); + +diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c +index de5fa72..84bbb7b 100644 +--- a/src/test/test-cap-list.c ++++ b/src/test/test-cap-list.c +@@ -30,6 +30,8 @@ static void test_cap_list(void) { + assert_se(capability_from_name("cAp_aUdIt_rEAd") == CAP_AUDIT_READ); + assert_se(capability_from_name("0") == 0); + assert_se(capability_from_name("15") == 15); ++ assert_se(capability_from_name("63") == 63); ++ assert_se(capability_from_name("64") == -EINVAL); + assert_se(capability_from_name("-1") == -EINVAL); + + for (i = 0; i < capability_list_length(); i++) { +@@ -64,7 +66,7 @@ static void test_capability_set_one(uint64_t c, const char *t) { + + free(t1); + assert_se(t1 = strjoin("'cap_chown cap_dac_override' \"cap_setgid cap_setuid\"", t, +- " hogehoge foobar 12345 3.14 -3 ", t)); ++ " hogehoge foobar 18446744073709551616 3.14 -3 ", t)); + assert_se(capability_set_from_string(t1, &c1) == 0); + assert_se(c1 == c_masked); + } +-- +2.20.1 + diff --git a/debian/patches/apertis/0102-basic-capability-util-let-cap_last_cap-return-unsign.patch b/debian/patches/apertis/0102-basic-capability-util-let-cap_last_cap-return-unsign.patch new file mode 100644 index 0000000000000000000000000000000000000000..3537388ddc36357d2f7d37bd7863908204b05a89 --- /dev/null +++ b/debian/patches/apertis/0102-basic-capability-util-let-cap_last_cap-return-unsign.patch @@ -0,0 +1,191 @@ +From a6ebc26df4bd0915a6488f2766f329f9590f17eb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Fri, 10 Jul 2020 16:53:51 +0200 +Subject: [PATCH 2/3] basic/capability-util: let cap_last_cap() return unsigned + integer + +We never return anything higher than 63, so using "long unsigned" +as the type only confused the reader. (We can still use "long unsigned" +and safe_atolu() to parse the kernel file.) +--- + src/basic/cap-list.c | 5 ++--- + src/basic/capability-util.c | 26 ++++++++++---------------- + src/basic/capability-util.h | 2 +- + src/libsystemd/sd-bus/bus-creds.c | 5 ++--- + 4 files changed, 15 insertions(+), 23 deletions(-) + +diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c +index b72b037..49b4d31 100644 +--- a/src/basic/cap-list.c ++++ b/src/basic/cap-list.c +@@ -58,12 +58,11 @@ int capability_list_length(void) { + + int capability_set_to_string_alloc(uint64_t set, char **s) { + _cleanup_free_ char *str = NULL; +- unsigned long i; + size_t allocated = 0, n = 0; + + assert(s); + +- for (i = 0; i < cap_last_cap(); i++) ++ for (unsigned i = 0; i < cap_last_cap(); i++) + if (set & (UINT64_C(1) << i)) { + const char *p; + char buf[2 + 16 + 1]; +@@ -71,7 +70,7 @@ int capability_set_to_string_alloc(uint64_t set, char **s) { + + p = capability_to_name(i); + if (!p) { +- xsprintf(buf, "0x%lx", i); ++ xsprintf(buf, "0x%x", i); + p = buf; + } + +diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c +index b944ee6..afabd02 100644 +--- a/src/basic/capability-util.c ++++ b/src/basic/capability-util.c +@@ -32,8 +32,8 @@ int have_effective_cap(int value) { + return fv == CAP_SET; + } + +-unsigned long cap_last_cap(void) { +- static thread_local unsigned long saved; ++unsigned cap_last_cap(void) { ++ static thread_local unsigned saved; + static thread_local bool valid = false; + _cleanup_free_ char *content = NULL; + unsigned long p = 0; +@@ -60,7 +60,7 @@ unsigned long cap_last_cap(void) { + + /* Hmm, look downwards, until we find one that + * works */ +- for (p--; p > 0; p --) ++ for (p--; p > 0; p--) + if (prctl(PR_CAPBSET_READ, p) >= 0) + break; + +@@ -80,12 +80,10 @@ unsigned long cap_last_cap(void) { + } + + int capability_update_inherited_set(cap_t caps, uint64_t set) { +- unsigned long i; +- + /* Add capabilities in the set to the inherited caps. Do not apply + * them yet. */ + +- for (i = 0; i < cap_last_cap(); i++) { ++ for (unsigned i = 0; i < cap_last_cap(); i++) { + + if (set & (UINT64_C(1) << i)) { + cap_value_t v; +@@ -102,7 +100,6 @@ int capability_update_inherited_set(cap_t caps, uint64_t set) { + } + + int capability_ambient_set_apply(uint64_t set, bool also_inherit) { +- unsigned long i; + _cleanup_cap_free_ cap_t caps = NULL; + + /* Add the capabilities to the ambient set. */ +@@ -121,7 +118,7 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) { + return -errno; + } + +- for (i = 0; i < cap_last_cap(); i++) { ++ for (unsigned i = 0; i < cap_last_cap(); i++) { + + if (set & (UINT64_C(1) << i)) { + +@@ -137,7 +134,6 @@ int capability_ambient_set_apply(uint64_t set, bool also_inherit) { + int capability_bounding_set_drop(uint64_t keep, bool right_now) { + _cleanup_cap_free_ cap_t before_cap = NULL, after_cap = NULL; + cap_flag_value_t fv; +- unsigned long i; + int r; + + /* If we are run as PID 1 we will lack CAP_SETPCAP by default +@@ -174,7 +170,7 @@ int capability_bounding_set_drop(uint64_t keep, bool right_now) { + if (!after_cap) + return -errno; + +- for (i = 0; i <= cap_last_cap(); i++) { ++ for (unsigned i = 0; i <= cap_last_cap(); i++) { + cap_value_t v; + + if ((keep & (UINT64_C(1) << i))) +@@ -366,16 +362,15 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { + int r; + + if (q->ambient != (uint64_t) -1) { +- unsigned long i; + bool changed = false; + + c = cap_get_proc(); + if (!c) + return -errno; + +- /* In order to raise the ambient caps set we first need to raise the matching inheritable + permitted +- * cap */ +- for (i = 0; i <= cap_last_cap(); i++) { ++ /* In order to raise the ambient caps set we first need to raise the matching ++ * inheritable + permitted cap */ ++ for (unsigned i = 0; i <= cap_last_cap(); i++) { + uint64_t m = UINT64_C(1) << i; + cap_value_t cv = (cap_value_t) i; + cap_flag_value_t old_value_inheritable, old_value_permitted; +@@ -411,7 +406,6 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { + + if (q->inheritable != (uint64_t) -1 || q->permitted != (uint64_t) -1 || q->effective != (uint64_t) -1) { + bool changed = false; +- unsigned long i; + + if (!c) { + c = cap_get_proc(); +@@ -419,7 +413,7 @@ int capability_quintet_enforce(const CapabilityQuintet *q) { + return -errno; + } + +- for (i = 0; i <= cap_last_cap(); i++) { ++ for (unsigned i = 0; i <= cap_last_cap(); i++) { + uint64_t m = UINT64_C(1) << i; + cap_value_t cv = (cap_value_t) i; + +diff --git a/src/basic/capability-util.h b/src/basic/capability-util.h +index 02c7d5c..b288389 100644 +--- a/src/basic/capability-util.h ++++ b/src/basic/capability-util.h +@@ -12,7 +12,7 @@ + + #define CAP_ALL (uint64_t) -1 + +-unsigned long cap_last_cap(void); ++unsigned cap_last_cap(void); + int have_effective_cap(int value); + int capability_bounding_set_drop(uint64_t keep, bool right_now); + int capability_bounding_set_drop_usermode(uint64_t keep); +diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c +index 81d97ff..4de7e6d 100644 +--- a/src/libsystemd/sd-bus/bus-creds.c ++++ b/src/libsystemd/sd-bus/bus-creds.c +@@ -650,16 +650,15 @@ _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) { + } + + static int has_cap(sd_bus_creds *c, size_t offset, int capability) { +- unsigned long lc; + size_t sz; + + assert(c); + assert(capability >= 0); + assert(c->capability); + +- lc = cap_last_cap(); ++ unsigned lc = cap_last_cap(); + +- if ((unsigned long) capability > lc) ++ if ((unsigned) capability > lc) + return 0; + + sz = DIV_ROUND_UP(lc, 32LU); +-- +2.20.1 + diff --git a/debian/patches/apertis/0103-basic-cap-list-reduce-scope-of-variables.patch b/debian/patches/apertis/0103-basic-cap-list-reduce-scope-of-variables.patch new file mode 100644 index 0000000000000000000000000000000000000000..c681449df67874804445d3bc7dad84c3a86cd298 --- /dev/null +++ b/debian/patches/apertis/0103-basic-cap-list-reduce-scope-of-variables.patch @@ -0,0 +1,65 @@ +From e13370fbe379d39668871f8a3471a6640653721f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Thu, 9 Jul 2020 23:23:07 +0200 +Subject: [PATCH 3/3] basic/cap-list: reduce scope of variables + +--- + src/basic/cap-list.c | 4 +--- + src/test/test-cap-list.c | 6 ++---- + 2 files changed, 3 insertions(+), 7 deletions(-) + +diff --git a/src/basic/cap-list.c b/src/basic/cap-list.c +index 49b4d31..2fa016b 100644 +--- a/src/basic/cap-list.c ++++ b/src/basic/cap-list.c +@@ -19,7 +19,6 @@ static const struct capability_name* lookup_capability(register const char *str, + #include "cap-to-name.h" + + const char *capability_to_name(int id) { +- + if (id < 0) + return NULL; + +@@ -95,11 +94,10 @@ int capability_set_to_string_alloc(uint64_t set, char **s) { + + int capability_set_from_string(const char *s, uint64_t *set) { + uint64_t val = 0; +- const char *p; + + assert(set); + +- for (p = s;;) { ++ for (const char *p = s;;) { + _cleanup_free_ char *word = NULL; + int r; + +diff --git a/src/test/test-cap-list.c b/src/test/test-cap-list.c +index 84bbb7b..f6f0930 100644 +--- a/src/test/test-cap-list.c ++++ b/src/test/test-cap-list.c +@@ -11,12 +11,10 @@ + + /* verify the capability parser */ + static void test_cap_list(void) { +- int i; +- + assert_se(!capability_to_name(-1)); + assert_se(!capability_to_name(capability_list_length())); + +- for (i = 0; i < capability_list_length(); i++) { ++ for (int i = 0; i < capability_list_length(); i++) { + const char *n; + + assert_se(n = capability_to_name(i)); +@@ -34,7 +32,7 @@ static void test_cap_list(void) { + assert_se(capability_from_name("64") == -EINVAL); + assert_se(capability_from_name("-1") == -EINVAL); + +- for (i = 0; i < capability_list_length(); i++) { ++ for (int i = 0; i < capability_list_length(); i++) { + _cleanup_cap_free_charp_ char *a = NULL; + const char *b; + unsigned u; +-- +2.20.1 + diff --git a/debian/patches/series b/debian/patches/series index cc677bc417c49a2bef9ce96c6059294876e40e18..a30715a741abcdd698d8c1929ea303fe7ac8c0fb 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -81,3 +81,6 @@ apertis/journald-add-API-to-move-logging-from-var-to-run-again.patch apertis/journalctl-add-new-relinquish-and-smart-relinquish-option.patch apertis/units-automatically-revert-to-run-logging-on-shutdown-if-.patch sd-boot-fix-menu-ordering-with-boot-counting.patch +apertis/0101-basic-cap-list-parse-print-numerical-capabilities.patch +apertis/0102-basic-capability-util-let-cap_last_cap-return-unsign.patch +apertis/0103-basic-cap-list-reduce-scope-of-variables.patch