summaryrefslogtreecommitdiffstats
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/cgroup-util.c10
-rw-r--r--src/basic/confidential-virt.c66
-rw-r--r--src/basic/confidential-virt.h1
-rw-r--r--src/basic/hexdecoct.c18
-rw-r--r--src/basic/log.c11
-rw-r--r--src/basic/log.h16
6 files changed, 85 insertions, 37 deletions
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__))