diff options
Diffstat (limited to 'src')
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, ¶ms->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 |