From 1e34d75027c0773e21b35688c27034d5af5e635c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 16 Sep 2024 20:25:59 +0200 Subject: Adding upstream version 256.5. Signed-off-by: Daniel Baumann --- src/basic/cgroup-util.c | 10 ++++++- src/basic/confidential-virt.c | 66 ++++++++++++++++++++++++++++++------------- src/basic/confidential-virt.h | 1 + src/basic/hexdecoct.c | 18 ++++++------ src/basic/log.c | 11 +++++--- src/basic/log.h | 16 ++++++++--- 6 files changed, 85 insertions(+), 37 deletions(-) (limited to 'src/basic') diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 553ee60..b0fe0ec 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -149,7 +149,9 @@ int cg_read_pidref(FILE *f, PidRef *ret, CGroupFlags flags) { if (pid == 0) return -EREMOTE; - if (FLAGS_SET(flags, CGROUP_NO_PIDFD)) { + /* We might read kernel thread pids from cgroup.procs for which we cannot create a pidfd so + * catch those and don't try to create a pidfd for them. */ + if (FLAGS_SET(flags, CGROUP_NO_PIDFD) || pid_is_kernel_thread(pid) > 0) { *ret = PIDREF_MAKE_FROM_PID(pid); return 1; } @@ -369,6 +371,12 @@ static int cg_kill_items( if (set_get(s, PID_TO_PTR(pidref.pid)) == PID_TO_PTR(pidref.pid)) continue; + /* Ignore kernel threads to mimick the behavior of cgroup.kill. */ + if (pidref_is_kernel_thread(&pidref) > 0) { + log_debug("Ignoring kernel thread with pid " PID_FMT " in cgroup '%s'", pidref.pid, path); + continue; + } + if (log_kill) ret_log_kill = log_kill(&pidref, sig, userdata); diff --git a/src/basic/confidential-virt.c b/src/basic/confidential-virt.c index b6521cf..c246636 100644 --- a/src/basic/confidential-virt.c +++ b/src/basic/confidential-virt.c @@ -11,6 +11,7 @@ #include "confidential-virt-fundamental.h" #include "confidential-virt.h" #include "fd-util.h" +#include "fileio.h" #include "missing_threads.h" #include "string-table.h" #include "utf8.h" @@ -76,7 +77,7 @@ static uint64_t msr(uint64_t index) { return ret; } -static bool detect_hyperv_sev(void) { +static bool detect_hyperv_cvm(uint32_t isoltype) { uint32_t eax, ebx, ecx, edx, feat; char sig[13] = {}; @@ -100,7 +101,7 @@ static bool detect_hyperv_sev(void) { ebx = ecx = edx = 0; cpuid(&eax, &ebx, &ecx, &edx); - if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == CPUID_HYPERV_ISOLATION_TYPE_SNP) + if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == isoltype) return true; } @@ -133,7 +134,7 @@ static ConfidentialVirtualization detect_sev(void) { if (!(eax & EAX_SEV)) { log_debug("No sev in CPUID, trying hyperv CPUID"); - if (detect_hyperv_sev()) + if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_SNP)) return CONFIDENTIAL_VIRTUALIZATION_SEV_SNP; log_debug("No hyperv CPUID"); @@ -171,6 +172,11 @@ static ConfidentialVirtualization detect_tdx(void) { if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) return CONFIDENTIAL_VIRTUALIZATION_TDX; + log_debug("No tdx in CPUID, trying hyperv CPUID"); + + if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_TDX)) + return CONFIDENTIAL_VIRTUALIZATION_TDX; + return CONFIDENTIAL_VIRTUALIZATION_NONE; } @@ -189,40 +195,62 @@ static bool detect_hypervisor(void) { return is_hv; } -ConfidentialVirtualization detect_confidential_virtualization(void) { - static thread_local ConfidentialVirtualization cached_found = _CONFIDENTIAL_VIRTUALIZATION_INVALID; +static ConfidentialVirtualization detect_confidential_virtualization_impl(void) { char sig[13] = {}; - ConfidentialVirtualization cv = CONFIDENTIAL_VIRTUALIZATION_NONE; - - if (cached_found >= 0) - return cached_found; /* Skip everything on bare metal */ if (detect_hypervisor()) { cpuid_leaf(0, sig, true); if (memcmp(sig, CPUID_SIG_AMD, sizeof(sig)) == 0) - cv = detect_sev(); + return detect_sev(); else if (memcmp(sig, CPUID_SIG_INTEL, sizeof(sig)) == 0) - cv = detect_tdx(); + return detect_tdx(); } - cached_found = cv; - return cv; + return CONFIDENTIAL_VIRTUALIZATION_NONE; } +#elif defined(__s390x__) +static ConfidentialVirtualization detect_confidential_virtualization_impl(void) { + _cleanup_free_ char *s = NULL; + size_t readsize; + int r; + + r = read_full_virtual_file("/sys/firmware/uv/prot_virt_guest", &s, &readsize); + if (r < 0) { + log_debug_errno(r, "Unable to read /sys/firmware/uv/prot_virt_guest: %m"); + return CONFIDENTIAL_VIRTUALIZATION_NONE; + } + + if (readsize >= 1 && s[0] == '1') + return CONFIDENTIAL_VIRTUALIZATION_PROTVIRT; + + return CONFIDENTIAL_VIRTUALIZATION_NONE; +} + #else /* ! x86_64 */ -ConfidentialVirtualization detect_confidential_virtualization(void) { +static ConfidentialVirtualization detect_confidential_virtualization_impl(void) { log_debug("No confidential virtualization detection on this architecture"); return CONFIDENTIAL_VIRTUALIZATION_NONE; } #endif /* ! x86_64 */ +ConfidentialVirtualization detect_confidential_virtualization(void) { + static thread_local ConfidentialVirtualization cached_found = _CONFIDENTIAL_VIRTUALIZATION_INVALID; + + if (cached_found == _CONFIDENTIAL_VIRTUALIZATION_INVALID) + cached_found = detect_confidential_virtualization_impl(); + + return cached_found; +} + static const char *const confidential_virtualization_table[_CONFIDENTIAL_VIRTUALIZATION_MAX] = { - [CONFIDENTIAL_VIRTUALIZATION_NONE] = "none", - [CONFIDENTIAL_VIRTUALIZATION_SEV] = "sev", - [CONFIDENTIAL_VIRTUALIZATION_SEV_ES] = "sev-es", - [CONFIDENTIAL_VIRTUALIZATION_SEV_SNP] = "sev-snp", - [CONFIDENTIAL_VIRTUALIZATION_TDX] = "tdx", + [CONFIDENTIAL_VIRTUALIZATION_NONE] = "none", + [CONFIDENTIAL_VIRTUALIZATION_SEV] = "sev", + [CONFIDENTIAL_VIRTUALIZATION_SEV_ES] = "sev-es", + [CONFIDENTIAL_VIRTUALIZATION_SEV_SNP] = "sev-snp", + [CONFIDENTIAL_VIRTUALIZATION_TDX] = "tdx", + [CONFIDENTIAL_VIRTUALIZATION_PROTVIRT] = "protvirt", }; DEFINE_STRING_TABLE_LOOKUP(confidential_virtualization, ConfidentialVirtualization); diff --git a/src/basic/confidential-virt.h b/src/basic/confidential-virt.h index c02f3b2..f92e3e8 100644 --- a/src/basic/confidential-virt.h +++ b/src/basic/confidential-virt.h @@ -13,6 +13,7 @@ typedef enum ConfidentialVirtualization { CONFIDENTIAL_VIRTUALIZATION_SEV_ES, CONFIDENTIAL_VIRTUALIZATION_SEV_SNP, CONFIDENTIAL_VIRTUALIZATION_TDX, + CONFIDENTIAL_VIRTUALIZATION_PROTVIRT, _CONFIDENTIAL_VIRTUALIZATION_MAX, _CONFIDENTIAL_VIRTUALIZATION_INVALID = -EINVAL, diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 4cb67d9..e02aa9e 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -36,7 +36,7 @@ int undecchar(char c) { } char hexchar(int x) { - static const char table[16] = "0123456789abcdef"; + static const char table[] = "0123456789abcdef"; return table[x & 15]; } @@ -168,8 +168,8 @@ int unhexmem_full( * useful when representing NSEC3 hashes, as one can then verify the * order of hashes directly from their representation. */ char base32hexchar(int x) { - static const char table[32] = "0123456789" - "ABCDEFGHIJKLMNOPQRSTUV"; + static const char table[] = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUV"; return table[x & 31]; } @@ -519,9 +519,9 @@ int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_l /* https://tools.ietf.org/html/rfc4648#section-4 */ char base64char(int x) { - static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; + static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; return table[x & 63]; } @@ -529,9 +529,9 @@ char base64char(int x) { * since we don't want "/" appear in interface names (since interfaces appear in sysfs as filenames). * See section #5 of RFC 4648. */ char urlsafe_base64char(int x) { - static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789-_"; + static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_"; return table[x & 63]; } diff --git a/src/basic/log.c b/src/basic/log.c index 13ad19a..2675d59 100644 --- a/src/basic/log.c +++ b/src/basic/log.c @@ -395,9 +395,10 @@ void log_forget_fds(void) { console_fd_is_tty = -1; } -void log_set_max_level(int level) { +int log_set_max_level(int level) { assert(level == LOG_NULL || LOG_PRI(level) == level); + int old = log_max_level; log_max_level = level; /* Also propagate max log level to libc's syslog(), just in case some other component loaded into our @@ -410,6 +411,8 @@ void log_set_max_level(int level) { /* Ensure that our own LOG_NULL define maps sanely to the log mask */ assert_cc(LOG_UPTO(LOG_NULL) == 0); + + return old; } void log_set_facility(int facility) { @@ -743,7 +746,7 @@ static int write_to_journal( if (LOG_PRI(level) > log_target_max_level[LOG_TARGET_JOURNAL]) return 0; - iovec_len = MIN(6 + _log_context_num_fields * 2, IOVEC_MAX); + iovec_len = MIN(6 + _log_context_num_fields * 3, IOVEC_MAX); iovec = newa(struct iovec, iovec_len); log_do_header(header, sizeof(header), level, error, file, line, func, object_field, object, extra_field, extra); @@ -1095,7 +1098,7 @@ int log_struct_internal( int r; bool fallback = false; - iovec_len = MIN(17 + _log_context_num_fields * 2, IOVEC_MAX); + iovec_len = MIN(17 + _log_context_num_fields * 3, IOVEC_MAX); iovec = newa(struct iovec, iovec_len); /* If the journal is available do structured logging. @@ -1192,7 +1195,7 @@ int log_struct_iovec_internal( struct iovec *iovec; size_t n = 0, iovec_len; - iovec_len = MIN(1 + n_input_iovec * 2 + _log_context_num_fields * 2, IOVEC_MAX); + iovec_len = MIN(1 + n_input_iovec * 2 + _log_context_num_fields * 3, IOVEC_MAX); iovec = newa(struct iovec, iovec_len); log_do_header(header, sizeof(header), level, error, file, line, func, NULL, NULL, NULL, NULL); diff --git a/src/basic/log.h b/src/basic/log.h index 726f035..4543556 100644 --- a/src/basic/log.h +++ b/src/basic/log.h @@ -35,9 +35,8 @@ typedef enum LogTarget{ * used as a regular log level. */ #define LOG_NULL (LOG_EMERG - 1) -/* Note to readers: << and >> have lower precedence (are evaluated earlier) than & and | */ -#define SYNTHETIC_ERRNO(num) (1 << 30 | (num)) -#define IS_SYNTHETIC_ERRNO(val) ((val) >> 30 & 1) +#define SYNTHETIC_ERRNO(num) (abs(num) | (1 << 30)) +#define IS_SYNTHETIC_ERRNO(val) (((val) >> 30) == 1) #define ERRNO_VALUE(val) (abs(val) & ~(1 << 30)) /* The callback function to be invoked when syntax warnings are seen @@ -57,7 +56,7 @@ int log_set_target_from_string(const char *e); LogTarget log_get_target(void) _pure_; void log_settle_target(void); -void log_set_max_level(int level); +int log_set_max_level(int level); int log_set_max_level_from_string(const char *e); int log_get_max_level(void) _pure_; int log_max_levels_to_string(int level, char **ret); @@ -492,6 +491,15 @@ size_t log_context_num_contexts(void); /* Returns the number of fields in all attached log contexts. */ size_t log_context_num_fields(void); +static inline void _reset_log_level(int *saved_log_level) { + assert(saved_log_level); + + log_set_max_level(*saved_log_level); +} + +#define LOG_CONTEXT_SET_LOG_LEVEL(level) \ + _cleanup_(_reset_log_level) _unused_ int _saved_log_level_ = log_set_max_level(level); + #define LOG_CONTEXT_PUSH(...) \ LOG_CONTEXT_PUSH_STRV(STRV_MAKE(__VA_ARGS__)) -- cgit v1.2.3