summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
-rw-r--r--src/boot/efi/boot.c2
-rw-r--r--src/boot/efi/efi-string.c2
-rw-r--r--src/boot/efi/linux.c6
-rw-r--r--src/boot/efi/linux.h3
-rw-r--r--src/boot/efi/linux_x86.c21
-rw-r--r--src/boot/efi/pe.c7
-rw-r--r--src/boot/efi/pe.h2
-rw-r--r--src/boot/efi/vmm.c9
-rw-r--r--src/core/exec-credential.c21
-rw-r--r--src/core/exec-invoke.c16
-rw-r--r--src/core/execute-serialize.c56
-rw-r--r--src/core/execute.c1
-rw-r--r--src/core/load-dropin.c2
-rw-r--r--src/core/load-dropin.h4
-rw-r--r--src/core/socket.c4
-rw-r--r--src/core/unit.c2
-rw-r--r--src/firstboot/firstboot.c68
-rw-r--r--src/fundamental/confidential-virt-fundamental.h1
-rw-r--r--src/import/import-raw.c5
-rw-r--r--src/import/import-tar.c5
-rw-r--r--src/journal/journald-server.c7
-rw-r--r--src/journal/journald.c3
-rw-r--r--src/journal/journald.conf2
-rwxr-xr-xsrc/kernel-install/50-depmod.install1
-rwxr-xr-xsrc/kernel-install/90-loaderentry.install.in20
-rw-r--r--src/libsystemd/sd-event/sd-event.c3
-rw-r--r--src/login/logind-dbus.c39
-rw-r--r--src/network/networkd-link.c41
-rw-r--r--src/network/networkd-ndisc.c6
-rw-r--r--src/network/networkd-routing-policy-rule.c7
-rw-r--r--src/nspawn/nspawn-network.c50
-rw-r--r--src/nspawn/nspawn-network.h1
-rw-r--r--src/nspawn/nspawn.c4
-rw-r--r--src/pcrlock/pcrlock.c16
-rw-r--r--src/resolve/resolved-bus.c5
-rw-r--r--src/resolve/resolved-dns-stream.c6
-rw-r--r--src/resolve/resolved-dns-transaction.c4
-rw-r--r--src/resolve/resolved-varlink.c5
-rw-r--r--src/shared/base-filesystem.c24
-rw-r--r--src/shared/edit-util.c2
-rw-r--r--src/shared/resize-fs.h6
-rw-r--r--src/shared/tests.h37
-rw-r--r--src/systemctl/systemctl-logind.c8
-rw-r--r--src/systemctl/systemctl.c4
-rw-r--r--src/sysusers/sysusers.c8
-rw-r--r--src/test/test-conf-parser.c8
-rw-r--r--src/test/test-fs-util.c76
-rw-r--r--src/test/test-id128.c332
-rw-r--r--src/test/test-log.c14
-rw-r--r--src/test/test-macro.c15
-rw-r--r--src/ukify/test/pytest.ini2
57 files changed, 692 insertions, 423 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__))
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index e1f0817..93e1236 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -2405,7 +2405,7 @@ static EFI_STATUS image_start(
if (err == EFI_UNSUPPORTED && entry->type == LOADER_LINUX) {
uint32_t compat_address;
- err = pe_kernel_info(loaded_image->ImageBase, &compat_address);
+ err = pe_kernel_info(loaded_image->ImageBase, &compat_address, /* ret_size_in_memory= */ NULL);
if (err != EFI_SUCCESS) {
if (err != EFI_UNSUPPORTED)
return log_error_status(err, "Error finding kernel compat entry address: %m");
diff --git a/src/boot/efi/efi-string.c b/src/boot/efi/efi-string.c
index 3bdb802..db00890 100644
--- a/src/boot/efi/efi-string.c
+++ b/src/boot/efi/efi-string.c
@@ -481,7 +481,7 @@ char *line_get_key_value(char *s, const char *sep, size_t *pos, char **ret_key,
}
char16_t *hexdump(const void *data, size_t size) {
- static const char hex[16] = "0123456789abcdef";
+ static const char hex[] = "0123456789abcdef";
const uint8_t *d = data;
assert(data || size == 0);
diff --git a/src/boot/efi/linux.c b/src/boot/efi/linux.c
index 65bc176..c8e5951 100644
--- a/src/boot/efi/linux.c
+++ b/src/boot/efi/linux.c
@@ -98,6 +98,7 @@ EFI_STATUS linux_exec(
const void *initrd_buffer,
size_t initrd_length) {
+ size_t kernel_size_in_memory = 0;
uint32_t compat_address;
EFI_STATUS err;
@@ -105,7 +106,7 @@ EFI_STATUS linux_exec(
assert(linux_buffer && linux_length > 0);
assert(initrd_buffer || initrd_length == 0);
- err = pe_kernel_info(linux_buffer, &compat_address);
+ err = pe_kernel_info(linux_buffer, &compat_address, &kernel_size_in_memory);
#if defined(__i386__) || defined(__x86_64__)
if (err == EFI_UNSUPPORTED)
/* Kernel is too old to support LINUX_INITRD_MEDIA_GUID, try the deprecated EFI handover
@@ -116,7 +117,8 @@ EFI_STATUS linux_exec(
linux_buffer,
linux_length,
initrd_buffer,
- initrd_length);
+ initrd_length,
+ kernel_size_in_memory);
#endif
if (err != EFI_SUCCESS)
return log_error_status(err, "Bad kernel image: %m");
diff --git a/src/boot/efi/linux.h b/src/boot/efi/linux.h
index 46b5f4f..0d74c6a 100644
--- a/src/boot/efi/linux.h
+++ b/src/boot/efi/linux.h
@@ -16,4 +16,5 @@ EFI_STATUS linux_exec_efi_handover(
const void *linux_buffer,
size_t linux_length,
const void *initrd_buffer,
- size_t initrd_length);
+ size_t initrd_length,
+ size_t kernel_size_in_memory);
diff --git a/src/boot/efi/linux_x86.c b/src/boot/efi/linux_x86.c
index 757902d..58b1b3c 100644
--- a/src/boot/efi/linux_x86.c
+++ b/src/boot/efi/linux_x86.c
@@ -7,12 +7,13 @@
* this x86 specific linux_exec function passes the initrd by setting the
* corresponding fields in the setup_header struct.
*
- * see https://docs.kernel.org/x86/boot.html
+ * see https://docs.kernel.org/arch/x86/boot.html
*/
#include "initrd.h"
#include "linux.h"
#include "macro-fundamental.h"
+#include "memory-util-fundamental.h"
#include "util.h"
#define KERNEL_SECTOR_SIZE 512u
@@ -126,7 +127,8 @@ EFI_STATUS linux_exec_efi_handover(
const void *linux_buffer,
size_t linux_length,
const void *initrd_buffer,
- size_t initrd_length) {
+ size_t initrd_length,
+ size_t kernel_size_in_memory) {
assert(parent);
assert(linux_buffer);
@@ -153,13 +155,22 @@ EFI_STATUS linux_exec_efi_handover(
FLAGS_SET(image_params->hdr.xloadflags, XLF_CAN_BE_LOADED_ABOVE_4G);
/* There is no way to pass the high bits of code32_start. Newer kernels seems to handle this
- * just fine, but older kernels will fail even if they otherwise have above 4G boot support. */
+ * just fine, but older kernels will fail even if they otherwise have above 4G boot support.
+ * A PE image's memory footprint can be larger than its file size, due to unallocated virtual
+ * memory sections. While normally all PE headers should be taken into account, this case only
+ * involves x86 Linux bzImage kernel images, for which unallocated areas are only part of the last
+ * header, so parsing SizeOfImage and zeroeing the buffer past the image size is enough. */
_cleanup_pages_ Pages linux_relocated = {};
- if (POINTER_TO_PHYSICAL_ADDRESS(linux_buffer) + linux_length > UINT32_MAX) {
+ if (POINTER_TO_PHYSICAL_ADDRESS(linux_buffer) + linux_length > UINT32_MAX || kernel_size_in_memory > linux_length) {
linux_relocated = xmalloc_pages(
- AllocateMaxAddress, EfiLoaderCode, EFI_SIZE_TO_PAGES(linux_length), UINT32_MAX);
+ AllocateMaxAddress,
+ EfiLoaderCode,
+ EFI_SIZE_TO_PAGES(kernel_size_in_memory > linux_length ? kernel_size_in_memory : linux_length),
+ UINT32_MAX);
linux_buffer = memcpy(
PHYSICAL_ADDRESS_TO_POINTER(linux_relocated.addr), linux_buffer, linux_length);
+ if (kernel_size_in_memory > linux_length)
+ memzero((uint8_t *) linux_buffer + linux_length, kernel_size_in_memory - linux_length);
}
_cleanup_pages_ Pages initrd_relocated = {};
diff --git a/src/boot/efi/pe.c b/src/boot/efi/pe.c
index 829266b..fdca0c9 100644
--- a/src/boot/efi/pe.c
+++ b/src/boot/efi/pe.c
@@ -209,7 +209,7 @@ static uint32_t get_compatibility_entry_address(const DosFileHeader *dos, const
return 0;
}
-EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address) {
+EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address, size_t *ret_size_in_memory) {
assert(base);
assert(ret_compat_address);
@@ -221,6 +221,11 @@ EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address) {
if (!verify_pe(pe, /* allow_compatibility= */ true))
return EFI_LOAD_ERROR;
+ /* When allocating we need to also consider the virtual/uninitialized data sections, so parse it out
+ * of the SizeOfImage field in the PE header and return it */
+ if (ret_size_in_memory)
+ *ret_size_in_memory = pe->OptionalHeader.SizeOfImage;
+
/* Support for LINUX_INITRD_MEDIA_GUID was added in kernel stub 1.0. */
if (pe->OptionalHeader.MajorImageVersion < 1)
return EFI_UNSUPPORTED;
diff --git a/src/boot/efi/pe.h b/src/boot/efi/pe.h
index 7e2258f..860cfe5 100644
--- a/src/boot/efi/pe.h
+++ b/src/boot/efi/pe.h
@@ -16,4 +16,4 @@ EFI_STATUS pe_file_locate_sections(
size_t *offsets,
size_t *sizes);
-EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address);
+EFI_STATUS pe_kernel_info(const void *base, uint32_t *ret_compat_address, size_t *ret_size_in_memory);
diff --git a/src/boot/efi/vmm.c b/src/boot/efi/vmm.c
index bfc7acc..ed654f6 100644
--- a/src/boot/efi/vmm.c
+++ b/src/boot/efi/vmm.c
@@ -346,7 +346,7 @@ static uint64_t msr(uint32_t index) {
return val;
}
-static bool detect_hyperv_sev(void) {
+static bool detect_hyperv_cvm(uint32_t isoltype) {
uint32_t eax, ebx, ecx, edx, feat;
char sig[13] = {};
@@ -363,7 +363,7 @@ static bool detect_hyperv_sev(void) {
if (ebx & CPUID_HYPERV_ISOLATION && !(ebx & CPUID_HYPERV_CPU_MANAGEMENT)) {
__cpuid(CPUID_HYPERV_ISOLATION_CONFIG, 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;
}
@@ -388,7 +388,7 @@ static bool detect_sev(void) {
* specific CPUID checks.
*/
if (!(eax & EAX_SEV))
- return detect_hyperv_sev();
+ return detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_SNP);
msrval = msr(MSR_AMD64_SEV);
@@ -412,6 +412,9 @@ static bool detect_tdx(void) {
if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0)
return true;
+ if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_TDX))
+ return true;
+
return false;
}
#endif /* ! __i386__ && ! __x86_64__ */
diff --git a/src/core/exec-credential.c b/src/core/exec-credential.c
index f4cff57..6157ac4 100644
--- a/src/core/exec-credential.c
+++ b/src/core/exec-credential.c
@@ -353,6 +353,17 @@ static int load_credential_glob(
_cleanup_(erase_and_freep) char *data = NULL;
size_t size;
+ r = path_extract_filename(*p, &fn);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to extract filename from '%s': %m", *p);
+
+ if (faccessat(write_dfd, fn, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) {
+ log_debug("Skipping credential with duplicated ID %s at %s", fn, *p);
+ continue;
+ }
+ if (errno != ENOENT)
+ return log_debug_errno(errno, "Failed to test if credential %s exists: %m", fn);
+
/* path is absolute, hence pass AT_FDCWD as nop dir fd here */
r = read_full_file_full(
AT_FDCWD,
@@ -365,10 +376,6 @@ static int load_credential_glob(
if (r < 0)
return log_debug_errno(r, "Failed to read credential '%s': %m", *p);
- r = path_extract_filename(*p, &fn);
- if (r < 0)
- return log_debug_errno(r, "Failed to extract filename from '%s': %m", *p);
-
r = maybe_decrypt_and_write_credential(
write_dfd,
fn,
@@ -378,8 +385,6 @@ static int load_credential_glob(
ownership_ok,
data, size,
left);
- if (r == -EEXIST)
- continue;
if (r < 0)
return r;
}
@@ -717,8 +722,10 @@ static int acquire_credentials(
* EEXIST if the credential already exists. That's because the TPM2-based decryption is kinda
* slow and involved, hence it's nice to be able to skip that if the credential already
* exists anyway. */
- if (faccessat(dfd, sc->id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
+ if (faccessat(dfd, sc->id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) {
+ log_debug("Skipping credential with duplicated ID %s", sc->id);
continue;
+ }
if (errno != ENOENT)
return log_debug_errno(errno, "Failed to test if credential %s exists: %m", sc->id);
diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c
index 09f98d3..5850a59 100644
--- a/src/core/exec-invoke.c
+++ b/src/core/exec-invoke.c
@@ -4402,14 +4402,6 @@ int exec_invoke(
}
}
- if (context->nice_set) {
- r = setpriority_closest(context->nice);
- if (r < 0) {
- *exit_status = EXIT_NICE;
- return log_exec_error_errno(context, params, r, "Failed to set up process scheduling priority (nice level): %m");
- }
- }
-
if (context->cpu_sched_set) {
struct sched_attr attr = {
.size = sizeof(attr),
@@ -4425,6 +4417,14 @@ int exec_invoke(
}
}
+ if (context->nice_set) {
+ r = setpriority_closest(context->nice);
+ if (r < 0) {
+ *exit_status = EXIT_NICE;
+ return log_exec_error_errno(context, params, r, "Failed to set up process scheduling priority (nice level): %m");
+ }
+ }
+
if (context->cpu_affinity_from_numa || context->cpu_set.set) {
_cleanup_(cpu_set_reset) CPUSet converted_cpu_set = {};
const CPUSet *cpu_set;
diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c
index ecd1e70..41b31e9 100644
--- a/src/core/execute-serialize.c
+++ b/src/core/execute-serialize.c
@@ -434,11 +434,11 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
if (r < 0)
return r;
- r = serialize_strv(f, "exec-cgroup-context-ip-ingress-filter-path=", c->ip_filters_ingress);
+ r = serialize_strv(f, "exec-cgroup-context-ip-ingress-filter-path", c->ip_filters_ingress);
if (r < 0)
return r;
- r = serialize_strv(f, "exec-cgroup-context-ip-egress-filter-path=", c->ip_filters_egress);
+ r = serialize_strv(f, "exec-cgroup-context-ip-egress-filter-path", c->ip_filters_egress);
if (r < 0)
return r;
@@ -1759,15 +1759,23 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) {
if (r < 0)
return r;
- r = serialize_item(f, "exec-context-working-directory", c->working_directory);
+ r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
if (r < 0)
return r;
- r = serialize_item(f, "exec-context-root-directory", c->root_directory);
+ r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
if (r < 0)
return r;
- r = serialize_item(f, "exec-context-root-image", c->root_image);
+ r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
+ if (r < 0)
+ return r;
+
+ r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
+ if (r < 0)
+ return r;
+
+ r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
if (r < 0)
return r;
@@ -1982,14 +1990,6 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) {
return r;
}
- r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
- if (r < 0)
- return r;
-
- r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
- if (r < 0)
- return r;
-
if (c->oom_score_adjust_set) {
r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
if (r < 0)
@@ -2627,17 +2627,29 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) {
if (r < 0)
return r;
} else if ((val = startswith(l, "exec-context-working-directory="))) {
- r = free_and_strdup(&c->working_directory, val);
- if (r < 0)
- return r;
+ ssize_t k;
+ char *p;
+
+ k = cunescape(val, 0, &p);
+ if (k < 0)
+ return k;
+ free_and_replace(c->working_directory, p);
} else if ((val = startswith(l, "exec-context-root-directory="))) {
- r = free_and_strdup(&c->root_directory, val);
- if (r < 0)
- return r;
+ ssize_t k;
+ char *p;
+
+ k = cunescape(val, 0, &p);
+ if (k < 0)
+ return k;
+ free_and_replace(c->root_directory, p);
} else if ((val = startswith(l, "exec-context-root-image="))) {
- r = free_and_strdup(&c->root_image, val);
- if (r < 0)
- return r;
+ ssize_t k;
+ char *p;
+
+ k = cunescape(val, 0, &p);
+ if (k < 0)
+ return k;
+ free_and_replace(c->root_image, p);
} else if ((val = startswith(l, "exec-context-root-image-options="))) {
for (;;) {
_cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
diff --git a/src/core/execute.c b/src/core/execute.c
index 513e95e..f74665f 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -379,6 +379,7 @@ int exec_spawn(
assert(ret);
LOG_CONTEXT_PUSH_UNIT(unit);
+ LOG_CONTEXT_SET_LOG_LEVEL(context->log_level_max >= 0 ? context->log_level_max : log_get_max_level());
r = exec_context_load_environment(unit, context, &params->files_env);
if (r < 0)
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index fd45744..dc9c44e 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -102,7 +102,7 @@ int unit_load_dropin(Unit *u) {
return r;
/* Load .conf dropins */
- r = unit_find_dropin_paths(u, &l);
+ r = unit_find_dropin_paths(u, /* use_unit_path_cache = */ true, &l);
if (r <= 0)
return 0;
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
index f0b87d3..141bc7d 100644
--- a/src/core/load-dropin.h
+++ b/src/core/load-dropin.h
@@ -6,12 +6,12 @@
/* Read service data supplementary drop-in directories */
-static inline int unit_find_dropin_paths(Unit *u, char ***paths) {
+static inline int unit_find_dropin_paths(Unit *u, bool use_unit_path_cache, char ***paths) {
assert(u);
return unit_file_find_dropin_paths(NULL,
u->manager->lookup_paths.search_path,
- u->manager->unit_path_cache,
+ use_unit_path_cache ? u->manager->unit_path_cache : NULL,
".d", ".conf",
u->id, u->aliases,
paths);
diff --git a/src/core/socket.c b/src/core/socket.c
index 41147d4..0694fe7 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -2481,7 +2481,7 @@ static int socket_start(Unit *u) {
/* If the service is already active we cannot start the
* socket */
if (!IN_SET(service->state,
- SERVICE_DEAD, SERVICE_DEAD_BEFORE_AUTO_RESTART, SERVICE_FAILED, SERVICE_FAILED_BEFORE_AUTO_RESTART,
+ SERVICE_DEAD, SERVICE_DEAD_BEFORE_AUTO_RESTART, SERVICE_DEAD_RESOURCES_PINNED, SERVICE_FAILED, SERVICE_FAILED_BEFORE_AUTO_RESTART,
SERVICE_AUTO_RESTART, SERVICE_AUTO_RESTART_QUEUED))
return log_unit_error_errno(u, SYNTHETIC_ERRNO(EBUSY),
"Socket service %s already active, refusing.", UNIT(service)->id);
@@ -3369,7 +3369,7 @@ static void socket_trigger_notify(Unit *u, Unit *other) {
return;
if (IN_SET(SERVICE(other)->state,
- SERVICE_DEAD, SERVICE_DEAD_BEFORE_AUTO_RESTART, SERVICE_FAILED, SERVICE_FAILED_BEFORE_AUTO_RESTART,
+ SERVICE_DEAD, SERVICE_DEAD_BEFORE_AUTO_RESTART, SERVICE_DEAD_RESOURCES_PINNED, SERVICE_FAILED, SERVICE_FAILED_BEFORE_AUTO_RESTART,
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
SERVICE_AUTO_RESTART, SERVICE_AUTO_RESTART_QUEUED))
socket_enter_listening(s);
diff --git a/src/core/unit.c b/src/core/unit.c
index 01c9983..4ca7dc4 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -3831,7 +3831,7 @@ bool unit_need_daemon_reload(Unit *u) {
if (u->load_state == UNIT_LOADED) {
_cleanup_strv_free_ char **dropins = NULL;
- (void) unit_find_dropin_paths(u, &dropins);
+ (void) unit_find_dropin_paths(u, /* use_unit_path_cache = */ false, &dropins);
if (!strv_equal(u->dropin_paths, dropins))
return true;
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 6afabef..0dbdfc6 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -908,8 +908,7 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch
_cleanup_fclose_ FILE *original = NULL, *passwd = NULL;
_cleanup_(unlink_and_freep) char *passwd_tmp = NULL;
int r;
-
- assert(password);
+ bool found = false;
r = fopen_temporary_at_label(etc_fd, "passwd", "passwd", &passwd, &passwd_tmp);
if (r < 0)
@@ -929,9 +928,11 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch
while ((r = fgetpwent_sane(original, &i)) > 0) {
if (streq(i->pw_name, "root")) {
- i->pw_passwd = (char *) password;
+ if (password)
+ i->pw_passwd = (char *) password;
if (shell)
i->pw_shell = (char *) shell;
+ found = true;
}
r = putpwent_sane(i, passwd);
@@ -942,9 +943,15 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch
return r;
} else {
+ r = fchmod(fileno(passwd), 0644);
+ if (r < 0)
+ return -errno;
+ }
+
+ if (!found) {
struct passwd root = {
.pw_name = (char *) "root",
- .pw_passwd = (char *) password,
+ .pw_passwd = (char *) (password ?: PASSWORD_SEE_SHADOW),
.pw_uid = 0,
.pw_gid = 0,
.pw_gecos = (char *) "Super User",
@@ -955,10 +962,6 @@ static int write_root_passwd(int rfd, int etc_fd, const char *password, const ch
if (errno != ENOENT)
return -errno;
- r = fchmod(fileno(passwd), 0644);
- if (r < 0)
- return -errno;
-
r = putpwent_sane(&root, passwd);
if (r < 0)
return r;
@@ -979,8 +982,7 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) {
_cleanup_fclose_ FILE *original = NULL, *shadow = NULL;
_cleanup_(unlink_and_freep) char *shadow_tmp = NULL;
int r;
-
- assert(hashed_password);
+ bool found = false;
r = fopen_temporary_at_label(etc_fd, "shadow", "shadow", &shadow, &shadow_tmp);
if (r < 0)
@@ -1000,8 +1002,11 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) {
while ((r = fgetspent_sane(original, &i)) > 0) {
if (streq(i->sp_namp, "root")) {
- i->sp_pwdp = (char *) hashed_password;
- i->sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+ if (hashed_password) {
+ i->sp_pwdp = (char *) hashed_password;
+ i->sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY);
+ }
+ found = true;
}
r = putspent_sane(i, shadow);
@@ -1012,9 +1017,15 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) {
return r;
} else {
+ r = fchmod(fileno(shadow), 0000);
+ if (r < 0)
+ return -errno;
+ }
+
+ if (!found) {
struct spwd root = {
.sp_namp = (char*) "root",
- .sp_pwdp = (char *) hashed_password,
+ .sp_pwdp = (char *) (hashed_password ?: PASSWORD_LOCKED_AND_INVALID),
.sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY),
.sp_min = -1,
.sp_max = -1,
@@ -1027,10 +1038,6 @@ static int write_root_shadow(int etc_fd, const char *hashed_password) {
if (errno != ENOENT)
return -errno;
- r = fchmod(fileno(shadow), 0000);
- if (r < 0)
- return -errno;
-
r = putspent_sane(&root, shadow);
if (r < 0)
return r;
@@ -1081,13 +1088,6 @@ static int process_root_account(int rfd) {
return 0;
}
- /* Don't create/modify passwd and shadow if not asked */
- if (!(arg_root_password || arg_prompt_root_password || arg_copy_root_password || arg_delete_root_password ||
- arg_root_shell || arg_prompt_root_shell || arg_copy_root_shell)) {
- log_debug("Initialization of root account was not requested, skipping.");
- return 0;
- }
-
r = make_lock_file_at(pfd, ETC_PASSWD_LOCK_FILENAME, LOCK_EX, &lock);
if (r < 0)
return log_error_errno(r, "Failed to take a lock on /etc/passwd: %m");
@@ -1142,10 +1142,22 @@ static int process_root_account(int rfd) {
password = PASSWORD_SEE_SHADOW;
hashed_password = _hashed_password;
- } else if (arg_delete_root_password)
- password = hashed_password = PASSWORD_NONE;
- else
- password = hashed_password = PASSWORD_LOCKED_AND_INVALID;
+ } else if (arg_delete_root_password) {
+ password = PASSWORD_SEE_SHADOW;
+ hashed_password = PASSWORD_NONE;
+ } else if (!arg_root_password && arg_prompt_root_password) {
+ /* If the user was prompted, but no password was supplied, lock the account. */
+ password = PASSWORD_SEE_SHADOW;
+ hashed_password = PASSWORD_LOCKED_AND_INVALID;
+ } else
+ /* Leave the password as is. */
+ password = hashed_password = NULL;
+
+ /* Don't create/modify passwd and shadow if there's nothing to do. */
+ if (!(password || hashed_password || arg_root_shell)) {
+ log_debug("Initialization of root account was not requested, skipping.");
+ return 0;
+ }
r = write_root_passwd(rfd, pfd, password, arg_root_shell);
if (r < 0)
diff --git a/src/fundamental/confidential-virt-fundamental.h b/src/fundamental/confidential-virt-fundamental.h
index 986923e..618b580 100644
--- a/src/fundamental/confidential-virt-fundamental.h
+++ b/src/fundamental/confidential-virt-fundamental.h
@@ -65,6 +65,7 @@
#define CPUID_HYPERV_ISOLATION_TYPE_MASK UINT32_C(0xf)
#define CPUID_HYPERV_ISOLATION_TYPE_SNP 2
+#define CPUID_HYPERV_ISOLATION_TYPE_TDX 3
#define EAX_SEV (UINT32_C(1) << 1)
#define MSR_SEV (UINT64_C(1) << 0)
diff --git a/src/import/import-raw.c b/src/import/import-raw.c
index ee9b297..78775b9 100644
--- a/src/import/import-raw.c
+++ b/src/import/import-raw.c
@@ -409,6 +409,11 @@ static int raw_import_process(RawImport *i) {
goto finish;
}
+ if ((size_t) l > sizeof(i->buffer) - i->buffer_size) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Read input file exceeded maximum size.");
+ goto finish;
+ }
+
i->buffer_size += l;
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
diff --git a/src/import/import-tar.c b/src/import/import-tar.c
index 39df11b..976c918 100644
--- a/src/import/import-tar.c
+++ b/src/import/import-tar.c
@@ -276,6 +276,11 @@ static int tar_import_process(TarImport *i) {
goto finish;
}
+ if ((size_t) l > sizeof(i->buffer) - i->buffer_size) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Read input file exceeded maximum size.");
+ goto finish;
+ }
+
i->buffer_size += l;
if (i->compress.type == IMPORT_COMPRESS_UNKNOWN) {
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
index 717c8e4..07748f0 100644
--- a/src/journal/journald-server.c
+++ b/src/journal/journald-server.c
@@ -1349,9 +1349,10 @@ int server_flush_to_var(Server *s, bool require_flag_file) {
start = now(CLOCK_MONOTONIC);
r = sd_journal_open(&j, SD_JOURNAL_RUNTIME_ONLY | SD_JOURNAL_ASSUME_IMMUTABLE);
- if (r < 0)
- return log_ratelimit_error_errno(r, JOURNAL_LOG_RATELIMIT,
- "Failed to read runtime journal: %m");
+ if (r < 0) {
+ log_ratelimit_error_errno(r, JOURNAL_LOG_RATELIMIT, "Failed to read runtime journal: %m");
+ goto finish;
+ }
sd_journal_set_data_threshold(j, 0);
diff --git a/src/journal/journald.c b/src/journal/journald.c
index 2f013c2..87ed22e 100644
--- a/src/journal/journald.c
+++ b/src/journal/journald.c
@@ -94,8 +94,7 @@ static int run(int argc, char *argv[]) {
/* The retention time is reached, so let's vacuum! */
if (t <= 0) {
- log_info("Retention time reached, rotating.");
- server_rotate(s);
+ log_info("Retention time reached, vacuuming.");
server_vacuum(s, /* verbose = */ false);
continue;
}
diff --git a/src/journal/journald.conf b/src/journal/journald.conf
index 13cdd63..9a12ca7 100644
--- a/src/journal/journald.conf
+++ b/src/journal/journald.conf
@@ -32,7 +32,7 @@
#RuntimeKeepFree=
#RuntimeMaxFileSize=
#RuntimeMaxFiles=100
-#MaxRetentionSec=
+#MaxRetentionSec=0
#MaxFileSec=1month
#ForwardToSyslog=no
#ForwardToKMsg=no
diff --git a/src/kernel-install/50-depmod.install b/src/kernel-install/50-depmod.install
index 88f858f..08247c7 100755
--- a/src/kernel-install/50-depmod.install
+++ b/src/kernel-install/50-depmod.install
@@ -44,6 +44,7 @@ case "$COMMAND" in
"/lib/modules/$KERNEL_VERSION/modules.dep.bin" \
"/lib/modules/$KERNEL_VERSION/modules.devname" \
"/lib/modules/$KERNEL_VERSION/modules.softdep" \
+ "/lib/modules/$KERNEL_VERSION/modules.weakdep" \
"/lib/modules/$KERNEL_VERSION/modules.symbols" \
"/lib/modules/$KERNEL_VERSION/modules.symbols.bin"
;;
diff --git a/src/kernel-install/90-loaderentry.install.in b/src/kernel-install/90-loaderentry.install.in
index 4ef6aca..c9ba111 100755
--- a/src/kernel-install/90-loaderentry.install.in
+++ b/src/kernel-install/90-loaderentry.install.in
@@ -79,8 +79,10 @@ elif [ -f /etc/kernel/cmdline ]; then
BOOT_OPTIONS="$(tr -s "$IFS" ' ' </etc/kernel/cmdline)"
elif [ -f /usr/lib/kernel/cmdline ]; then
BOOT_OPTIONS="$(tr -s "$IFS" ' ' </usr/lib/kernel/cmdline)"
-else
+elif ! systemd-detect-virt --container --quiet; then
BOOT_OPTIONS="$(tr -s "$IFS" '\n' </proc/cmdline | grep -ve '^BOOT_IMAGE=' -e '^initrd=' | tr '\n' ' ')"
+else
+ BOOT_OPTIONS=""
fi
BOOT_OPTIONS="${BOOT_OPTIONS% }"
@@ -194,7 +196,7 @@ mkdir -p "${LOADER_ENTRY%/*}" || {
echo "machine-id $MACHINE_ID"
fi
[ -n "$SORT_KEY" ] && echo "sort-key $SORT_KEY"
- echo "options $BOOT_OPTIONS"
+ [ -n "$BOOT_OPTIONS" ] && echo "options $BOOT_OPTIONS"
echo "linux $KERNEL_ENTRY"
[ -n "$DEVICETREE_ENTRY" ] && echo "devicetree $DEVICETREE_ENTRY"
@@ -205,8 +207,18 @@ mkdir -p "${LOADER_ENTRY%/*}" || {
have_initrd=yes
done
- # Try "initrd", generated by dracut in its kernel-install hook, if no initrds were supplied
- [ -z "$have_initrd" ] && [ -f "$ENTRY_DIR_ABS/initrd" ] && echo "initrd $ENTRY_DIR/initrd"
+ # Try a few variations that are generated by various initrd generators in their kernel-install hooks if
+ # no initrds were supplied.
+
+ if [ -z "$have_initrd" ] && [ -f "$ENTRY_DIR_ABS/initrd" ]; then
+ echo "initrd $ENTRY_DIR/initrd"
+ have_initrd=yes
+ fi
+
+ if [ -z "$have_initrd" ] && [ -f "$BOOT_ROOT/initramfs-$KERNEL_VERSION.img" ]; then
+ echo "initrd /initramfs-$KERNEL_VERSION.img"
+ have_initrd=yes
+ fi
:
} >"$LOADER_ENTRY" || {
echo "Error: could not create loader entry '$LOADER_ENTRY'." >&2
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index a1305ef..73a95e7 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -3866,7 +3866,8 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events, i
if (_unlikely_(n != sizeof(si)))
return -EIO;
- assert(SIGNAL_VALID(si.ssi_signo));
+ if (_unlikely_(!SIGNAL_VALID(si.ssi_signo)))
+ return -EIO;
if (e->signal_sources)
s = e->signal_sources[si.ssi_signo];
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 0521863..ceff268 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -9,6 +9,7 @@
#include "alloc-util.h"
#include "audit-util.h"
+#include "bitfield.h"
#include "bootspec.h"
#include "bus-common-errors.h"
#include "bus-error.h"
@@ -3550,23 +3551,27 @@ static int method_inhibit(sd_bus_message *message, void *userdata, sd_bus_error
return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS,
"The operation inhibition has been requested for is already running");
- r = bus_verify_polkit_async(
- message,
- w == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
- w == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
- w == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
- w == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
- w == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
- w == INHIBIT_HANDLE_REBOOT_KEY ? "org.freedesktop.login1.inhibit-handle-reboot-key" :
- w == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
- "org.freedesktop.login1.inhibit-handle-lid-switch",
- /* details= */ NULL,
- &m->polkit_registry,
- error);
- if (r < 0)
- return r;
- if (r == 0)
- return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+ BIT_FOREACH(i, w) {
+ const InhibitWhat v = 1U << i;
+
+ r = bus_verify_polkit_async(
+ message,
+ v == INHIBIT_SHUTDOWN ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-shutdown" : "org.freedesktop.login1.inhibit-delay-shutdown") :
+ v == INHIBIT_SLEEP ? (mm == INHIBIT_BLOCK ? "org.freedesktop.login1.inhibit-block-sleep" : "org.freedesktop.login1.inhibit-delay-sleep") :
+ v == INHIBIT_IDLE ? "org.freedesktop.login1.inhibit-block-idle" :
+ v == INHIBIT_HANDLE_POWER_KEY ? "org.freedesktop.login1.inhibit-handle-power-key" :
+ v == INHIBIT_HANDLE_SUSPEND_KEY ? "org.freedesktop.login1.inhibit-handle-suspend-key" :
+ v == INHIBIT_HANDLE_REBOOT_KEY ? "org.freedesktop.login1.inhibit-handle-reboot-key" :
+ v == INHIBIT_HANDLE_HIBERNATE_KEY ? "org.freedesktop.login1.inhibit-handle-hibernate-key" :
+ "org.freedesktop.login1.inhibit-handle-lid-switch",
+ /* details= */ NULL,
+ &m->polkit_registry,
+ error);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
+ }
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PIDFD, &creds);
if (r < 0)
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 6b0f099..9ce7536 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1714,6 +1714,13 @@ static int link_carrier_gained(Link *link) {
if (r < 0)
log_link_warning_errno(link, r, "Failed to disable carrier lost timer, ignoring: %m");
+ /* Process BindCarrier= setting specified by other interfaces. This is independent of the .network
+ * file assigned to this interface, but depends on .network files assigned to other interfaces.
+ * Hence, this can and should be called earlier. */
+ r = link_handle_bound_by_list(link);
+ if (r < 0)
+ return r;
+
/* If a wireless interface was connected to an access point, and the SSID is changed (that is,
* both previous_ssid and ssid are non-NULL), then the connected wireless network could be
* changed. So, always reconfigure the link. Which means e.g. the DHCP client will be
@@ -1747,10 +1754,6 @@ static int link_carrier_gained(Link *link) {
if (r != 0)
return r;
- r = link_handle_bound_by_list(link);
- if (r < 0)
- return r;
-
if (link->iftype == ARPHRD_CAN)
/* let's shortcut things for CAN which doesn't need most of what's done below. */
return 0;
@@ -1769,25 +1772,22 @@ static int link_carrier_gained(Link *link) {
}
static int link_carrier_lost_impl(Link *link) {
- int r, ret = 0;
+ int ret = 0;
assert(link);
link->previous_ssid = mfree(link->previous_ssid);
+ ret = link_handle_bound_by_list(link);
+
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
- return 0;
+ return ret;
if (!link->network)
- return 0;
-
- r = link_stop_engines(link, false);
- if (r < 0)
- ret = r;
+ return ret;
- r = link_drop_managed_config(link);
- if (r < 0 && ret >= 0)
- ret = r;
+ RET_GATHER(ret, link_stop_engines(link, false));
+ RET_GATHER(ret, link_drop_managed_config(link));
return ret;
}
@@ -1808,22 +1808,17 @@ static int link_carrier_lost_handler(sd_event_source *s, uint64_t usec, void *us
static int link_carrier_lost(Link *link) {
uint16_t dhcp_mtu;
usec_t usec;
- int r;
assert(link);
- r = link_handle_bound_by_list(link);
- if (r < 0)
- return r;
-
if (link->iftype == ARPHRD_CAN)
/* let's shortcut things for CAN which doesn't need most of what's done below. */
- return 0;
+ usec = 0;
- if (!link->network)
- return 0;
+ else if (!link->network)
+ usec = 0;
- if (link->network->ignore_carrier_loss_set)
+ else if (link->network->ignore_carrier_loss_set)
/* If IgnoreCarrierLoss= is explicitly specified, then use the specified value. */
usec = link->network->ignore_carrier_loss_usec;
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 50d284b..84558a5 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -2080,12 +2080,6 @@ static int ndisc_start_dhcp6_client(Link *link, sd_ndisc_router *rt) {
assert(link);
assert(link->network);
- /* Do not start DHCPv6 client if the router lifetime is zero, as the message sent as a signal of
- * that the router is e.g. shutting down, revoked, etc,. */
- r = sd_ndisc_router_get_lifetime(rt, NULL);
- if (r <= 0)
- return r;
-
switch (link->network->ndisc_start_dhcp6_client) {
case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO:
return 0;
diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c
index 886b4da..c6b3779 100644
--- a/src/network/networkd-routing-policy-rule.c
+++ b/src/network/networkd-routing-policy-rule.c
@@ -483,9 +483,7 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
return r;
}
- if (rule->l3mdev)
- r = sd_rtnl_message_routing_policy_rule_set_table(m, RT_TABLE_UNSPEC);
- else if (rule->table < 256)
+ if (rule->table < 256)
r = sd_rtnl_message_routing_policy_rule_set_table(m, rule->table);
else {
r = sd_rtnl_message_routing_policy_rule_set_table(m, RT_TABLE_UNSPEC);
@@ -1784,6 +1782,9 @@ static int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
/* rule->family can be AF_UNSPEC only when Family=both. */
}
+ if (rule->l3mdev)
+ rule->table = RT_TABLE_UNSPEC;
+
return 0;
}
diff --git a/src/nspawn/nspawn-network.c b/src/nspawn/nspawn-network.c
index ec5d396..f46995b 100644
--- a/src/nspawn/nspawn-network.c
+++ b/src/nspawn/nspawn-network.c
@@ -821,6 +821,56 @@ int setup_macvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
return 0;
}
+static int remove_macvlan_impl(char **interface_pairs) {
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
+ int r;
+
+ assert(interface_pairs);
+
+ r = sd_netlink_open(&rtnl);
+ if (r < 0)
+ return log_error_errno(r, "Failed to connect to netlink: %m");
+
+ STRV_FOREACH_PAIR(a, b, interface_pairs) {
+ _cleanup_free_ char *n = NULL;
+
+ n = strdup(*b);
+ if (!n)
+ return log_oom();
+
+ (void) net_shorten_ifname(n, /* check_naming_scheme= */ true);
+
+ r = remove_one_link(rtnl, n);
+ if (r < 0)
+ log_warning_errno(r, "Failed to remove macvlan interface %s, ignoring: %m", n);
+ }
+
+ return 0;
+}
+
+int remove_macvlan(int child_netns_fd, char **interface_pairs) {
+ _cleanup_close_ int parent_netns_fd = -EBADF;
+ int r;
+
+ /* In some cases the kernel might pin the macvlan links on the container even after the namespace
+ * died. Hence, let's better remove them explicitly too. See issue #680. */
+
+ assert(child_netns_fd >= 0);
+
+ if (strv_isempty(interface_pairs))
+ return 0;
+
+ r = netns_fork_and_wait(child_netns_fd, &parent_netns_fd);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ r = remove_macvlan_impl(interface_pairs);
+ _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+ }
+
+ return 0;
+}
+
int setup_ipvlan(const char *machine_name, pid_t pid, char **iface_pairs) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
int r;
diff --git a/src/nspawn/nspawn-network.h b/src/nspawn/nspawn-network.h
index 840fe15..ed08c98 100644
--- a/src/nspawn/nspawn-network.h
+++ b/src/nspawn/nspawn-network.h
@@ -17,6 +17,7 @@ int setup_bridge(const char *veth_name, const char *bridge_name, bool create);
int remove_bridge(const char *bridge_name);
int setup_macvlan(const char *machine_name, pid_t pid, char **iface_pairs);
+int remove_macvlan(int child_netns_fd, char **interface_pairs);
int setup_ipvlan(const char *machine_name, pid_t pid, char **iface_pairs);
int move_network_interfaces(int netns_fd, char **iface_pairs);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f8c34b5..7d87116 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -5607,6 +5607,10 @@ static int run_container(
r = move_back_network_interfaces(child_netns_fd, arg_network_interfaces);
if (r < 0)
return r;
+
+ r = remove_macvlan(child_netns_fd, arg_network_macvlan);
+ if (r < 0)
+ return r;
}
r = wait_for_container(TAKE_PID(*pid), &container_status);
diff --git a/src/pcrlock/pcrlock.c b/src/pcrlock/pcrlock.c
index 1716fb3..9a7b73f 100644
--- a/src/pcrlock/pcrlock.c
+++ b/src/pcrlock/pcrlock.c
@@ -1925,6 +1925,9 @@ static int event_log_map_components(EventLog *el) {
continue;
}
+ if (c->n_variants == 0)
+ log_notice("Component '%s' has no defined variants.", c->id);
+
FOREACH_ARRAY(ii, c->variants, c->n_variants) {
EventLogComponentVariant *i = *ii;
@@ -4060,6 +4063,15 @@ static int event_log_predict_pcrs(
component = ASSERT_PTR(el->components[component_index]);
+ if (component->n_variants == 0)
+ return event_log_predict_pcrs(
+ el,
+ context,
+ parent_result,
+ component_index + 1, /* Next component */
+ pcr,
+ path);
+
FOREACH_ARRAY(ii, component->variants, component->n_variants) {
_cleanup_free_ Tpm2PCRPredictionResult *result = NULL;
EventLogComponentVariant *variant = *ii;
@@ -4118,7 +4130,9 @@ static ssize_t event_log_calculate_component_combinations(EventLog *el) {
/* Overflow check */
if (c->n_variants > (size_t) (SSIZE_MAX/count))
return log_error_errno(SYNTHETIC_ERRNO(E2BIG), "Too many component combinations.");
-
+ /* If no variant, this will lead to count being 0 and sigfpe */
+ if (c->n_variants == 0)
+ continue;
count *= c->n_variants;
}
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
index d6d2273..847bb6b 100644
--- a/src/resolve/resolved-bus.c
+++ b/src/resolve/resolved-bus.c
@@ -1148,6 +1148,11 @@ static void resolve_service_all_complete(DnsQuery *query) {
if (r < 0)
goto finish;
+ if (isempty(type)) {
+ r = reply_method_errorf(q, BUS_ERROR_NO_SUCH_SERVICE, "'%s' does not provide valid service", dns_query_string(q));
+ goto finish;
+ }
+
r = sd_bus_message_append(
reply,
"ssst",
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
index 1a43d0b..8c15120 100644
--- a/src/resolve/resolved-dns-stream.c
+++ b/src/resolve/resolved-dns-stream.c
@@ -322,6 +322,12 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use
return dns_stream_complete(s, -r);
}
+ if (revents & EPOLLERR) {
+ socklen_t errlen = sizeof(r);
+ if (getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &r, &errlen) == 0)
+ return dns_stream_complete(s, r);
+ }
+
if ((revents & EPOLLOUT) &&
s->write_packet &&
s->n_written < sizeof(s->write_size) + s->write_packet->size) {
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 92ac075..17a815c 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -633,7 +633,7 @@ static int on_stream_complete(DnsStream *s, int error) {
if (ERRNO_IS_DISCONNECT(error) && s->protocol != DNS_PROTOCOL_LLMNR) {
log_debug_errno(error, "Connection failure for DNS TCP stream: %m");
- if (s->transactions) {
+ if (error != ECONNRESET && s->transactions) {
DnsTransaction *t;
t = s->transactions;
@@ -1264,7 +1264,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
}
/* These codes probably indicate a transient error. Let's try again. */
- if (IN_SET(t->answer_ede_rcode, DNS_EDE_RCODE_NOT_READY, DNS_EDE_RCODE_NET_ERROR)) {
+ if (t->answer_ede_rcode == DNS_EDE_RCODE_NOT_READY) {
log_debug("Server returned error: %s (%s%s%s), retrying transaction.",
FORMAT_DNS_RCODE(DNS_PACKET_RCODE(p)),
FORMAT_DNS_EDE_RCODE(t->answer_ede_rcode),
diff --git a/src/resolve/resolved-varlink.c b/src/resolve/resolved-varlink.c
index 25f85d8..f02ebe3 100644
--- a/src/resolve/resolved-varlink.c
+++ b/src/resolve/resolved-varlink.c
@@ -829,6 +829,11 @@ static void resolve_service_all_complete(DnsQuery *query) {
if (r < 0)
goto finish;
+ if (isempty(type)) {
+ r = varlink_error(q->varlink_request, "io.systemd.Resolve.ServiceNotProvided", NULL);
+ goto finish;
+ }
+
r = varlink_replyb(query->varlink_request, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("services", JSON_BUILD_VARIANT(srv)),
JSON_BUILD_PAIR_CONDITION(!json_variant_is_blank_object(txt), "txt", JSON_BUILD_VARIANT(txt)),
diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
index a4e2dae..0d5075e 100644
--- a/src/shared/base-filesystem.c
+++ b/src/shared/base-filesystem.c
@@ -56,8 +56,7 @@ static const BaseFilesystem table[] = {
/* aarch64 ELF ABI actually says dynamic loader is in /lib/, but Fedora puts it in /lib64/ anyway and
* just symlinks /lib/ld-linux-aarch64.so.1 to ../lib64/ld-linux-aarch64.so.1. For this to work
* correctly, /lib64/ must be symlinked to /usr/lib64/. */
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld-linux-aarch64.so.1" },
# define KNOW_LIB64_DIRS 1
#elif defined(__alpha__)
@@ -66,24 +65,20 @@ static const BaseFilesystem table[] = {
/* No /lib64 on arm. The linker is /lib/ld-linux-armhf.so.3. */
# define KNOW_LIB64_DIRS 1
#elif defined(__i386__) || defined(__x86_64__)
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld-linux-x86-64.so.2" },
# define KNOW_LIB64_DIRS 1
#elif defined(__ia64__)
#elif defined(__loongarch_lp64)
# define KNOW_LIB64_DIRS 1
# if defined(__loongarch_double_float)
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld-linux-loongarch-lp64d.so.1" },
# elif defined(__loongarch_single_float)
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld-linux-loongarch-lp64f.so.1" },
# elif defined(__loongarch_soft_float)
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld-linux-loongarch-lp64s.so.1" },
# else
# error "Unknown LoongArch ABI"
@@ -100,8 +95,7 @@ static const BaseFilesystem table[] = {
# endif
#elif defined(__powerpc__)
# if defined(__PPC64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld64.so.2" },
# define KNOW_LIB64_DIRS 1
# elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
@@ -113,16 +107,14 @@ static const BaseFilesystem table[] = {
# if __riscv_xlen == 32
# elif __riscv_xlen == 64
/* Same situation as for aarch64 */
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld-linux-riscv64-lp64d.so.1" },
# define KNOW_LIB64_DIRS 1
# else
# error "Unknown RISC-V ABI"
# endif
#elif defined(__s390x__)
- { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0"
- "usr/lib64\0"
+ { "lib64", 0, "usr/lib64\0"
"usr/lib\0", "ld-lsb-s390x.so.3" },
# define KNOW_LIB64_DIRS 1
#elif defined(__s390__)
diff --git a/src/shared/edit-util.c b/src/shared/edit-util.c
index cfb2828..b049603 100644
--- a/src/shared/edit-util.c
+++ b/src/shared/edit-util.c
@@ -357,7 +357,7 @@ static int strip_edit_temp_file(EditFile *e) {
return 1; /* Contents have real changes */
r = write_string_file(e->temp, new_contents,
- WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_TRUNCATE | WRITE_STRING_FILE_AVOID_NEWLINE);
+ WRITE_STRING_FILE_TRUNCATE | WRITE_STRING_FILE_AVOID_NEWLINE);
if (r < 0)
return log_error_errno(r, "Failed to strip temporary file '%s': %m", e->temp);
diff --git a/src/shared/resize-fs.h b/src/shared/resize-fs.h
index b40943c..bacaec7 100644
--- a/src/shared/resize-fs.h
+++ b/src/shared/resize-fs.h
@@ -7,9 +7,9 @@
int resize_fs(int fd, uint64_t sz, uint64_t *ret_size);
-#define BTRFS_MINIMAL_SIZE (256U*1024U*1024U)
-#define XFS_MINIMAL_SIZE (300U*1024U*1024U)
-#define EXT4_MINIMAL_SIZE (1024U*1024U)
+#define BTRFS_MINIMAL_SIZE (256U*U64_MB)
+#define XFS_MINIMAL_SIZE (300U*U64_MB)
+#define EXT4_MINIMAL_SIZE (32U*U64_MB)
uint64_t minimal_size_by_fs_magic(statfs_f_type_t magic);
uint64_t minimal_size_by_fs_name(const char *str);
diff --git a/src/shared/tests.h b/src/shared/tests.h
index 09fdfd6..21f00db 100644
--- a/src/shared/tests.h
+++ b/src/shared/tests.h
@@ -227,6 +227,16 @@ static inline int run_test_table(void) {
} \
})
+#define ASSERT_FAIL(expr) \
+ ({ \
+ typeof(expr) _result = (expr); \
+ if (_result >= 0) { \
+ log_error_errno(_result, "%s:%i: Assertion failed: expected \"%s\" to fail, but it succeeded", \
+ PROJECT_FILE, __LINE__, #expr); \
+ abort(); \
+ } \
+ })
+
#define ASSERT_ERROR(expr1, expr2) \
({ \
int _expr1 = (expr1); \
@@ -419,3 +429,30 @@ static inline int run_test_table(void) {
abort(); \
} \
})
+
+
+#define ASSERT_EQ_ID128(expr1, expr2) \
+ ({ \
+ typeof(expr1) _expr1 = (expr1); \
+ typeof(expr2) _expr2 = (expr2); \
+ if (!sd_id128_equal(_expr1, _expr2)) { \
+ log_error("%s:%i: Assertion failed: \"%s == %s\", but \"%s != %s\"", \
+ PROJECT_FILE, __LINE__, \
+ #expr1, #expr2, \
+ SD_ID128_TO_STRING(_expr1), SD_ID128_TO_STRING(_expr2)); \
+ abort(); \
+ } \
+ })
+
+#define ASSERT_NE_ID128(expr1, expr2) \
+ ({ \
+ typeof(expr1) _expr1 = (expr1); \
+ typeof(expr2) _expr2 = (expr2); \
+ if (sd_id128_equal(_expr1, _expr2)) { \
+ log_error("%s:%i: Assertion failed: \"%s != %s\", but \"%s == %s\"", \
+ PROJECT_FILE, __LINE__, \
+ #expr1, #expr2, \
+ SD_ID128_TO_STRING(_expr1), SD_ID128_TO_STRING(_expr2)); \
+ abort(); \
+ } \
+ })
diff --git a/src/systemctl/systemctl-logind.c b/src/systemctl/systemctl-logind.c
index d6cdd97..4507000 100644
--- a/src/systemctl/systemctl-logind.c
+++ b/src/systemctl/systemctl-logind.c
@@ -432,6 +432,14 @@ int help_boot_loader_entry(void) {
sd_bus *bus;
int r;
+ /* This is called without checking runtime scope and bus transport like we do in parse_argv().
+ * Loading boot entries is only supported by system scope. Let's gracefully adjust them. */
+ arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
+ if (arg_transport == BUS_TRANSPORT_CAPSULE) {
+ arg_host = NULL;
+ arg_transport = BUS_TRANSPORT_LOCAL;
+ }
+
r = acquire_bus(BUS_FULL, &bus);
if (r < 0)
return r;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 0ca76ac..97bdfad 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1073,6 +1073,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Cannot access user instance remotely.");
+ if (arg_transport == BUS_TRANSPORT_CAPSULE && arg_runtime_scope != RUNTIME_SCOPE_USER)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Cannot access system instance with --capsule=/-C.");
+
if (arg_wait && arg_no_block)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--wait may not be combined with --no-block.");
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index 5fe3b0c..7758267 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -1448,9 +1448,15 @@ static int process_item(Context *c, Item *i) {
case ADD_USER: {
Item *j = NULL;
- if (!i->gid_set)
+ if (!i->gid_set) {
j = ordered_hashmap_get(c->groups, i->group_name ?: i->name);
+ /* If that's not a match, also check if the group name
+ * matches a user name in the queue. */
+ if (!j && i->group_name)
+ j = ordered_hashmap_get(c->users, i->group_name);
+ }
+
if (j && j->todo_group) {
/* When a group with the target name is already in queue,
* use the information about the group and do not create
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
index 4e236bd..5643053 100644
--- a/src/test/test-conf-parser.c
+++ b/src/test/test-conf-parser.c
@@ -7,6 +7,7 @@
#include "log.h"
#include "macro.h"
#include "mkdir.h"
+#include "rm-rf.h"
#include "string-util.h"
#include "strv.h"
#include "tests.h"
@@ -393,19 +394,16 @@ TEST(config_parse) {
}
TEST(config_parse_standard_file_with_dropins_full) {
- _cleanup_(rmdir_and_freep) char *root = NULL;
+ _cleanup_(rm_rf_physical_and_freep) char *root = NULL;
_cleanup_close_ int rfd = -EBADF;
int r;
- assert_se(mkdtemp_malloc(NULL, &root) >= 0);
+ ASSERT_OK(rfd = mkdtemp_open("/tmp/test-config-parse-XXXXXX", 0, &root));
assert_se(mkdir_p_root(root, "/etc/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755));
assert_se(mkdir_p_root(root, "/run/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755));
assert_se(mkdir_p_root(root, "/usr/lib/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755));
assert_se(mkdir_p_root(root, "/usr/local/lib/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755));
- rfd = open(root, O_CLOEXEC|O_DIRECTORY);
- assert_se(rfd >= 0);
-
assert_se(write_string_file_at(rfd, "usr/lib/kernel/install.conf", /* this one is ignored */
"A=!!!", WRITE_STRING_FILE_CREATE) == 0);
assert_se(write_string_file_at(rfd, "usr/local/lib/kernel/install.conf",
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
index d44e043..f2fa51f 100644
--- a/src/test/test-fs-util.c
+++ b/src/test/test-fs-util.c
@@ -606,71 +606,67 @@ TEST(open_mkdir_at) {
}
TEST(openat_report_new) {
- _cleanup_free_ char *j = NULL;
- _cleanup_(rm_rf_physical_and_freep) char *d = NULL;
- _cleanup_close_ int fd = -EBADF;
+ _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
+ _cleanup_close_ int tfd = -EBADF, fd = -EBADF;
bool b;
- assert_se(mkdtemp_malloc(NULL, &d) >= 0);
-
- j = path_join(d, "test");
- assert_se(j);
+ ASSERT_OK((tfd = mkdtemp_open(NULL, 0, &t)));
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(b);
+ ASSERT_TRUE(b);
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(!b);
+ ASSERT_FALSE(b);
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(!b);
+ ASSERT_FALSE(b);
- assert_se(unlink(j) >= 0);
+ ASSERT_OK_ERRNO(unlinkat(tfd, "test", 0));
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(b);
+ ASSERT_TRUE(b);
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(!b);
+ ASSERT_FALSE(b);
- assert_se(unlink(j) >= 0);
+ ASSERT_OK_ERRNO(unlinkat(tfd, "test", 0));
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT, 0666, NULL);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT, 0666, NULL);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(!b);
+ ASSERT_FALSE(b);
- fd = openat_report_new(AT_FDCWD, j, O_RDWR, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(!b);
+ ASSERT_FALSE(b);
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT|O_EXCL, 0666, &b);
- assert_se(fd == -EEXIST);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT|O_EXCL, 0666, &b);
+ ASSERT_ERROR(fd, EEXIST);
- assert_se(unlink(j) >= 0);
+ ASSERT_OK_ERRNO(unlinkat(tfd, "test", 0));
- fd = openat_report_new(AT_FDCWD, j, O_RDWR, 0666, &b);
- assert_se(fd == -ENOENT);
+ fd = openat_report_new(tfd, "test", O_RDWR, 0666, &b);
+ ASSERT_ERROR(fd, ENOENT);
- fd = openat_report_new(AT_FDCWD, j, O_RDWR|O_CREAT|O_EXCL, 0666, &b);
- assert_se(fd >= 0);
+ fd = openat_report_new(tfd, "test", O_RDWR|O_CREAT|O_EXCL, 0666, &b);
+ ASSERT_OK(fd);
fd = safe_close(fd);
- assert_se(b);
+ ASSERT_TRUE(b);
}
TEST(xopenat_full) {
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
index 48fdbba..a6ed640 100644
--- a/src/test/test-id128.c
+++ b/src/test/test-id128.c
@@ -28,31 +28,31 @@ TEST(id128) {
_cleanup_free_ char *b = NULL;
_cleanup_close_ int fd = -EBADF;
- assert_se(sd_id128_randomize(&id) == 0);
+ ASSERT_OK(sd_id128_randomize(&id));
printf("random: %s\n", sd_id128_to_string(id, t));
- assert_se(sd_id128_from_string(t, &id2) == 0);
- assert_se(sd_id128_equal(id, id2));
- assert_se(sd_id128_in_set(id, id));
- assert_se(sd_id128_in_set(id, id2));
- assert_se(sd_id128_in_set(id, id2, id));
- assert_se(sd_id128_in_set(id, ID128_WALDI, id));
- assert_se(!sd_id128_in_set(id));
- assert_se(!sd_id128_in_set(id, ID128_WALDI));
- assert_se(!sd_id128_in_set(id, ID128_WALDI, ID128_WALDI));
+ ASSERT_OK(sd_id128_from_string(t, &id2) == 0);
+ ASSERT_EQ_ID128(id, id2);
+ ASSERT_TRUE(sd_id128_in_set(id, id));
+ ASSERT_TRUE(sd_id128_in_set(id, id2));
+ ASSERT_TRUE(sd_id128_in_set(id, id2, id));
+ ASSERT_TRUE(sd_id128_in_set(id, ID128_WALDI, id));
+ ASSERT_FALSE(sd_id128_in_set(id));
+ ASSERT_FALSE(sd_id128_in_set(id, ID128_WALDI));
+ ASSERT_FALSE(sd_id128_in_set(id, ID128_WALDI, ID128_WALDI));
if (sd_booted() > 0 && sd_id128_get_machine(NULL) >= 0) {
- assert_se(sd_id128_get_machine(&id) == 0);
+ ASSERT_OK(sd_id128_get_machine(&id));
printf("machine: %s\n", sd_id128_to_string(id, t));
- assert_se(sd_id128_get_boot(&id) == 0);
+ ASSERT_OK(sd_id128_get_boot(&id));
printf("boot: %s\n", sd_id128_to_string(id, t));
}
printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t));
ASSERT_STREQ(t, STR_WALDI);
- assert_se(asprintf(&b, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 32);
+ ASSERT_EQ(asprintf(&b, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)), 32);
printf("waldi2: %s\n", b);
ASSERT_STREQ(t, b);
@@ -60,137 +60,137 @@ TEST(id128) {
ASSERT_STREQ(q, UUID_WALDI);
b = mfree(b);
- assert_se(asprintf(&b, SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 36);
+ ASSERT_EQ(asprintf(&b, SD_ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)), 36);
printf("waldi4: %s\n", b);
ASSERT_STREQ(q, b);
- assert_se(sd_id128_from_string(STR_WALDI, &id) >= 0);
- assert_se(sd_id128_equal(id, ID128_WALDI));
-
- assert_se(sd_id128_from_string(UUID_WALDI, &id) >= 0);
- assert_se(sd_id128_equal(id, ID128_WALDI));
-
- assert_se(sd_id128_from_string("", &id) < 0);
- assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f101", &id) < 0);
- assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f10-", &id) < 0);
- assert_se(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0);
- assert_se(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0);
-
- assert_se(id128_from_string_nonzero(STR_WALDI, &id) == 0);
- assert_se(id128_from_string_nonzero(STR_NULL, &id) == -ENXIO);
- assert_se(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f101", &id) < 0);
- assert_se(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f10-", &id) < 0);
- assert_se(id128_from_string_nonzero("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0);
- assert_se(id128_from_string_nonzero("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0);
-
- assert_se(id128_is_valid(STR_WALDI));
- assert_se(id128_is_valid(UUID_WALDI));
- assert_se(!id128_is_valid(""));
- assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f101"));
- assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f10-"));
- assert_se(!id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10"));
- assert_se(!id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10"));
+ ASSERT_OK(sd_id128_from_string(STR_WALDI, &id));
+ ASSERT_EQ_ID128(id, ID128_WALDI);
+
+ ASSERT_OK(sd_id128_from_string(UUID_WALDI, &id));
+ ASSERT_EQ_ID128(id, ID128_WALDI);
+
+ ASSERT_FAIL(sd_id128_from_string("", &id));
+ ASSERT_FAIL(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f101", &id));
+ ASSERT_FAIL(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f10-", &id));
+ ASSERT_FAIL(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id));
+ ASSERT_FAIL(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id));
+
+ ASSERT_OK(id128_from_string_nonzero(STR_WALDI, &id));
+ ASSERT_ERROR(id128_from_string_nonzero(STR_NULL, &id), ENXIO);
+ ASSERT_FAIL(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f101", &id));
+ ASSERT_FAIL(id128_from_string_nonzero("01020304-0506-0708-090a-0b0c0d0e0f10-", &id));
+ ASSERT_FAIL(id128_from_string_nonzero("01020304-0506-0708-090a0b0c0d0e0f10", &id));
+ ASSERT_FAIL(id128_from_string_nonzero("010203040506-0708-090a-0b0c0d0e0f10", &id));
+
+ ASSERT_TRUE(id128_is_valid(STR_WALDI));
+ ASSERT_TRUE(id128_is_valid(UUID_WALDI));
+ ASSERT_FALSE(id128_is_valid(""));
+ ASSERT_FALSE(id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f101"));
+ ASSERT_FALSE(id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f10-"));
+ ASSERT_FALSE(id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10"));
+ ASSERT_FALSE(id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10"));
fd = open_tmpfile_unlinkable(NULL, O_RDWR|O_CLOEXEC);
- assert_se(fd >= 0);
+ ASSERT_OK(fd);
/* First, write as UUID */
- assert_se(sd_id128_randomize(&id) >= 0);
- assert_se(id128_write_fd(fd, ID128_FORMAT_UUID, id) >= 0);
+ ASSERT_OK(sd_id128_randomize(&id));
+ ASSERT_OK(id128_write_fd(fd, ID128_FORMAT_UUID, id));
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EUCLEAN);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2), EUCLEAN);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK(id128_read_fd(fd, ID128_FORMAT_UUID, &id2));
+ ASSERT_EQ_ID128(id, id2);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK(id128_read_fd(fd, ID128_FORMAT_ANY, &id2));
+ ASSERT_EQ_ID128(id, id2);
/* Second, write as plain */
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
- assert_se(sd_id128_randomize(&id) >= 0);
- assert_se(id128_write_fd(fd, ID128_FORMAT_PLAIN, id) >= 0);
+ ASSERT_OK(sd_id128_randomize(&id));
+ ASSERT_OK(id128_write_fd(fd, ID128_FORMAT_PLAIN, id));
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EUCLEAN);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET) == 0);
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_UUID, &id2), EUCLEAN);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2));
+ ASSERT_EQ_ID128(id, id2);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK(id128_read_fd(fd, ID128_FORMAT_ANY, &id2));
+ ASSERT_EQ_ID128(id, id2);
/* Third, write plain without trailing newline */
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
- assert_se(sd_id128_randomize(&id) >= 0);
- assert_se(write(fd, sd_id128_to_string(id, t), 32) == 32);
+ ASSERT_OK(sd_id128_randomize(&id));
+ ASSERT_EQ(write(fd, sd_id128_to_string(id, t), 32), 32);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EUCLEAN);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_UUID, &id2), EUCLEAN);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2));
+ ASSERT_EQ_ID128(id, id2);
/* Fourth, write UUID without trailing newline */
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
- assert_se(sd_id128_randomize(&id) >= 0);
- assert_se(write(fd, sd_id128_to_uuid_string(id, q), 36) == 36);
+ ASSERT_OK(sd_id128_randomize(&id));
+ ASSERT_EQ(write(fd, sd_id128_to_uuid_string(id, q), 36), 36);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EUCLEAN);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2), EUCLEAN);
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK(id128_read_fd(fd, ID128_FORMAT_UUID, &id2));
+ ASSERT_EQ_ID128(id, id2);
/* Fifth, tests for "uninitialized" */
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
- assert_se(write(fd, "uninitialized", STRLEN("uninitialized")) == STRLEN("uninitialized"));
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -ENOPKG);
-
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
- assert_se(write(fd, "uninitialized\n", STRLEN("uninitialized\n")) == STRLEN("uninitialized\n"));
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -ENOPKG);
-
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
- assert_se(write(fd, "uninitialized\nfoo", STRLEN("uninitialized\nfoo")) == STRLEN("uninitialized\nfoo"));
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EUCLEAN);
-
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(ftruncate(fd, 0) >= 0);
- assert_se(write(fd, "uninit", STRLEN("uninit")) == STRLEN("uninit"));
- assert_se(lseek(fd, 0, SEEK_SET) == 0);
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EUCLEAN);
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
+ ASSERT_EQ(write(fd, "uninitialized", STRLEN("uninitialized")), (ssize_t) STRLEN("uninitialized"));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_ANY, NULL), ENOPKG);
+
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
+ ASSERT_EQ(write(fd, "uninitialized\n", STRLEN("uninitialized\n")), (ssize_t) STRLEN("uninitialized\n"));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_ANY, NULL), ENOPKG);
+
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
+ ASSERT_EQ(write(fd, "uninitialized\nfoo", STRLEN("uninitialized\nfoo")), (ssize_t) STRLEN("uninitialized\nfoo"));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_ANY, NULL), EUCLEAN);
+
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_OK_ERRNO(ftruncate(fd, 0));
+ ASSERT_EQ(write(fd, "uninit", STRLEN("uninit")), (ssize_t) STRLEN("uninit"));
+ ASSERT_OK_ERRNO(lseek(fd, 0, SEEK_SET));
+ ASSERT_ERROR(id128_read_fd(fd, ID128_FORMAT_ANY, NULL), EUCLEAN);
/* build/systemd-id128 -a f03daaeb1c334b43a732172944bf772e show 51df0b4bc3b04c9780e299b98ca373b8 */
- assert_se(sd_id128_get_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8),
- SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
- assert_se(sd_id128_equal(id, SD_ID128_MAKE(1d,ee,59,54,e7,5c,4d,6f,b9,6c,c6,c0,4c,a1,8a,86)));
+ ASSERT_OK(sd_id128_get_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8),
+ SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id));
+ ASSERT_EQ_ID128(id, SD_ID128_MAKE(1d,ee,59,54,e7,5c,4d,6f,b9,6c,c6,c0,4c,a1,8a,86));
if (sd_booted() > 0 && sd_id128_get_machine(NULL) >= 0) {
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
- assert_se(sd_id128_equal(id, id2));
- assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2) >= 0);
- assert_se(!sd_id128_equal(id, id2));
+ ASSERT_OK(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id));
+ ASSERT_OK(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2));
+ ASSERT_EQ_ID128(id, id2);
+ ASSERT_OK(sd_id128_get_machine_app_specific(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8), &id2));
+ ASSERT_NE_ID128(id, id2);
}
/* Check return values */
@@ -214,7 +214,7 @@ TEST(sd_id128_get_invocation) {
if (r < 0)
log_warning_errno(r, "Failed to get invocation ID, ignoring: %m");
else {
- assert(!sd_id128_equal(id, appid));
+ ASSERT_NE_ID128(id, appid);
log_info("Per-App Invocation ID: " SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(appid));
}
@@ -223,8 +223,8 @@ TEST(sd_id128_get_invocation) {
if (r < 0)
log_warning_errno(r, "Failed to get invocation ID, ignoring: %m");
else {
- assert(!sd_id128_equal(id, appid2));
- assert(!sd_id128_equal(appid, appid2));
+ ASSERT_NE_ID128(id, appid2);
+ ASSERT_NE_ID128(appid, appid2);
log_info("Per-App Invocation ID 2: " SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(appid2));
}
@@ -233,9 +233,9 @@ TEST(sd_id128_get_invocation) {
if (r < 0)
log_warning_errno(r, "Failed to get invocation ID, ignoring: %m");
else {
- assert(!sd_id128_equal(id, appid3));
- assert(sd_id128_equal(appid, appid3));
- assert(!sd_id128_equal(appid2, appid3));
+ ASSERT_NE_ID128(id, appid3);
+ ASSERT_EQ_ID128(appid, appid3);
+ ASSERT_NE_ID128(appid2, appid3);
log_info("Per-App Invocation ID 3: " SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(appid3));
}
}
@@ -256,7 +256,7 @@ TEST(benchmark_sd_id128_get_machine_app_specific) {
for (unsigned i = 0; i < iterations; i++) {
id.qwords[1] = i;
- assert_se(sd_id128_get_machine_app_specific(id, &id2) >= 0);
+ ASSERT_OK(sd_id128_get_machine_app_specific(id, &id2));
}
q = now(CLOCK_MONOTONIC) - t;
@@ -271,79 +271,79 @@ TEST(id128_at) {
sd_id128_t id, i;
tfd = mkdtemp_open(NULL, O_PATH, &t);
- assert_se(tfd >= 0);
- assert_se(mkdirat(tfd, "etc", 0755) >= 0);
- assert_se(symlinkat("etc", tfd, "etc2") >= 0);
- assert_se(symlinkat("machine-id", tfd, "etc/hoge-id") >= 0);
+ ASSERT_OK(tfd);
+ ASSERT_OK_ERRNO(mkdirat(tfd, "etc", 0755));
+ ASSERT_OK_ERRNO(symlinkat("etc", tfd, "etc2"));
+ ASSERT_OK_ERRNO(symlinkat("machine-id", tfd, "etc/hoge-id"));
- assert_se(sd_id128_randomize(&id) == 0);
+ ASSERT_OK(sd_id128_randomize(&id));
- assert_se(id128_write_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, id) >= 0);
+ ASSERT_OK(id128_write_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, id));
if (geteuid() == 0)
- assert_se(id128_write_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, id) >= 0);
+ ASSERT_OK(id128_write_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, id));
else
- assert_se(id128_write_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, id) == -EACCES);
- assert_se(unlinkat(tfd, "etc/machine-id", 0) >= 0);
- assert_se(id128_write_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, id) >= 0);
- assert_se(unlinkat(tfd, "etc/machine-id", 0) >= 0);
- assert_se(id128_write_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, id) >= 0);
- assert_se(unlinkat(tfd, "etc/machine-id", 0) >= 0);
- assert_se(id128_write_at(tfd, "etc2/hoge-id", ID128_FORMAT_PLAIN, id) >= 0);
+ ASSERT_ERROR(id128_write_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, id), EACCES);
+ ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
+ ASSERT_OK(id128_write_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, id));
+ ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
+ ASSERT_OK(id128_write_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, id));
+ ASSERT_OK_ERRNO(unlinkat(tfd, "etc/machine-id", 0));
+ ASSERT_OK(id128_write_at(tfd, "etc2/hoge-id", ID128_FORMAT_PLAIN, id));
/* id128_read_at() */
i = SD_ID128_NULL; /* Not necessary in real code, but for testing that the id is really assigned. */
- assert_se(id128_read_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read_at(tfd, "etc/machine-id", ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
i = SD_ID128_NULL;
- assert_se(id128_read_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read_at(tfd, "etc2/machine-id", ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
i = SD_ID128_NULL;
- assert_se(id128_read_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read_at(tfd, "etc/hoge-id", ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
i = SD_ID128_NULL;
- assert_se(id128_read_at(tfd, "etc2/hoge-id", ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read_at(tfd, "etc2/hoge-id", ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
/* id128_read() */
- assert_se(p = path_join(t, "/etc/machine-id"));
+ ASSERT_NOT_NULL(p = path_join(t, "/etc/machine-id"));
i = SD_ID128_NULL;
- assert_se(id128_read(p, ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read(p, ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
free(p);
- assert_se(p = path_join(t, "/etc2/machine-id"));
+ ASSERT_NOT_NULL(p = path_join(t, "/etc2/machine-id"));
i = SD_ID128_NULL;
- assert_se(id128_read(p, ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read(p, ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
free(p);
- assert_se(p = path_join(t, "/etc/hoge-id"));
+ ASSERT_NOT_NULL(p = path_join(t, "/etc/hoge-id"));
i = SD_ID128_NULL;
- assert_se(id128_read(p, ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read(p, ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
free(p);
- assert_se(p = path_join(t, "/etc2/hoge-id"));
+ ASSERT_NOT_NULL(p = path_join(t, "/etc2/hoge-id"));
i = SD_ID128_NULL;
- assert_se(id128_read(p, ID128_FORMAT_PLAIN, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_read(p, ID128_FORMAT_PLAIN, &i));
+ ASSERT_EQ_ID128(id, i);
/* id128_get_machine_at() */
i = SD_ID128_NULL;
- assert_se(id128_get_machine_at(tfd, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_get_machine_at(tfd, &i));
+ ASSERT_EQ_ID128(id, i);
/* id128_get_machine() */
i = SD_ID128_NULL;
- assert_se(id128_get_machine(t, &i) >= 0);
- assert_se(sd_id128_equal(id, i));
+ ASSERT_OK(id128_get_machine(t, &i));
+ ASSERT_EQ_ID128(id, i);
}
TEST(ID128_REFUSE_NULL) {
@@ -352,18 +352,18 @@ TEST(ID128_REFUSE_NULL) {
sd_id128_t id;
tfd = mkdtemp_open(NULL, O_PATH, &t);
- assert_se(tfd >= 0);
+ ASSERT_OK(tfd);
- assert_se(id128_write_at(tfd, "zero-id", ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, (sd_id128_t) {}) == -ENOMEDIUM);
- assert_se(unlinkat(tfd, "zero-id", 0) >= 0);
- assert_se(id128_write_at(tfd, "zero-id", ID128_FORMAT_PLAIN, (sd_id128_t) {}) >= 0);
+ ASSERT_ERROR(id128_write_at(tfd, "zero-id", ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, (sd_id128_t) {}), ENOMEDIUM);
+ ASSERT_OK_ERRNO(unlinkat(tfd, "zero-id", 0));
+ ASSERT_OK(id128_write_at(tfd, "zero-id", ID128_FORMAT_PLAIN, (sd_id128_t) {}));
- assert_se(sd_id128_randomize(&id) == 0);
- assert_se(!sd_id128_equal(id, SD_ID128_NULL));
- assert_se(id128_read_at(tfd, "zero-id", ID128_FORMAT_PLAIN, &id) >= 0);
- assert_se(sd_id128_equal(id, SD_ID128_NULL));
+ ASSERT_OK(sd_id128_randomize(&id));
+ ASSERT_NE_ID128(id, SD_ID128_NULL);
+ ASSERT_OK(id128_read_at(tfd, "zero-id", ID128_FORMAT_PLAIN, &id));
+ ASSERT_EQ_ID128(id, SD_ID128_NULL);
- assert_se(id128_read_at(tfd, "zero-id", ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, &id) == -ENOMEDIUM);
+ ASSERT_ERROR(id128_read_at(tfd, "zero-id", ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, &id), ENOMEDIUM);
}
DEFINE_TEST_MAIN(LOG_INFO);
diff --git a/src/test/test-log.c b/src/test/test-log.c
index 97eb5e0..57cab63 100644
--- a/src/test/test-log.c
+++ b/src/test/test-log.c
@@ -13,11 +13,6 @@
#include "strv.h"
#include "tests.h"
-assert_cc(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(EINVAL)));
-assert_cc(!IS_SYNTHETIC_ERRNO(EINVAL));
-assert_cc(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(0)));
-assert_cc(!IS_SYNTHETIC_ERRNO(0));
-
#define X10(x) x x x x x x x x x x
#define X100(x) X10(X10(x))
#define X1000(x) X100(X10(x))
@@ -227,6 +222,15 @@ static void test_log_prefix(void) {
int main(int argc, char* argv[]) {
test_setup_logging(LOG_DEBUG);
+ ASSERT_TRUE(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(EINVAL)));
+ ASSERT_TRUE(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(-EINVAL)));
+ assert_cc(!IS_SYNTHETIC_ERRNO(EINVAL));
+ assert_cc(!IS_SYNTHETIC_ERRNO(-EINVAL));
+ ASSERT_TRUE(IS_SYNTHETIC_ERRNO(SYNTHETIC_ERRNO(0)));
+ assert_cc(!IS_SYNTHETIC_ERRNO(0));
+ ASSERT_EQ(ERRNO_VALUE(EINVAL), EINVAL);
+ ASSERT_EQ(ERRNO_VALUE(SYNTHETIC_ERRNO(-EINVAL)), EINVAL);
+
test_assert_return_is_critical();
test_file();
diff --git a/src/test/test-macro.c b/src/test/test-macro.c
index 9e2875d..3d5b0cf 100644
--- a/src/test/test-macro.c
+++ b/src/test/test-macro.c
@@ -4,6 +4,7 @@
#include <sys/stat.h>
#include "errno-util.h"
+#include "id128-util.h"
#include "log.h"
#include "macro.h"
#include "tests.h"
@@ -1122,6 +1123,11 @@ TEST(ASSERT) {
ASSERT_SIGNAL(ASSERT_OK_ERRNO(-1), SIGABRT);
ASSERT_SIGNAL(ASSERT_OK_ERRNO(-ENOANO), SIGABRT);
+ ASSERT_FAIL(-ENOENT);
+ ASSERT_FAIL(-EPERM);
+ ASSERT_SIGNAL(ASSERT_FAIL(0), SIGABRT);
+ ASSERT_SIGNAL(ASSERT_FAIL(255), SIGABRT);
+
ASSERT_ERROR(-ENOENT, ENOENT);
ASSERT_ERROR(RET_NERRNO(mkdir("/i/will/fail/with/enoent", 666)), ENOENT);
ASSERT_SIGNAL(ASSERT_ERROR(0, ENOENT), SIGABRT);
@@ -1181,6 +1187,15 @@ TEST(ASSERT) {
ASSERT_LT(-1, 1);
ASSERT_SIGNAL(ASSERT_LT(0, 0), SIGABRT);
ASSERT_SIGNAL(ASSERT_LT(1, -1), SIGABRT);
+
+ ASSERT_EQ_ID128(SD_ID128_NULL, SD_ID128_NULL);
+ ASSERT_NE_ID128(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8),
+ SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e));
+ ASSERT_SIGNAL(
+ ASSERT_EQ_ID128(SD_ID128_MAKE(51,df,0b,4b,c3,b0,4c,97,80,e2,99,b9,8c,a3,73,b8),
+ SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e)),
+ SIGABRT);
+ ASSERT_SIGNAL(ASSERT_NE_ID128(SD_ID128_NULL, SD_ID128_NULL), SIGABRT);
}
DEFINE_TEST_MAIN(LOG_INFO);
diff --git a/src/ukify/test/pytest.ini b/src/ukify/test/pytest.ini
new file mode 100644
index 0000000..a7c58bb
--- /dev/null
+++ b/src/ukify/test/pytest.ini
@@ -0,0 +1,2 @@
+[pytest]
+tmp_path_retention_policy = failed