new file mode 100644
@@ -0,0 +1,58 @@
+From 6e87b78114d6f8be2e69f8ed004c7a4466494b3b Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Mon, 29 Sep 2025 11:04:09 +0800
+Subject: [PATCH] musl.h: introduce header file and add __THROW
+
+1. Introduce musl.h in preparation to hold musl related header workarounds.
+2. Define __THROW as empty to avoid compilation error.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/include/override/musl.h | 8 ++++++++
+ src/include/override/net/if.h | 2 ++
+ src/include/override/sys/mount.h | 2 ++
+ 3 files changed, 12 insertions(+)
+ create mode 100644 src/include/override/musl.h
+
+diff --git a/src/include/override/musl.h b/src/include/override/musl.h
+new file mode 100644
+index 0000000000..6d747c1005
+--- /dev/null
++++ b/src/include/override/musl.h
+@@ -0,0 +1,8 @@
++#ifndef _MUSL_H
++#define _MUSL_H 1
++
++#ifndef __THROW
++#define __THROW
++#endif
++
++#endif /* musl.h */
+diff --git a/src/include/override/net/if.h b/src/include/override/net/if.h
+index 1914b596e3..1606be0fef 100644
+--- a/src/include/override/net/if.h
++++ b/src/include/override/net/if.h
+@@ -4,6 +4,8 @@
+ #include <features.h>
+ #include <linux/if.h> /* IWYU pragma: export */
+
++#include <musl.h>
++
+ #define IF_NAMESIZE 16
+
+ extern unsigned int if_nametoindex(const char *__ifname) __THROW;
+diff --git a/src/include/override/sys/mount.h b/src/include/override/sys/mount.h
+index 33a843b8f4..1b9d00ee60 100644
+--- a/src/include/override/sys/mount.h
++++ b/src/include/override/sys/mount.h
+@@ -9,6 +9,8 @@
+ #include <stdint.h>
+ #include <sys/ioctl.h>
+
++#include <musl.h>
++
+ /* Since glibc-2.37 (774058d72942249f71d74e7f2b639f77184160a6), sys/mount.h includes linux/mount.h, and
+ * we can safely include both headers in the same source file. However, we cannot do that with older glibc.
+ * To avoid conflicts, let's not use glibc's sys/mount.h, and provide our own minimal implementation.
new file mode 100644
@@ -0,0 +1,408 @@
+From 54e9aaa98ee0593013d8badf60a62d6fb5ba255a Mon Sep 17 00:00:00 2001
+From: Alexander Kanavin <alex.kanavin@gmail.com>
+Date: Sat, 22 May 2021 20:26:24 +0200
+Subject: [PATCH] add fallback parse_printf_format implementation
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Emil Renner Berthing <systemd@esmil.dk>
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+[rebased for systemd 243]
+Signed-off-by: Scott Murray <scott.murray@konsulko.com>
+[Rebased for systemd 258]
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ meson.build | 1 +
+ src/basic/meson.build | 5 +
+ src/basic/parse-printf-format.c | 273 ++++++++++++++++++++++++++++++++
+ src/basic/parse-printf-format.h | 55 +++++++
+ src/basic/stdio-util.h | 2 +-
+ 5 files changed, 335 insertions(+), 1 deletion(-)
+ create mode 100644 src/basic/parse-printf-format.c
+ create mode 100644 src/basic/parse-printf-format.h
+
+diff --git a/meson.build b/meson.build
+index 3fbab32730..5e217a35ac 100644
+--- a/meson.build
++++ b/meson.build
+@@ -693,6 +693,7 @@ foreach header : [
+ endforeach
+
+ foreach header : [
++ 'printf.h',
+ 'sys/sdt.h',
+ 'threads.h',
+ 'valgrind/memcheck.h',
+diff --git a/src/basic/meson.build b/src/basic/meson.build
+index 79af468381..a06d0b4745 100644
+--- a/src/basic/meson.build
++++ b/src/basic/meson.build
+@@ -166,6 +166,11 @@ endforeach
+ generated_sources += generated_gperf_headers
+ basic_sources += generated_gperf_headers
+
++if conf.get('HAVE_PRINTF_H') != 1
++ basic_sources += [files('parse-printf-format.c')]
++endif
++
++
+ ############################################################
+
+ filesystem_sets_py = files('filesystem-sets.py')
+diff --git a/src/basic/parse-printf-format.c b/src/basic/parse-printf-format.c
+new file mode 100644
+index 0000000000..49437e5445
+--- /dev/null
++++ b/src/basic/parse-printf-format.c
+@@ -0,0 +1,273 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++/***
++ This file is part of systemd.
++
++ Copyright 2014 Emil Renner Berthing <systemd@esmil.dk>
++
++ With parts from the musl C library
++ Copyright 2005-2014 Rich Felker, et al.
++
++ systemd is free software; you can redistribute it and/or modify it
++ under the terms of the GNU Lesser General Public License as published by
++ the Free Software Foundation; either version 2.1 of the License, or
++ (at your option) any later version.
++
++ systemd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#include <stddef.h>
++#include <string.h>
++
++#include "parse-printf-format.h"
++
++static const char *consume_nonarg(const char *fmt)
++{
++ do {
++ if (*fmt == '\0')
++ return fmt;
++ } while (*fmt++ != '%');
++ return fmt;
++}
++
++static const char *consume_num(const char *fmt)
++{
++ for (;*fmt >= '0' && *fmt <= '9'; fmt++)
++ /* do nothing */;
++ return fmt;
++}
++
++static const char *consume_argn(const char *fmt, size_t *arg)
++{
++ const char *p = fmt;
++ size_t val = 0;
++
++ if (*p < '1' || *p > '9')
++ return fmt;
++ do {
++ val = 10*val + (*p++ - '0');
++ } while (*p >= '0' && *p <= '9');
++
++ if (*p != '$')
++ return fmt;
++ *arg = val;
++ return p+1;
++}
++
++static const char *consume_flags(const char *fmt)
++{
++ while (1) {
++ switch (*fmt) {
++ case '#':
++ case '0':
++ case '-':
++ case ' ':
++ case '+':
++ case '\'':
++ case 'I':
++ fmt++;
++ continue;
++ }
++ return fmt;
++ }
++}
++
++enum state {
++ BARE,
++ LPRE,
++ LLPRE,
++ HPRE,
++ HHPRE,
++ BIGLPRE,
++ ZTPRE,
++ JPRE,
++ STOP
++};
++
++enum type {
++ NONE,
++ PTR,
++ INT,
++ UINT,
++ ULLONG,
++ LONG,
++ ULONG,
++ SHORT,
++ USHORT,
++ CHAR,
++ UCHAR,
++ LLONG,
++ SIZET,
++ IMAX,
++ UMAX,
++ PDIFF,
++ UIPTR,
++ DBL,
++ LDBL,
++ MAXTYPE
++};
++
++static const short pa_types[MAXTYPE] = {
++ [NONE] = PA_INT,
++ [PTR] = PA_POINTER,
++ [INT] = PA_INT,
++ [UINT] = PA_INT,
++ [ULLONG] = PA_INT | PA_FLAG_LONG_LONG,
++ [LONG] = PA_INT | PA_FLAG_LONG,
++ [ULONG] = PA_INT | PA_FLAG_LONG,
++ [SHORT] = PA_INT | PA_FLAG_SHORT,
++ [USHORT] = PA_INT | PA_FLAG_SHORT,
++ [CHAR] = PA_CHAR,
++ [UCHAR] = PA_CHAR,
++ [LLONG] = PA_INT | PA_FLAG_LONG_LONG,
++ [SIZET] = PA_INT | PA_FLAG_LONG,
++ [IMAX] = PA_INT | PA_FLAG_LONG_LONG,
++ [UMAX] = PA_INT | PA_FLAG_LONG_LONG,
++ [PDIFF] = PA_INT | PA_FLAG_LONG_LONG,
++ [UIPTR] = PA_INT | PA_FLAG_LONG,
++ [DBL] = PA_DOUBLE,
++ [LDBL] = PA_DOUBLE | PA_FLAG_LONG_DOUBLE
++};
++
++#define S(x) [(x)-'A']
++#define E(x) (STOP + (x))
++
++static const unsigned char states[]['z'-'A'+1] = {
++ { /* 0: bare types */
++ S('d') = E(INT), S('i') = E(INT),
++ S('o') = E(UINT),S('u') = E(UINT),S('x') = E(UINT), S('X') = E(UINT),
++ S('e') = E(DBL), S('f') = E(DBL), S('g') = E(DBL), S('a') = E(DBL),
++ S('E') = E(DBL), S('F') = E(DBL), S('G') = E(DBL), S('A') = E(DBL),
++ S('c') = E(CHAR),S('C') = E(INT),
++ S('s') = E(PTR), S('S') = E(PTR), S('p') = E(UIPTR),S('n') = E(PTR),
++ S('m') = E(NONE),
++ S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
++ S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE
++ }, { /* 1: l-prefixed */
++ S('d') = E(LONG), S('i') = E(LONG),
++ S('o') = E(ULONG),S('u') = E(ULONG),S('x') = E(ULONG),S('X') = E(ULONG),
++ S('e') = E(DBL), S('f') = E(DBL), S('g') = E(DBL), S('a') = E(DBL),
++ S('E') = E(DBL), S('F') = E(DBL), S('G') = E(DBL), S('A') = E(DBL),
++ S('c') = E(INT), S('s') = E(PTR), S('n') = E(PTR),
++ S('l') = LLPRE
++ }, { /* 2: ll-prefixed */
++ S('d') = E(LLONG), S('i') = E(LLONG),
++ S('o') = E(ULLONG),S('u') = E(ULLONG),
++ S('x') = E(ULLONG),S('X') = E(ULLONG),
++ S('n') = E(PTR)
++ }, { /* 3: h-prefixed */
++ S('d') = E(SHORT), S('i') = E(SHORT),
++ S('o') = E(USHORT),S('u') = E(USHORT),
++ S('x') = E(USHORT),S('X') = E(USHORT),
++ S('n') = E(PTR),
++ S('h') = HHPRE
++ }, { /* 4: hh-prefixed */
++ S('d') = E(CHAR), S('i') = E(CHAR),
++ S('o') = E(UCHAR),S('u') = E(UCHAR),
++ S('x') = E(UCHAR),S('X') = E(UCHAR),
++ S('n') = E(PTR)
++ }, { /* 5: L-prefixed */
++ S('e') = E(LDBL),S('f') = E(LDBL),S('g') = E(LDBL), S('a') = E(LDBL),
++ S('E') = E(LDBL),S('F') = E(LDBL),S('G') = E(LDBL), S('A') = E(LDBL),
++ S('n') = E(PTR)
++ }, { /* 6: z- or t-prefixed (assumed to be same size) */
++ S('d') = E(PDIFF),S('i') = E(PDIFF),
++ S('o') = E(SIZET),S('u') = E(SIZET),
++ S('x') = E(SIZET),S('X') = E(SIZET),
++ S('n') = E(PTR)
++ }, { /* 7: j-prefixed */
++ S('d') = E(IMAX), S('i') = E(IMAX),
++ S('o') = E(UMAX), S('u') = E(UMAX),
++ S('x') = E(UMAX), S('X') = E(UMAX),
++ S('n') = E(PTR)
++ }
++};
++
++size_t parse_printf_format(const char *fmt, size_t n, int *types)
++{
++ size_t i = 0;
++ size_t last = 0;
++
++ memset(types, 0, n);
++
++ while (1) {
++ size_t arg;
++ unsigned int state;
++
++ fmt = consume_nonarg(fmt);
++ if (*fmt == '\0')
++ break;
++ if (*fmt == '%') {
++ fmt++;
++ continue;
++ }
++ arg = 0;
++ fmt = consume_argn(fmt, &arg);
++ /* flags */
++ fmt = consume_flags(fmt);
++ /* width */
++ if (*fmt == '*') {
++ size_t warg = 0;
++ fmt = consume_argn(fmt+1, &warg);
++ if (warg == 0)
++ warg = ++i;
++ if (warg > last)
++ last = warg;
++ if (warg <= n && types[warg-1] == NONE)
++ types[warg-1] = INT;
++ } else
++ fmt = consume_num(fmt);
++ /* precision */
++ if (*fmt == '.') {
++ fmt++;
++ if (*fmt == '*') {
++ size_t parg = 0;
++ fmt = consume_argn(fmt+1, &parg);
++ if (parg == 0)
++ parg = ++i;
++ if (parg > last)
++ last = parg;
++ if (parg <= n && types[parg-1] == NONE)
++ types[parg-1] = INT;
++ } else {
++ if (*fmt == '-')
++ fmt++;
++ fmt = consume_num(fmt);
++ }
++ }
++ /* length modifier and conversion specifier */
++ state = BARE;
++ do {
++ unsigned char c = *fmt++;
++
++ if (c < 'A' || c > 'z')
++ continue;
++ state = states[state]S(c);
++ if (state == 0)
++ continue;
++ } while (state < STOP);
++
++ if (state == E(NONE))
++ continue;
++
++ if (arg == 0)
++ arg = ++i;
++ if (arg > last)
++ last = arg;
++ if (arg <= n)
++ types[arg-1] = state - STOP;
++ }
++
++ if (last > n)
++ last = n;
++ for (i = 0; i < last; i++)
++ types[i] = pa_types[types[i]];
++
++ return last;
++}
+diff --git a/src/basic/parse-printf-format.h b/src/basic/parse-printf-format.h
+new file mode 100644
+index 0000000000..1d4e8ac914
+--- /dev/null
++++ b/src/basic/parse-printf-format.h
+@@ -0,0 +1,55 @@
++/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
++
++/***
++ This file is part of systemd.
++
++ Copyright 2014 Emil Renner Berthing <systemd@esmil.dk>
++
++ With parts from the GNU C Library
++ Copyright 1991-2014 Free Software Foundation, Inc.
++
++ systemd is free software; you can redistribute it and/or modify it
++ under the terms of the GNU Lesser General Public License as published by
++ the Free Software Foundation; either version 2.1 of the License, or
++ (at your option) any later version.
++
++ systemd is distributed in the hope that it will be useful, but
++ WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public License
++ along with systemd; If not, see <http://www.gnu.org/licenses/>.
++***/
++
++#pragma once
++
++#if HAVE_PRINTF_H
++#include <printf.h>
++#else
++
++#include <stddef.h>
++
++enum { /* C type: */
++ PA_INT, /* int */
++ PA_CHAR, /* int, cast to char */
++ PA_WCHAR, /* wide char */
++ PA_STRING, /* const char *, a '\0'-terminated string */
++ PA_WSTRING, /* const wchar_t *, wide character string */
++ PA_POINTER, /* void * */
++ PA_FLOAT, /* float */
++ PA_DOUBLE, /* double */
++ PA_LAST
++};
++
++/* Flag bits that can be set in a type returned by `parse_printf_format'. */
++#define PA_FLAG_MASK 0xff00
++#define PA_FLAG_LONG_LONG (1 << 8)
++#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
++#define PA_FLAG_LONG (1 << 9)
++#define PA_FLAG_SHORT (1 << 10)
++#define PA_FLAG_PTR (1 << 11)
++
++size_t parse_printf_format(const char *fmt, size_t n, int *types);
++
++#endif /* HAVE_PRINTF_H */
+diff --git a/src/basic/stdio-util.h b/src/basic/stdio-util.h
+index 052087ce15..62a6b6b316 100644
+--- a/src/basic/stdio-util.h
++++ b/src/basic/stdio-util.h
+@@ -1,10 +1,10 @@
+ /* SPDX-License-Identifier: LGPL-2.1-or-later */
+ #pragma once
+
+-#include <printf.h>
+ #include <stdio.h>
+
+ #include "forward.h"
++#include "parse-printf-format.h"
+
+ _printf_(3, 4)
+ static inline char* snprintf_ok(char *buf, size_t len, const char *format, ...) {
new file mode 100644
@@ -0,0 +1,114 @@
+From 4b9a7d88843227a317e7d87b13dab16ece835449 Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Mon, 29 Sep 2025 12:52:35 +0800
+Subject: [PATCH] Make mallinfo related contents glibc specific
+
+musl does not define mallinfo related contents.
+And systemd has removed support for checking, and has assumed it
+always exists[1], so these contents need to made glibc specific.
+
+[1] https://github.com/systemd/systemd/commit/abb99d3168259136187f81e0f701cda712ffd78d
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/include/override/malloc.h | 3 ++-
+ src/libsystemd/sd-event/sd-event.c | 14 ++++++++++----
+ src/shared/selinux-util.c | 10 +++++++++-
+ 3 files changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/src/include/override/malloc.h b/src/include/override/malloc.h
+index d0080b6cbc..c129713831 100644
+--- a/src/include/override/malloc.h
++++ b/src/include/override/malloc.h
+@@ -2,7 +2,7 @@
+ #pragma once
+
+ #include_next <malloc.h>
+-
++#ifdef __GLIBC__
+ #if !HAVE_MALLINFO2
+ struct mallinfo2 {
+ size_t arena; /* non-mmapped space allocated from system */
+@@ -37,3 +37,4 @@ static inline struct mallinfo2 mallinfo2(void) {
+ };
+ }
+ #endif
++#endif
+diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
+index 6cb496c541..79d574f5a9 100644
+--- a/src/libsystemd/sd-event/sd-event.c
++++ b/src/libsystemd/sd-event/sd-event.c
+@@ -1867,9 +1867,9 @@ _public_ int sd_event_trim_memory(void) {
+ * NULL callback parameter. */
+
+ log_debug("Memory pressure event, trimming malloc() memory.");
+-
++#ifdef __GLIBC__
+ struct mallinfo2 before_mallinfo = mallinfo2();
+-
++#endif
+ usec_t before_timestamp = now(CLOCK_MONOTONIC);
+ hashmap_trim_pools();
+ r = malloc_trim(0);
+@@ -1881,7 +1881,7 @@ _public_ int sd_event_trim_memory(void) {
+ log_debug("Couldn't trim any memory.");
+
+ usec_t period = after_timestamp - before_timestamp;
+-
++#ifdef __GLIBC__
+ struct mallinfo2 after_mallinfo = mallinfo2();
+ size_t l = LESS_BY(before_mallinfo.hblkhd, after_mallinfo.hblkhd) +
+ LESS_BY(before_mallinfo.arena, after_mallinfo.arena);
+@@ -1892,7 +1892,13 @@ _public_ int sd_event_trim_memory(void) {
+ LOG_MESSAGE_ID(SD_MESSAGE_MEMORY_TRIM_STR),
+ LOG_ITEM("TRIMMED_BYTES=%zu", l),
+ LOG_ITEM("TRIMMED_USEC=" USEC_FMT, period));
+-
++#else
++ log_struct(LOG_DEBUG,
++ LOG_MESSAGE("Memory trimming took %s",
++ FORMAT_TIMESPAN(period, 0)),
++ LOG_MESSAGE_ID(SD_MESSAGE_MEMORY_TRIM_STR),
++ LOG_ITEM("TRIMMED_USEC=" USEC_FMT, period));
++#endif
+ return 0;
+ }
+
+diff --git a/src/shared/selinux-util.c b/src/shared/selinux-util.c
+index f7c4c7d2f8..b669475180 100644
+--- a/src/shared/selinux-util.c
++++ b/src/shared/selinux-util.c
+@@ -91,10 +91,13 @@ static int open_label_db(void) {
+ struct selabel_handle *hnd;
+ /* Avoid maybe-uninitialized false positives */
+ usec_t before_timestamp = USEC_INFINITY, after_timestamp = USEC_INFINITY;
++#ifdef __GLIBC__
+ struct mallinfo2 before_mallinfo = {};
+-
++#endif
+ if (DEBUG_LOGGING) {
++#ifdef __GLIBC__
+ before_mallinfo = mallinfo2();
++#endif
+ before_timestamp = now(CLOCK_MONOTONIC);
+ }
+
+@@ -104,11 +107,16 @@ static int open_label_db(void) {
+
+ if (DEBUG_LOGGING) {
+ after_timestamp = now(CLOCK_MONOTONIC);
++#ifdef __GLIBC__
+ struct mallinfo2 after_mallinfo = mallinfo2();
+ size_t l = LESS_BY(after_mallinfo.uordblks, before_mallinfo.uordblks);
+ log_debug("Successfully loaded SELinux database in %s, size on heap is %zuK.",
+ FORMAT_TIMESPAN(after_timestamp - before_timestamp, 0),
+ DIV_ROUND_UP(l, 1024));
++#else
++ log_debug("Successfully loaded SELinux database in %s",
++ FORMAT_TIMESPAN(after_timestamp - before_timestamp, 0));
++#endif
+ }
+
+ /* release memory after measurement */
new file mode 100644
@@ -0,0 +1,40 @@
+From c79dcf90047fb13db488249aded3a59a00ed396d Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Mon, 29 Sep 2025 14:14:44 +0800
+Subject: [PATCH] add src/include/override/sys/prctl.h to avoid redefinition
+ error
+
+The linux/prctl.h has all the needed macros, what we need is the
+prctl function definition. This avoids error of redefinition.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/include/override/sys/prctl.h | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+ create mode 100644 src/include/override/sys/prctl.h
+
+diff --git a/src/include/override/sys/prctl.h b/src/include/override/sys/prctl.h
+new file mode 100644
+index 0000000000..20468bd30f
+--- /dev/null
++++ b/src/include/override/sys/prctl.h
+@@ -0,0 +1,17 @@
++#ifndef _SYS_PRCTL_H
++#define _SYS_PRCTL_H
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#include <stdint.h>
++#include <linux/prctl.h>
++
++int prctl (int, ...);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
new file mode 100644
@@ -0,0 +1,73 @@
+From 74c5a57b48d12b31474974a1936a9f8495d2aa55 Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Tue, 10 Jul 2018 15:40:17 +0800
+Subject: [PATCH] distinguish XSI-compliant strerror_r from GNU-specific
+ strerror_r
+
+XSI-compliant strerror_r and GNU-specific strerror_r are different.
+
+ int strerror_r(int errnum, char *buf, size_t buflen);
+ /* XSI-compliant */
+
+ char *strerror_r(int errnum, char *buf, size_t buflen);
+ /* GNU-specific */
+
+We need to distinguish between them. Otherwise, we'll get an int value
+assigned to (char *) variable, resulting in segment fault.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/libsystemd/sd-bus/bus-error.c | 11 ++++++++++-
+ src/libsystemd/sd-journal/journal-send.c | 5 +++++
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/src/libsystemd/sd-bus/bus-error.c b/src/libsystemd/sd-bus/bus-error.c
+index bc0164c1b4..e69ffe4f75 100644
+--- a/src/libsystemd/sd-bus/bus-error.c
++++ b/src/libsystemd/sd-bus/bus-error.c
+@@ -400,7 +400,12 @@ static void bus_error_strerror(sd_bus_error *e, int error) {
+ return;
+
+ errno = 0;
++#ifndef __GLIBC__
++ strerror_r(error, m, k);
++ x = m;
++#else
+ x = strerror_r(error, m, k);
++#endif
+ if (errno == ERANGE || strlen(x) >= k - 1) {
+ free(m);
+ k *= 2;
+@@ -585,8 +590,12 @@ const char* _bus_error_message(const sd_bus_error *e, int error, char buf[static
+
+ if (e && e->message)
+ return e->message;
+-
++#ifndef __GLIBC__
++ strerror_r(ABS(error), buf, ERRNO_BUF_LEN);
++ return buf;
++#else
+ return strerror_r(ABS(error), buf, ERRNO_BUF_LEN);
++#endif
+ }
+
+ static bool map_ok(const sd_bus_error_map *map) {
+diff --git a/src/libsystemd/sd-journal/journal-send.c b/src/libsystemd/sd-journal/journal-send.c
+index e838e7e0d7..28b6e014c0 100644
+--- a/src/libsystemd/sd-journal/journal-send.c
++++ b/src/libsystemd/sd-journal/journal-send.c
+@@ -338,7 +338,12 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove
+ char* j;
+
+ errno = 0;
++#ifndef __GLIBC__
++ strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k);
++ j = buffer + 8 + k;
++#else
+ j = strerror_r(_saved_errno_, buffer + 8 + k, n - 8 - k);
++#endif
+ if (errno == 0) {
+ char error[STRLEN("ERRNO=") + DECIMAL_STR_MAX(int) + 1];
+
new file mode 100644
@@ -0,0 +1,41 @@
+From 0583caaa2ac357bf79dcf08f28ab6776521beae0 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Mon, 23 Jan 2023 23:39:46 -0800
+Subject: [PATCH] errno-util: Make STRERROR portable for musl
+
+Sadly, systemd has decided to use yet another GNU extention in a macro
+lets make this such that we can use XSI compliant strerror_r() for
+non-glibc hosts
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+Rebased for v258
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/basic/errno-util.h | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/src/basic/errno-util.h b/src/basic/errno-util.h
+index 5fe337cfb1..dee34167cb 100644
+--- a/src/basic/errno-util.h
++++ b/src/basic/errno-util.h
+@@ -13,8 +13,16 @@
+ * https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks
+ *
+ * Note that we use the GNU variant of strerror_r() here. */
+-#define STRERROR(errnum) strerror_r(ABS(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN)
++static inline const char * STRERROR(int errnum);
+
++static inline const char * STRERROR(int errnum) {
++#ifdef __GLIBC__
++ return strerror_r(ABS(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN);
++#else
++ static __thread char buf[ERRNO_BUF_LEN];
++ return strerror_r(ABS(errnum), buf, ERRNO_BUF_LEN) ? "unknown error" : buf;
++#endif
++}
+ /* A helper to print an error message or message for functions that return 0 on EOF.
+ * Note that we can't use ({ … }) to define a temporary variable, so errnum is
+ * evaluated twice. */
new file mode 100644
@@ -0,0 +1,37 @@
+From 72d27e8d350033d6bfc9fe488d25442baba157fa Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Mon, 29 Sep 2025 14:41:52 +0800
+Subject: [PATCH] src/basic/format-util.h: define RLIM_FMT to fit musl's rlim_t
+ definition
+
+musl always defines rlim_t to be "unsigned long long".
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/basic/format-util.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/src/basic/format-util.h b/src/basic/format-util.h
+index e42f788ce6..9275f9615d 100644
+--- a/src/basic/format-util.h
++++ b/src/basic/format-util.h
+@@ -39,6 +39,7 @@ assert_cc(sizeof(gid_t) == sizeof(uint32_t));
+ # error Unknown timex member size
+ #endif
+
++#ifdef __GLIBC__
+ #if SIZEOF_RLIM_T == 8
+ # define RLIM_FMT "%" PRIu64
+ #elif SIZEOF_RLIM_T == 4
+@@ -46,6 +47,9 @@ assert_cc(sizeof(gid_t) == sizeof(uint32_t));
+ #else
+ # error Unknown rlim_t size
+ #endif
++#else
++#define RLIM_FMT "%llu"
++#endif
+
+ #if SIZEOF_DEV_T == 8
+ # define DEV_FMT "%" PRIu64
new file mode 100644
@@ -0,0 +1,38 @@
+From c194d40309fc85e36145f1dec0ff559a5f2ab14d Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Mon, 29 Sep 2025 14:49:13 +0800
+Subject: [PATCH] src/include/override/malloc.h: define dummy
+ malloc_trim/malloc_info for musl
+
+For malloc_trim:
+As we're not releasing any stack, just return 0 to match the
+malloc_trim's meaning in glibc.
+
+For malloc_info:
+There's no real malloc_info implementation in musl, define a dummy
+one which always return -1 to indicate error.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/include/override/malloc.h | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/src/include/override/malloc.h b/src/include/override/malloc.h
+index c129713831..0b09bf6de6 100644
+--- a/src/include/override/malloc.h
++++ b/src/include/override/malloc.h
+@@ -37,4 +37,12 @@ static inline struct mallinfo2 mallinfo2(void) {
+ };
+ }
+ #endif
++#else
++#include <stdio.h>
++static inline int malloc_trim(size_t s) {
++ return 0;
++}
++static inline int malloc_info(int options, FILE *stream) {
++ return -1;
++}
+ #endif
new file mode 100644
@@ -0,0 +1,43 @@
+From af05589f4de589c07e00f1b755172bccf09c76bd Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Mon, 29 Sep 2025 14:59:27 +0800
+Subject: [PATCH] src/shared/condition.c: avoid using glibc ConditionVersion
+
+The ConditionVersion on glibc is glibc specific.
+And musl does not export programming interface to get its version.
+So it cannot be extended to musl.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/shared/condition.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/shared/condition.c b/src/shared/condition.c
+index b09eff1bfb..4899bd6c39 100644
+--- a/src/shared/condition.c
++++ b/src/shared/condition.c
+@@ -2,7 +2,9 @@
+
+ #include <fcntl.h>
+ #include <fnmatch.h>
++#ifdef __GLIBC__
+ #include <gnu/libc-version.h>
++#endif
+ #include <sys/stat.h>
+ #include <sys/utsname.h>
+ #include <time.h>
+@@ -254,10 +256,10 @@ static int condition_test_version(Condition *c, char **env) {
+
+ if (streq(word, "systemd"))
+ return condition_test_version_cmp(p, STRINGIFY(PROJECT_VERSION));
+-
++#ifdef __GLIBC__
+ if (streq(word, "glibc"))
+ return condition_test_version_cmp(p, gnu_get_libc_version());
+-
++#endif
+ /* if no predicate has been set, default to "kernel" and use the whole parameter as condition */
+ if (!streq(word, "kernel"))
+ p = c->parameter;
new file mode 100644
@@ -0,0 +1,28 @@
+From 3382fc90cbd6dddb265a1621736004c1cd4f37e7 Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Wed, 3 Jul 2024 07:18:42 -0700
+Subject: [PATCH] build-path.c: avoid boot time segfault for musl
+
+This function, at runtime, should return -ENOEXEC. For musl, it
+somehow segfaults. I think it's related to getauxval, but it's
+really does not matter, just return -ENOEXEC.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/basic/build-path.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/basic/build-path.c b/src/basic/build-path.c
+index 577ff72bce..3a7876798c 100644
+--- a/src/basic/build-path.c
++++ b/src/basic/build-path.c
+@@ -152,6 +152,7 @@ int get_build_exec_dir(char **ret) {
+ */
+
+ static int runpath_cached = -ERRNO_MAX-1;
++ return -ENOEXEC;
+ if (runpath_cached == -ERRNO_MAX-1) {
+ const char *runpath = NULL;
+
new file mode 100644
@@ -0,0 +1,172 @@
+From b649e0902e72d15452e05778613a59b512bf0ccc Mon Sep 17 00:00:00 2001
+From: Alex Kiernan <alex.kiernan@gmail.com>
+Date: Tue, 10 Mar 2020 11:05:20 +0000
+Subject: [PATCH] Handle missing gshadow for musl
+
+gshadow usage is now present in the userdb code. Mask all uses of it to
+allow compilation on musl
+
+Upstream-Status: Inappropriate [musl specific]
+Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com>
+[Rebased for v247]
+Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
+[Rebased for v258]
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/include/override/gshadow.h | 10 ++++++++++
+ src/shared/user-record-nss.c | 20 ++++++++++++++++++++
+ src/shared/userdb.c | 7 ++++++-
+ 3 files changed, 36 insertions(+), 1 deletion(-)
+ create mode 100644 src/include/override/gshadow.h
+
+diff --git a/src/include/override/gshadow.h b/src/include/override/gshadow.h
+new file mode 100644
+index 0000000000..568a9bb2d9
+--- /dev/null
++++ b/src/include/override/gshadow.h
+@@ -0,0 +1,10 @@
++#ifndef _GSHADOW_H
++#define _GSHADOW_H 1
++
++#if ENABLE_GSHADOW
++#include_next <gshadow.h>
++#else
++struct sgrp;
++#endif
++
++#endif /* gshadow.h */
+diff --git a/src/shared/user-record-nss.c b/src/shared/user-record-nss.c
+index 10a5a75e9f..24db7c953d 100644
+--- a/src/shared/user-record-nss.c
++++ b/src/shared/user-record-nss.c
+@@ -296,8 +296,10 @@ int nss_group_to_group_record(
+ if (isempty(grp->gr_name))
+ return -EINVAL;
+
++#if ENABLE_GSHADOW
+ if (sgrp && !streq_ptr(sgrp->sg_namp, grp->gr_name))
+ return -EINVAL;
++#endif
+
+ g = group_record_new();
+ if (!g)
+@@ -313,6 +315,7 @@ int nss_group_to_group_record(
+
+ g->gid = grp->gr_gid;
+
++#if ENABLE_GSHADOW
+ if (sgrp) {
+ if (looks_like_hashed_password(utf8_only(sgrp->sg_passwd))) {
+ g->hashed_password = strv_new(sgrp->sg_passwd);
+@@ -328,6 +331,7 @@ int nss_group_to_group_record(
+ if (r < 0)
+ return r;
+ }
++#endif
+
+ r = sd_json_buildo(
+ &g->json,
+@@ -355,6 +359,7 @@ int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **re
+ assert(ret_sgrp);
+ assert(ret_buffer);
+
++#if ENABLE_GSHADOW
+ for (;;) {
+ _cleanup_free_ char *buf = NULL;
+ struct sgrp sgrp = {}, *result = NULL;
+@@ -383,6 +388,9 @@ int nss_sgrp_for_group(const struct group *grp, struct sgrp *ret_sgrp, char **re
+ buflen *= 2;
+ buf = mfree(buf);
+ }
++#else
++ return -ESRCH;
++#endif
+ }
+
+ int nss_group_record_by_name(
+@@ -393,7 +401,9 @@ int nss_group_record_by_name(
+ _cleanup_free_ char *sbuf = NULL;
+ _cleanup_free_ struct group *result = NULL;
+ bool incomplete = false;
++#if ENABLE_GSHADOW
+ struct sgrp sgrp, *sresult = NULL;
++#endif
+ int r;
+
+ assert(name);
+@@ -402,6 +412,7 @@ int nss_group_record_by_name(
+ if (r < 0)
+ return r;
+
++#if ENABLE_GSHADOW
+ if (with_shadow) {
+ r = nss_sgrp_for_group(result, &sgrp, &sbuf);
+ if (r < 0) {
+@@ -413,6 +424,9 @@ int nss_group_record_by_name(
+ incomplete = true;
+
+ r = nss_group_to_group_record(result, sresult, ret);
++#else
++ r = nss_group_to_group_record(result, NULL, ret);
++#endif
+ if (r < 0)
+ return r;
+
+@@ -429,13 +443,16 @@ int nss_group_record_by_gid(
+ _cleanup_free_ char *sbuf = NULL;
+ _cleanup_free_ struct group *result = NULL;
+ bool incomplete = false;
++#if ENABLE_GSHADOW
+ struct sgrp sgrp, *sresult = NULL;
++#endif
+ int r;
+
+ r = getgrgid_malloc(gid, &result);
+ if (r < 0)
+ return r;
+
++#if ENABLE_GSHADOW
+ if (with_shadow) {
+ r = nss_sgrp_for_group(result, &sgrp, &sbuf);
+ if (r < 0) {
+@@ -447,6 +464,9 @@ int nss_group_record_by_gid(
+ incomplete = true;
+
+ r = nss_group_to_group_record(result, sresult, ret);
++#else
++ r = nss_group_to_group_record(result, NULL, ret);
++#endif
+ if (r < 0)
+ return r;
+
+diff --git a/src/shared/userdb.c b/src/shared/userdb.c
+index 49850ff216..f4217c0971 100644
+--- a/src/shared/userdb.c
++++ b/src/shared/userdb.c
+@@ -1551,13 +1551,15 @@ static int groupdb_iterator_get_one(UserDBIterator *iterator, GroupRecord **ret)
+ if (gr) {
+ _cleanup_free_ char *buffer = NULL;
+ bool incomplete = false;
++#if ENABLE_GSHADOW
+ struct sgrp sgrp;
+-
++#endif
+ if (streq_ptr(gr->gr_name, "root"))
+ iterator->synthesize_root = false;
+ if (gr->gr_gid == GID_NOBODY)
+ iterator->synthesize_nobody = false;
+
++#if ENABLE_GSHADOW
+ if (!FLAGS_SET(iterator->flags, USERDB_SUPPRESS_SHADOW)) {
+ r = nss_sgrp_for_group(gr, &sgrp, &buffer);
+ if (r < 0) {
+@@ -1570,6 +1572,9 @@ static int groupdb_iterator_get_one(UserDBIterator *iterator, GroupRecord **ret)
+ }
+
+ r = nss_group_to_group_record(gr, r >= 0 ? &sgrp : NULL, ret);
++#else
++ r = nss_group_to_group_record(gr, NULL, ret);
++#endif
+ if (r < 0)
+ return r;
+
new file mode 100644
@@ -0,0 +1,32 @@
+From 6e6b23fff3a68502edc7e8d748999f3433d3d8da Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Thu, 9 Oct 2025 15:19:09 +0800
+Subject: [PATCH] Avoid sequence-point error
+
+See https://www.openwall.com/lists/musl/2025/09/30/4
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/shared/cpu-set-util.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/shared/cpu-set-util.c b/src/shared/cpu-set-util.c
+index 7a155c12d4..a9c57fc31c 100644
+--- a/src/shared/cpu-set-util.c
++++ b/src/shared/cpu-set-util.c
+@@ -97,9 +97,11 @@ char* cpu_set_to_mask_string(const CPUSet *c) {
+ for (size_t i = c->allocated * 8; i > 0; ) {
+ uint32_t m = 0;
+
+- for (int j = (i % 32 ?: 32) - 1; j >= 0; j--)
+- if (CPU_ISSET_S(--i, c->allocated, c->set))
++ for (int j = (i % 32 ?: 32) - 1; j >= 0; j--) {
++ --i;
++ if (CPU_ISSET_S(i, c->allocated, c->set))
+ SET_BIT(m, j);
++ }
+
+ if (!found_nonzero) {
+ if (m == 0)
new file mode 100644
@@ -0,0 +1,406 @@
+From 78b1b1be3b9930e3076683159a7386e4b325e936 Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Mon, 13 Oct 2025 17:07:57 +0800
+Subject: [PATCH] Fix the segfault for glob related codes and define dummy
+ macros
+
+systemd switches to use its own free function to free gl_pathv
+located by glob() function. This causes segfault error for musl.
+
+The backtrace is like below:
+get_meta (p=p@entry=0x7ffff7b39fa8 "/proc/sys/net/ipv4/conf/all/rp_filter")
+ at /usr/src/debug/musl/1.2.5+git/src/malloc/mallocng/meta.h:131
+ 131 assert(!((uintptr_t)p & 15));
+
+Why so? Because it's expected that people use globfree to do the memory
+freeing work. Invoking free on gl_pathv[*] is not freeing the correct
+memory address.
+
+The key line in musl's globfree is as below:
+ free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
+
+So we can see the addree is not gl_pathv[*], it's
+gl_pathv[*] - offsetof(struct match, name).
+
+To address this issue, revert the following codes:
+1. Revert "glob-util: rework safe_glob()"
+ This reverts commit 2a5f950e5643a74bef70b1c3c46ec33ad0e3fd41.
+2. Revert "glob-util: drop unused _cleanup_globfree_"
+ This reverts commit f117272f6645fc2fe9751898770603ed07d15cea.
+
+There is no functional change.
+
+Also, define dummy macros to make things compile for musl.
+
+Note:
+If systemd later adopts some dramatic change for glob, we might
+need to adopt other methods instead of doing the revert. In this
+version, reverting is prefered because there is NO functional change.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ src/basic/glob-util.c | 96 ++++++++++++++++++-------------------
+ src/basic/glob-util.h | 12 ++---
+ src/core/exec-credential.c | 6 +--
+ src/core/execute.c | 8 ++--
+ src/include/override/glob.h | 6 +++
+ src/test/test-glob-util.c | 27 ++++++-----
+ src/tmpfiles/tmpfiles.c | 20 +++++---
+ 7 files changed, 95 insertions(+), 80 deletions(-)
+ create mode 100644 src/include/override/glob.h
+
+diff --git a/src/basic/glob-util.c b/src/basic/glob-util.c
+index 5843ef088f..a9c62151af 100644
+--- a/src/basic/glob-util.c
++++ b/src/basic/glob-util.c
+@@ -6,83 +6,81 @@
+ #include "dirent-util.h"
+ #include "errno-util.h"
+ #include "glob-util.h"
++#include "log.h"
+ #include "string-util.h"
+ #include "strv.h"
+
+-DEFINE_TRIVIAL_DESTRUCTOR(closedir_wrapper, void, closedir);
+-
+-int safe_glob_full(const char *path, int flags, opendir_t opendir_func, char ***ret) {
+- _cleanup_(globfree) glob_t g = {
+- .gl_closedir = closedir_wrapper,
+- .gl_readdir = (struct dirent* (*)(void *)) readdir_no_dot,
+- .gl_opendir = (void* (*)(const char *)) (opendir_func ?: opendir),
+- .gl_lstat = lstat,
+- .gl_stat = stat,
+- };
+- int r;
+-
+- assert(path);
++static void closedir_wrapper(void* v) {
++ (void) closedir(v);
++}
+
++int safe_glob(const char *path, int flags, glob_t *pglob) {
++ int k;
++
++ /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
++ assert(!(flags & GLOB_ALTDIRFUNC));
++#ifdef __GLIBC__
++ if (!pglob->gl_closedir)
++ pglob->gl_closedir = closedir_wrapper;
++ if (!pglob->gl_readdir)
++ pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
++ if (!pglob->gl_opendir)
++ pglob->gl_opendir = (void *(*)(const char *)) opendir;
++ if (!pglob->gl_lstat)
++ pglob->gl_lstat = lstat;
++ if (!pglob->gl_stat)
++ pglob->gl_stat = stat;
++#endif
+ errno = 0;
+- r = glob(path, flags | GLOB_ALTDIRFUNC, NULL, &g);
+- if (r == GLOB_NOMATCH)
++ k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
++ if (k == GLOB_NOMATCH)
+ return -ENOENT;
+- if (r == GLOB_NOSPACE)
++ if (k == GLOB_NOSPACE)
+ return -ENOMEM;
+- if (r != 0)
++ if (k != 0)
+ return errno_or_else(EIO);
+-
+- if (strv_isempty(g.gl_pathv))
++ if (strv_isempty(pglob->gl_pathv))
+ return -ENOENT;
+
+- if (ret) {
+- *ret = g.gl_pathv;
+- TAKE_STRUCT(g); /* To avoid the result being freed. */
+- }
+-
+ return 0;
+ }
+
+-int glob_first(const char *path, char **ret) {
+- _cleanup_strv_free_ char **v = NULL;
+- int r;
++int glob_first(const char *path, char **ret_first) {
++ _cleanup_globfree_ glob_t g = {};
++ int k;
+
+ assert(path);
+
+- r = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &v);
+- if (r == -ENOENT) {
+- if (ret)
+- *ret = NULL;
++ k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
++ if (k == -ENOENT) {
++ if (ret_first)
++ *ret_first = NULL;
+ return false;
+ }
+- if (r < 0)
+- return r;
+-
+- assert(!strv_isempty(v));
++ if (k < 0)
++ return k;
+
+- if (ret) {
+- /* Free all results except for the first one. */
+- STRV_FOREACH(p, strv_skip(v, 1))
+- *p = mfree(*p);
++ if (ret_first) {
++ assert(g.gl_pathv && g.gl_pathv[0]);
+
+- /* Then, take the first result. */
+- *ret = TAKE_PTR(*v);
++ char *first = strdup(g.gl_pathv[0]);
++ if (!first)
++ return log_oom_debug();
++ *ret_first = first;
+ }
+
+ return true;
+ }
+
+ int glob_extend(char ***strv, const char *path, int flags) {
+- char **v;
+- int r;
+-
+- assert(path);
++ _cleanup_globfree_ glob_t g = {};
++ int k;
+
+- r = safe_glob(path, GLOB_NOSORT|GLOB_BRACE|flags, &v);
+- if (r < 0)
+- return r;
++ k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE|flags, &g);
++ if (k < 0)
++ return k;
+
+- return strv_extend_strv_consume(strv, v, /* filter_duplicates = */ false);
++ return strv_extend_strv(strv, g.gl_pathv, false);
+ }
+
+ int glob_non_glob_prefix(const char *path, char **ret) {
+diff --git a/src/basic/glob-util.h b/src/basic/glob-util.h
+index ea3e869319..4fa23f5048 100644
+--- a/src/basic/glob-util.h
++++ b/src/basic/glob-util.h
+@@ -5,18 +5,16 @@
+
+ #include "forward.h"
+
+-typedef DIR* (*opendir_t)(const char *);
+-
+-int safe_glob_full(const char *path, int flags, opendir_t opendir_func, char ***ret);
+-static inline int safe_glob(const char *path, int flags, char ***ret) {
+- return safe_glob_full(path, flags, NULL, ret);
+-}
++/* Note: this function modifies pglob to set various functions. */
++int safe_glob(const char *path, int flags, glob_t *pglob);
+
+ /* Note: which match is returned depends on the implementation/system and not guaranteed to be stable */
+-int glob_first(const char *path, char **ret);
++int glob_first(const char *path, char **ret_first);
+ #define glob_exists(path) glob_first(path, NULL)
+ int glob_extend(char ***strv, const char *path, int flags);
+
+ int glob_non_glob_prefix(const char *path, char **ret);
+
++#define _cleanup_globfree_ _cleanup_(globfree)
++
+ bool string_is_glob(const char *p) _pure_;
+diff --git a/src/core/exec-credential.c b/src/core/exec-credential.c
+index ae5a32fb2c..847cb02a6a 100644
+--- a/src/core/exec-credential.c
++++ b/src/core/exec-credential.c
+@@ -563,20 +563,20 @@ static int load_credential_glob(
+ assert(search_path);
+
+ STRV_FOREACH(d, search_path) {
+- _cleanup_strv_free_ char **paths = NULL;
++ _cleanup_globfree_ glob_t pglob = {};
+ _cleanup_free_ char *j = NULL;
+
+ j = path_join(*d, ic->glob);
+ if (!j)
+ return -ENOMEM;
+
+- r = safe_glob(j, /* flags = */ 0, &paths);
++ r = safe_glob(j, 0, &pglob);
+ if (r == -ENOENT)
+ continue;
+ if (r < 0)
+ return r;
+
+- STRV_FOREACH(p, paths) {
++ FOREACH_ARRAY(p, pglob.gl_pathv, pglob.gl_pathc) {
+ _cleanup_free_ char *fn = NULL;
+ _cleanup_(erase_and_freep) char *data = NULL;
+ size_t size;
+diff --git a/src/core/execute.c b/src/core/execute.c
+index c384e9dd63..3d6546c037 100644
+--- a/src/core/execute.c
++++ b/src/core/execute.c
+@@ -897,7 +897,7 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c,
+ assert(ret);
+
+ STRV_FOREACH(i, c->environment_files) {
+- _cleanup_strv_free_ char **paths = NULL;
++ _cleanup_globfree_ glob_t pglob = {};
+ bool ignore = false;
+ char *fn = *i;
+
+@@ -913,7 +913,7 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c,
+ }
+
+ /* Filename supports globbing, take all matching files */
+- r = safe_glob(fn, /* flags = */ 0, &paths);
++ r = safe_glob(fn, 0, &pglob);
+ if (r < 0) {
+ if (ignore)
+ continue;
+@@ -921,9 +921,9 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c,
+ }
+
+ /* When we don't match anything, -ENOENT should be returned */
+- assert(!strv_isempty(paths));
++ assert(pglob.gl_pathc > 0);
+
+- STRV_FOREACH(path, paths) {
++ FOREACH_ARRAY(path, pglob.gl_pathv, pglob.gl_pathc) {
+ _cleanup_strv_free_ char **p = NULL;
+
+ r = load_env_file(NULL, *path, &p);
+diff --git a/src/include/override/glob.h b/src/include/override/glob.h
+new file mode 100644
+index 0000000000..a8f1829766
+--- /dev/null
++++ b/src/include/override/glob.h
+@@ -0,0 +1,6 @@
++#pragma once
++
++#include_next <glob.h>
++
++#define GLOB_BRACE 0
++#define GLOB_ALTDIRFUNC 0
+diff --git a/src/test/test-glob-util.c b/src/test/test-glob-util.c
+index a9880f15c8..754dc77447 100644
+--- a/src/test/test-glob-util.c
++++ b/src/test/test-glob-util.c
+@@ -9,7 +9,6 @@
+ #include "fs-util.h"
+ #include "glob-util.h"
+ #include "rm-rf.h"
+-#include "strv.h"
+ #include "tests.h"
+ #include "tmpfile-util.h"
+
+@@ -55,25 +54,31 @@ TEST(glob_exists) {
+ TEST(safe_glob) {
+ char template[] = "/tmp/test-glob-util.XXXXXXX";
+ const char *fn, *fn2, *fname;
+- _cleanup_strv_free_ char **v = NULL;
+
+- ASSERT_NOT_NULL(mkdtemp(template));
++ _cleanup_globfree_ glob_t g = {};
++ int r;
++
++ assert_se(mkdtemp(template));
+
+ fn = strjoina(template, "/*");
+- ASSERT_ERROR(safe_glob(fn, /* flags = */ 0, &v), ENOENT);
++ r = safe_glob(fn, 0, &g);
++ assert_se(r == -ENOENT);
+
+ fn2 = strjoina(template, "/.*");
+- ASSERT_ERROR(safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &v), ENOENT);
++ r = safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &g);
++ assert_se(r == -ENOENT);
+
+ fname = strjoina(template, "/.foobar");
+- ASSERT_OK(touch(fname));
++ assert_se(touch(fname) == 0);
+
+- ASSERT_ERROR(safe_glob(fn, /* flags = */ 0, &v), ENOENT);
++ r = safe_glob(fn, 0, &g);
++ assert_se(r == -ENOENT);
+
+- ASSERT_OK(safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &v));
+- ASSERT_EQ(strv_length(v), 1u);
+- ASSERT_STREQ(v[0], fname);
+- ASSERT_NULL(v[1]);
++ r = safe_glob(fn2, GLOB_NOSORT|GLOB_BRACE, &g);
++ assert_se(r == 0);
++ assert_se(g.gl_pathc == 1);
++ ASSERT_STREQ(g.gl_pathv[0], fname);
++ ASSERT_NULL(g.gl_pathv[1]);
+
+ (void) rm_rf(template, REMOVE_ROOT|REMOVE_PHYSICAL);
+ }
+diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
+index 4342ed70ab..2e1fd87f54 100644
+--- a/src/tmpfiles/tmpfiles.c
++++ b/src/tmpfiles/tmpfiles.c
+@@ -2575,21 +2575,25 @@ finish:
+ }
+
+ static int glob_item(Context *c, Item *i, action_t action) {
+- _cleanup_strv_free_ char **paths = NULL;
++ _cleanup_globfree_ glob_t g = {
++#ifdef __GLIBC__
++ .gl_opendir = (void *(*)(const char *)) opendir_nomod,
++#endif
++ };
+ int r;
+
+ assert(c);
+ assert(i);
+ assert(action);
+
+- r = safe_glob_full(i->path, GLOB_NOSORT|GLOB_BRACE, opendir_nomod, &paths);
++ r = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (r == -ENOENT)
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Failed to glob '%s': %m", i->path);
+
+ r = 0;
+- STRV_FOREACH(fn, paths)
++ STRV_FOREACH(fn, g.gl_pathv)
+ /* We pass CREATION_EXISTING here, since if we are globbing for it, it always has to exist */
+ RET_GATHER(r, action(c, i, *fn, CREATION_EXISTING));
+
+@@ -2601,21 +2605,25 @@ static int glob_item_recursively(
+ Item *i,
+ fdaction_t action) {
+
+- _cleanup_strv_free_ char **paths = NULL;
++ _cleanup_globfree_ glob_t g = {
++#ifdef __GLIBC__
++ .gl_opendir = (void *(*)(const char *)) opendir_nomod,
++#endif
++ };
+ int r;
+
+ assert(c);
+ assert(i);
+ assert(action);
+
+- r = safe_glob_full(i->path, GLOB_NOSORT|GLOB_BRACE, opendir_nomod, &paths);
++ r = safe_glob(i->path, GLOB_NOSORT|GLOB_BRACE, &g);
+ if (r == -ENOENT)
+ return 0;
+ if (r < 0)
+ return log_error_errno(r, "Failed to glob '%s': %m", i->path);
+
+ r = 0;
+- STRV_FOREACH(fn, paths) {
++ STRV_FOREACH(fn, g.gl_pathv) {
+ _cleanup_close_ int fd = -EBADF;
+
+ /* Make sure we won't trigger/follow file object (such as device nodes, automounts, ...)
new file mode 100644
@@ -0,0 +1,37 @@
+From 21eebd618d6485b2f41ff167cc1e23a19655f6d9 Mon Sep 17 00:00:00 2001
+From: Chen Qi <Qi.Chen@windriver.com>
+Date: Wed, 15 Oct 2025 15:48:09 +0800
+Subject: [PATCH] Always include netinet/if_ether.h first
+
+When compiling systemd with musl, we get many ethhdr redinition
+errors. This is because netinet/if_ether.h in musl does not check
+__UAPI_DEF_ETHHDR and expects programs to include it before other
+kernel headers.
+See https://www.openwall.com/lists/musl/2025/10/14/2
+
+To avoid this redefinition error, and to avoid resolving conflicts
+every time we upgrade systemd, use '-include netinet/if_ether.h' to
+make sure this file header is included first.
+
+The major consideration behind such method is maintenance.
+
+Upstream-Status: Inappropriate [musl specific]
+
+Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
+---
+ meson.build | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/meson.build b/meson.build
+index 5e217a35ac..8fb828f35b 100644
+--- a/meson.build
++++ b/meson.build
+@@ -2009,7 +2009,7 @@ config_h = configure_file(
+ output : 'config.h',
+ configuration : conf)
+
+-userspace_c_args += ['-include', 'config.h']
++userspace_c_args += ['-include', 'config.h', '-include', 'netinet/if_ether.h']
+
+ jinja2_cmdline = [meson_render_jinja2, config_h]
+
similarity index 100%
rename from meta/recipes-core/systemd/systemd-boot-native_258.1.bb
rename to meta/recipes-core/systemd/systemd-boot-native_258.3.bb
similarity index 100%
rename from meta/recipes-core/systemd/systemd-boot_258.1.bb
rename to meta/recipes-core/systemd/systemd-boot_258.3.bb
similarity index 99%
rename from meta/recipes-core/systemd/systemd-systemctl-native_258.1.bb
rename to meta/recipes-core/systemd/systemd-systemctl-native_258.3.bb
@@ -26,3 +26,4 @@ do_install:append() {
# added along with it, should be reverted.
install -Dm 0755 ${S}/src/systemctl/systemd-sysv-install.SKELETON ${D}${bindir}/systemd-sysv-install
}
+
@@ -15,7 +15,7 @@ LICENSE:libsystemd = "LGPL-2.1-or-later"
LIC_FILES_CHKSUM = "file://LICENSE.GPL2;md5=c09786363500a9acc29b147e6e72d2c6 \
file://LICENSE.LGPL2.1;md5=be0aaf4a380f73f7e00b420a007368f2"
-SRCREV = "67a1069b7269cc23c3d04a2fb0cf110abe7abf31"
+SRCREV = "56a85121cd3502e824ed368a6b06dda924932bcf"
SRCBRANCH = "v258-stable"
SRC_URI = "git://github.com/systemd/systemd.git;protocol=https;branch=${SRCBRANCH};tag=v${PV}"
@@ -1,8 +1,8 @@
-From b1ab58d3b4a8164e5978409706d6769f5cfde404 Mon Sep 17 00:00:00 2001
+From 506320efcf8d19d7e6ef902f09a25f245e73209d Mon Sep 17 00:00:00 2001
From: Chen Qi <Qi.Chen@windriver.com>
Date: Thu, 21 Feb 2019 16:23:24 +0800
-Subject: [PATCH 01/16] binfmt: Don't install dependency links at install time
- for the binfmt services
+Subject: [PATCH] binfmt: Don't install dependency links at install time for
+ the binfmt services
use [Install] blocks so that they get created when the service is enabled
like a traditional service.
@@ -74,6 +74,3 @@ index 318bf8efc2..6ef684861d 100644
+
+[Install]
+WantedBy=sysinit.target
-2.34.1
-
@@ -1,7 +1,7 @@
-From 08ab9f1eaa86ca2c6a0bb45219a0153495708acb Mon Sep 17 00:00:00 2001
+From 4dd542cb7b38dd92e738fe59eaecb5362bf88f63 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Sat, 5 Sep 2015 06:31:47 +0000
-Subject: [PATCH 02/16] implment systemd-sysv-install for OE
+Subject: [PATCH] implment systemd-sysv-install for OE
Use update-rc.d for enabling/disabling and status command
to check the status of the sysv service
@@ -38,6 +38,3 @@ index cb58d8243b..000bdf6165 100755
;;
*)
usage ;;
-2.34.1
-
@@ -1,7 +1,7 @@
-From a7f6a296707642d05463aec22ea3dfce7d06c989 Mon Sep 17 00:00:00 2001
+From ae20dccd041ddd8f1ffbe2b7c719765bd60ff7f7 Mon Sep 17 00:00:00 2001
From: Peter Kjellerstedt <pkj@axis.com>
Date: Tue, 21 Jan 2025 05:02:00 +0100
-Subject: [PATCH 03/16] Do not create /var/log/README
+Subject: [PATCH] Do not create /var/log/README
/var/log/README is a link to /usr/share/doc/systemd/README.logs. The
latter is packaged in systemd-doc and likely not installed, which leaves
@@ -28,6 +28,3 @@ index cdef21fa9b..03798c953e 100644
{% if HAVE_SYSV_COMPAT %}
# /run/lock/subsys is used for serializing SysV service execution, and
-2.34.1
-
similarity index 100%
rename from meta/recipes-core/systemd/systemd_258.1.bb
rename to meta/recipes-core/systemd/systemd_258.3.bb
Hello, this email is a notification from the Auto Upgrade Helper that the automatic attempt to upgrade the recipe(s) *systemd-boot,systemd,systemd-systemctl-native,systemd-boot-native* to *258.3,258.3,258.3,258.3* has Failed(do_compile). Detailed error information: do_compile failed Next steps: - apply the patch: git am 0001-systemd-boot-systemd-systemd-systemctl-native-system.patch - check the changes to upstream patches and summarize them in the commit message, - compile an image that contains the package - perform some basic sanity tests - amend the patch and sign it off: git commit -s --reset-author --amend - send it to the appropriate mailing list Alternatively, if you believe the recipe should not be upgraded at this time, you can fill RECIPE_NO_UPDATE_REASON in respective recipe file so that automatic upgrades would no longer be attempted. Please review the attached files for further information and build/update failures. Any problem please file a bug at https://bugzilla.yoctoproject.org/enter_bug.cgi?product=Automated%20Update%20Handler Regards, The Upgrade Helper -- >8 -- From 2c35d93c7f17f14eba7e19919f67018b229e7ab0 Mon Sep 17 00:00:00 2001 From: Upgrade Helper <auh@yoctoproject.org> Date: Mon, 15 Dec 2025 19:35:07 +0000 Subject: [PATCH] systemd-boot,systemd,systemd-systemctl-native,systemd-boot-native: upgrade 258.1 -> 258.3,258.1 -> 258.3,258.1 -> 258.3,258.1 -> 258.3 --- ...ntroduce-header-file-and-add-__THROW.patch | 58 +++ ...k-parse_printf_format-implementation.patch | 408 ++++++++++++++++++ ...info-related-contents-glibc-specific.patch | 114 +++++ ...override-sys-prctl.h-to-avoid-redefi.patch | 40 ++ ...compliant-strerror_r-from-GNU-specif.patch | 73 ++++ ...util-Make-STRERROR-portable-for-musl.patch | 41 ++ ...-util.h-define-RLIM_FMT-to-fit-musl-.patch | 37 ++ ...ride-malloc.h-define-dummy-malloc_tr.patch | 38 ++ ...tion.c-avoid-using-glibc-ConditionVe.patch | 43 ++ ....c-avoid-boot-time-segfault-for-musl.patch | 28 ++ ...0014-Handle-missing-gshadow-for-musl.patch | 172 ++++++++ .../0015-Avoid-sequence-point-error.patch | 32 ++ ...-for-glob-related-codes-and-define-d.patch | 406 +++++++++++++++++ ...ays-include-netinet-if_ether.h-first.patch | 37 ++ ..._258.1.bb => systemd-boot-native_258.3.bb} | 0 ...md-boot_258.1.bb => systemd-boot_258.3.bb} | 0 ...1.bb => systemd-systemctl-native_258.3.bb} | 1 + meta/recipes-core/systemd/systemd.inc | 2 +- ...tall-dependency-links-at-install-tim.patch | 9 +- ...implment-systemd-sysv-install-for-OE.patch | 7 +- .../0003-Do-not-create-var-log-README.patch | 7 +- .../{systemd_258.1.bb => systemd_258.3.bb} | 0 22 files changed, 1536 insertions(+), 17 deletions(-) create mode 100644 meta/recipes-core/systemd/files/0004-musl.h-introduce-header-file-and-add-__THROW.patch create mode 100644 meta/recipes-core/systemd/files/0005-add-fallback-parse_printf_format-implementation.patch create mode 100644 meta/recipes-core/systemd/files/0006-Make-mallinfo-related-contents-glibc-specific.patch create mode 100644 meta/recipes-core/systemd/files/0007-add-src-include-override-sys-prctl.h-to-avoid-redefi.patch create mode 100644 meta/recipes-core/systemd/files/0008-distinguish-XSI-compliant-strerror_r-from-GNU-specif.patch create mode 100644 meta/recipes-core/systemd/files/0009-errno-util-Make-STRERROR-portable-for-musl.patch create mode 100644 meta/recipes-core/systemd/files/0010-src-basic-format-util.h-define-RLIM_FMT-to-fit-musl-.patch create mode 100644 meta/recipes-core/systemd/files/0011-src-include-override-malloc.h-define-dummy-malloc_tr.patch create mode 100644 meta/recipes-core/systemd/files/0012-src-shared-condition.c-avoid-using-glibc-ConditionVe.patch create mode 100644 meta/recipes-core/systemd/files/0013-build-path.c-avoid-boot-time-segfault-for-musl.patch create mode 100644 meta/recipes-core/systemd/files/0014-Handle-missing-gshadow-for-musl.patch create mode 100644 meta/recipes-core/systemd/files/0015-Avoid-sequence-point-error.patch create mode 100644 meta/recipes-core/systemd/files/0016-Fix-the-segfault-for-glob-related-codes-and-define-d.patch create mode 100644 meta/recipes-core/systemd/files/0017-Always-include-netinet-if_ether.h-first.patch rename meta/recipes-core/systemd/{systemd-boot-native_258.1.bb => systemd-boot-native_258.3.bb} (100%) rename meta/recipes-core/systemd/{systemd-boot_258.1.bb => systemd-boot_258.3.bb} (100%) rename meta/recipes-core/systemd/{systemd-systemctl-native_258.1.bb => systemd-systemctl-native_258.3.bb} (99%) rename meta/recipes-core/systemd/{systemd_258.1.bb => systemd_258.3.bb} (100%)