1
0
mirror of https://github.com/systemd/systemd synced 2026-04-08 16:14:50 +02:00

Compare commits

...

23 Commits

Author SHA1 Message Date
Vito Caputo
b82aca89a5 mmap-cache: LIST_REMOVE() *after* w->unused_prev
The LIST_REMOVE() macro always assigns NULL to w->unused_prev,
meaning every time this window was in last_unused, the remainder
of the unused list was lost to the ether.

Turns out there's been a memory leak in journald after all, this
code has been there since at least 2013...
2021-11-25 21:39:38 +01:00
Zbigniew Jędrzejewski-Szmek
f1da1e7b5f
Merge pull request #21522 from yuwata/home-fix-memleak
home: fix memleak
2021-11-25 20:22:23 +01:00
Zbigniew Jędrzejewski-Szmek
55a044dece
Merge pull request #21517 from yuwata/network-long-hw-addr
network: make MACAddress= can take longer address
2021-11-25 20:21:38 +01:00
Yu Watanabe
5213507113 network,udev: make .network and .link file can match with hardware address longer or shorter than ETH_ALEN 2021-11-25 20:14:46 +01:00
Henri Chain
81e1590e2d Try to fix exittype test flakyness
The test was changed at @bluca 's request to avoid sleeps,
but the change insufficient to avoid all races.
The kill command is now run from the script itself to avoid using
ExecStartPost
2021-11-25 20:12:59 +01:00
Daan De Meyer
b41b682bd6 journal: Remove entry seqnum revert logic
This actually causes mismatches between the header tail entry seqnum
and the last entry seqnum since when we revert the header seqnum, we
don't remove the entry object we added. If adding the entry object
itself fails, we don't need to revert the seqnum since it's never
incremented so let's remove this logic alltogether.
2021-11-25 20:02:32 +01:00
Lennart Poettering
993b905772 test: don't provide password to deactivation
deactivation of home areas should work without any password being
supplied. Let's hence not supply it, to ensure things work correctly.
2021-11-25 18:19:02 +01:00
Lennart Poettering
c42234abf2 homed: support LogControl1 D-Bus API too, and make use of it
All our D-Bus services support the LogControl1 API, but homed didn't so
far. Fix that, and make use of it in the test case, to make debugging it
easier.
2021-11-25 18:18:42 +01:00
Lennart Poettering
7ff048a718
Merge pull request #21487 from DaanDeMeyer/dissect-image-other-arch
Allow dissect_image() to dissect images from architectures other than the native one
2021-11-25 17:36:57 +01:00
Yu Watanabe
5601a9b910 homework: fix memleak
Fixes #21521.
2021-11-26 00:14:32 +09:00
Yu Watanabe
47398ea705 homework: drop unnecessary initialization 2021-11-26 00:09:30 +09:00
Daan De Meyer
9df247da28 journal: Add more information to --verify error messages 2021-11-25 14:22:56 +01:00
Lennart Poettering
0cdf6b14a5 json: add new JSON_BUILD_CONST_STRING() macro
This macro is like JSON_BUILD_STRING() but uses our json library's
ability to use literal strings directly as JsonVariant objects.

The changes all our codebase to use this new macro whenever we build
JSON objects from literal strings.

(I tried to make this automatic, i.e. to detect in JSON_BUILD_STRING()
whether something is a literal string nicely and thus do this stuff
automatically, but I couldn't find a way.)

This should reduce memory usage of our JSON code a bit. Constant strings
we use very often will now be shared and mapped directly from the ELF
image.
2021-11-25 14:22:31 +01:00
Lennart Poettering
e2c7efd329 json: don't assert() if we add a NULL element via json_variant_set_field()
The rest of our JSON code tries hard to magically convert NULL inputs
into "null" JSON objects, let's make sure this also works with
json_variant_set_field().
2021-11-25 14:21:54 +01:00
Yu Watanabe
a8840714f3 network: make MACAddress= takes hardware address with its length is INFINIBAND_ALEN
Also, the multicast and local bits in the specified MAC address for
ethernet are adjusted.
2021-11-25 22:03:19 +09:00
Daan De Meyer
1b6f9b9880 mkosi: Install sd-boot using postinst script instead of in build script
This allows us to reuse bootctl install instead of replicating the
logic in the build script.
2021-11-25 13:54:03 +01:00
Yu Watanabe
37593b7c48 netif-util: introduce net_verify_hardware_address() 2021-11-25 21:07:32 +09:00
Daan De Meyer
49ae9d91f9 shared: Add support for non-native architectures to dissect_image()
To allow dissecting images of architectures other than the native
(or secondary) one, we add a third designator 'OTHER' to represent
architectures other than the native or secondary one.

If no partitions of the native or secondary arch are available, we
check if a root partition of any other arch is available and use that
instead if we found one.
2021-11-24 15:06:38 +01:00
Daan De Meyer
6ddd80ae18 gpt: Store the partition type in GptPartitionType
This replaces the _GPT_ALL_ARCHES macro.
2021-11-24 14:47:57 +01:00
Daan De Meyer
51d1c8f2fe gpt: Store the architecture in GptPartitionType
We also add a function gpt_partition_type_uuid_to_arch() to get the
architecture of a partition type uuid.
2021-11-24 14:47:21 +01:00
Daan De Meyer
3c58ae1313 basic: Rename SECONDARY_ARCHITECTURE to ARCHITECTURE_SECONDARY
For easier integration with the _GPT_ALL_ARCHES macro in a future
commit.
2021-11-24 12:00:41 +01:00
Daan De Meyer
6d4c80ddbb gpt: Rename PPC64LE TO PPC64_LE
For consistency with ARCHITECTURE_PPC64_LE
2021-11-24 12:00:41 +01:00
Daan De Meyer
b998ff21e1 basic: Give architecure enum a name 2021-11-24 12:00:41 +01:00
49 changed files with 633 additions and 408 deletions

View File

@ -89,12 +89,48 @@
<varlistentry id='mac-address'> <varlistentry id='mac-address'>
<term><varname>MACAddress=</varname></term> <term><varname>MACAddress=</varname></term>
<listitem> <listitem>
<para>A whitespace-separated list of hardware addresses. Use full colon-, hyphen- or dot-delimited hexadecimal. See the example below. <para>A whitespace-separated list of hardware addresses. The acceptable formats are:</para>
This option may appear more than once, in which case the lists are merged. If the empty string is assigned to this option, the list
of hardware addresses defined prior to this is reset.</para>
<para>Example: <variablelist>
<programlisting>MACAddress=01:23:45:67:89:ab 00-11-22-33-44-55 AABB.CCDD.EEFF</programlisting></para> <varlistentry>
<term><option>colon-delimited hexadecimal</option></term>
<listitem><para>
Each field must be one byte.
E.g. <literal>12:34:56:78:90:ab</literal> or <literal>AA:BB:CC:DD:EE:FF</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>hyphen-delimited hexadecimal</option></term>
<listitem><para>
Each field must be one byte.
E.g. <literal>12-34-56-78-90-ab</literal> or <literal>AA-BB-CC-DD-EE-FF</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>dot-delimited hexadecimal</option></term>
<listitem><para>
Each field must be two bytes.
E.g. <literal>1234.5678.90ab</literal> or <literal>AABB.CCDD.EEFF</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>IPv4 address format</option></term>
<listitem><para>
E.g. <literal>127.0.0.1</literal> or <literal>192.168.0.1</literal>.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>IPv6 address format</option></term>
<listitem><para>
E.g. <literal>2001:0db8:85a3::8a2e:0370:7334</literal> or <literal>::1</literal>.
</para></listitem>
</varlistentry>
</variablelist>
<para>The total length of each MAC address must be 4 (for IPv4 tunnel), 6 (for Ethernet), 16
(for IPv6 tunnel), or 20 (for InfiniBand). This option may appear more than once, in which
case the lists are merged. If the empty string is assigned to this option, the list of
hardware addresses defined prior to this is reset. Defaults to unset.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -104,9 +140,10 @@
<para>A whitespace-separated list of hardware's permanent addresses. While <para>A whitespace-separated list of hardware's permanent addresses. While
<varname>MACAddress=</varname> matches the device's current MAC address, this matches the <varname>MACAddress=</varname> matches the device's current MAC address, this matches the
device's permanent MAC address, which may be different from the current one. Use full device's permanent MAC address, which may be different from the current one. Use full
colon-, hyphen- or dot-delimited hexadecimal. This option may appear more than once, in colon-, hyphen- or dot-delimited hexadecimal, or IPv4 or IPv6 address format. This option may
which case the lists are merged. If the empty string is assigned to this option, the list appear more than once, in which case the lists are merged. If the empty string is assigned to
of hardware addresses defined prior to this is reset.</para> this option, the list of hardware addresses defined prior to this is reset. Defaults to
unset.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -110,12 +110,3 @@ if [ -n "$IMAGE_VERSION" ] ; then
cat /tmp/os-release.tmp > "$DESTDIR"/usr/lib/os-release cat /tmp/os-release.tmp > "$DESTDIR"/usr/lib/os-release
rm /tmp/os-release.tmp rm /tmp/os-release.tmp
fi fi
# Manually update the boot loader from the one we just built
mkdir -p "$DESTDIR"/boot/efi/EFI/systemd "$DESTDIR"/boot/efi/EFI/BOOT
cp "$DESTDIR"/usr/lib/systemd/boot/efi/systemd-bootx64.efi "$DESTDIR"/boot/efi/EFI/systemd/systemd-bootx64.efi
cp "$DESTDIR"/usr/lib/systemd/boot/efi/systemd-bootx64.efi "$DESTDIR"/boot/efi/EFI/BOOT/bootx64.efi
mkdir -p "$DESTDIR"/efi/EFI/systemd "$DESTDIR"/efi/EFI/BOOT
cp "$DESTDIR"/usr/lib/systemd/boot/efi/systemd-bootx64.efi "$DESTDIR"/efi/EFI/systemd/systemd-bootx64.efi
cp "$DESTDIR"/usr/lib/systemd/boot/efi/systemd-bootx64.efi "$DESTDIR"/efi/EFI/BOOT/bootx64.efi

6
mkosi.postinst Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
# SPDX-License-Identifier: LGPL-2.1-or-later
if [ "$1" = "final" ] && command -v bootctl > /dev/null; then
bootctl install
fi

View File

@ -10,7 +10,7 @@
* processor features, models, generations or even ABIs. Hence we * processor features, models, generations or even ABIs. Hence we
* focus on general family, and distinguish word width and endianness. */ * focus on general family, and distinguish word width and endianness. */
enum { typedef enum {
ARCHITECTURE_ALPHA, ARCHITECTURE_ALPHA,
ARCHITECTURE_ARC, ARCHITECTURE_ARC,
ARCHITECTURE_ARC_BE, ARCHITECTURE_ARC_BE,
@ -45,7 +45,7 @@ enum {
ARCHITECTURE_X86_64, ARCHITECTURE_X86_64,
_ARCHITECTURE_MAX, _ARCHITECTURE_MAX,
_ARCHITECTURE_INVALID = -EINVAL, _ARCHITECTURE_INVALID = -EINVAL,
}; } Architecture;
int uname_architecture(void); int uname_architecture(void);
@ -67,7 +67,7 @@ int uname_architecture(void);
# else # else
# define LIB_ARCH_TUPLE "x86_64-linux-gnu" # define LIB_ARCH_TUPLE "x86_64-linux-gnu"
# endif # endif
# define SECONDARY_ARCHITECTURE ARCHITECTURE_X86 # define ARCHITECTURE_SECONDARY ARCHITECTURE_X86
#elif defined(__i386__) #elif defined(__i386__)
# define native_architecture() ARCHITECTURE_X86 # define native_architecture() ARCHITECTURE_X86
# define LIB_ARCH_TUPLE "i386-linux-gnu" # define LIB_ARCH_TUPLE "i386-linux-gnu"
@ -75,11 +75,11 @@ int uname_architecture(void);
# if __BYTE_ORDER == __BIG_ENDIAN # if __BYTE_ORDER == __BIG_ENDIAN
# define native_architecture() ARCHITECTURE_PPC64 # define native_architecture() ARCHITECTURE_PPC64
# define LIB_ARCH_TUPLE "ppc64-linux-gnu" # define LIB_ARCH_TUPLE "ppc64-linux-gnu"
# define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC # define ARCHITECTURE_SECONDARY ARCHITECTURE_PPC
# else # else
# define native_architecture() ARCHITECTURE_PPC64_LE # define native_architecture() ARCHITECTURE_PPC64_LE
# define LIB_ARCH_TUPLE "powerpc64le-linux-gnu" # define LIB_ARCH_TUPLE "powerpc64le-linux-gnu"
# define SECONDARY_ARCHITECTURE ARCHITECTURE_PPC_LE # define ARCHITECTURE_SECONDARY ARCHITECTURE_PPC_LE
# endif # endif
#elif defined(__powerpc__) #elif defined(__powerpc__)
# if __BYTE_ORDER == __BIG_ENDIAN # if __BYTE_ORDER == __BIG_ENDIAN
@ -105,7 +105,7 @@ int uname_architecture(void);
#elif defined(__s390x__) #elif defined(__s390x__)
# define native_architecture() ARCHITECTURE_S390X # define native_architecture() ARCHITECTURE_S390X
# define LIB_ARCH_TUPLE "s390x-linux-gnu" # define LIB_ARCH_TUPLE "s390x-linux-gnu"
# define SECONDARY_ARCHITECTURE ARCHITECTURE_S390 # define ARCHITECTURE_SECONDARY ARCHITECTURE_S390
#elif defined(__s390__) #elif defined(__s390__)
# define native_architecture() ARCHITECTURE_S390 # define native_architecture() ARCHITECTURE_S390
# define LIB_ARCH_TUPLE "s390-linux-gnu" # define LIB_ARCH_TUPLE "s390-linux-gnu"
@ -149,7 +149,7 @@ int uname_architecture(void);
# else # else
# define native_architecture() ARCHITECTURE_ARM64 # define native_architecture() ARCHITECTURE_ARM64
# define LIB_ARCH_TUPLE "aarch64-linux-gnu" # define LIB_ARCH_TUPLE "aarch64-linux-gnu"
# define SECONDARY_ARCHITECTURE ARCHITECTURE_ARM # define ARCHITECTURE_SECONDARY ARCHITECTURE_ARM
# endif # endif
#elif defined(__arm__) #elif defined(__arm__)
# if __BYTE_ORDER == __BIG_ENDIAN # if __BYTE_ORDER == __BIG_ENDIAN

View File

@ -1045,8 +1045,8 @@ unsigned long personality_from_string(const char *p) {
if (architecture == native_architecture()) if (architecture == native_architecture())
return PER_LINUX; return PER_LINUX;
#ifdef SECONDARY_ARCHITECTURE #ifdef ARCHITECTURE_SECONDARY
if (architecture == SECONDARY_ARCHITECTURE) if (architecture == ARCHITECTURE_SECONDARY)
return PER_LINUX32; return PER_LINUX32;
#endif #endif
@ -1058,9 +1058,9 @@ const char* personality_to_string(unsigned long p) {
if (p == PER_LINUX) if (p == PER_LINUX)
architecture = native_architecture(); architecture = native_architecture();
#ifdef SECONDARY_ARCHITECTURE #ifdef ARCHITECTURE_SECONDARY
else if (p == PER_LINUX32) else if (p == PER_LINUX32)
architecture = SECONDARY_ARCHITECTURE; architecture = ARCHITECTURE_SECONDARY;
#endif #endif
if (architecture < 0) if (architecture < 0)

View File

@ -31,12 +31,12 @@ static int build_user_json(const char *user_name, uid_t uid, JsonVariant **ret)
JSON_BUILD_PAIR("userName", JSON_BUILD_STRING(user_name)), JSON_BUILD_PAIR("userName", JSON_BUILD_STRING(user_name)),
JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(uid)), JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(uid)),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(uid)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(uid)),
JSON_BUILD_PAIR("realName", JSON_BUILD_STRING("Dynamic User")), JSON_BUILD_PAIR("realName", JSON_BUILD_CONST_STRING("Dynamic User")),
JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_STRING("/")), JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_CONST_STRING("/")),
JSON_BUILD_PAIR("shell", JSON_BUILD_STRING(NOLOGIN)), JSON_BUILD_PAIR("shell", JSON_BUILD_CONST_STRING(NOLOGIN)),
JSON_BUILD_PAIR("locked", JSON_BUILD_BOOLEAN(true)), JSON_BUILD_PAIR("locked", JSON_BUILD_BOOLEAN(true)),
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.DynamicUser")), JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.DynamicUser")),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("dynamic")))))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("dynamic"))))));
} }
static bool user_match_lookup_parameters(LookupParameters *p, const char *name, uid_t uid) { static bool user_match_lookup_parameters(LookupParameters *p, const char *name, uid_t uid) {
@ -339,10 +339,10 @@ static int build_group_json(const char *group_name, gid_t gid, JsonVariant **ret
return json_build(ret, JSON_BUILD_OBJECT( return json_build(ret, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("record", JSON_BUILD_OBJECT( JSON_BUILD_PAIR("record", JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)), JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)),
JSON_BUILD_PAIR("description", JSON_BUILD_STRING("Dynamic Group")), JSON_BUILD_PAIR("description", JSON_BUILD_CONST_STRING("Dynamic Group")),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)),
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.DynamicUser")), JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.DynamicUser")),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("dynamic")))))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("dynamic"))))));
} }
static bool group_match_lookup_parameters(LookupParameters *p, const char *name, gid_t gid) { static bool group_match_lookup_parameters(LookupParameters *p, const char *name, gid_t gid) {

View File

@ -74,11 +74,11 @@ int enroll_fido2(
r = json_build(&v, r = json_build(&v,
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("type", JSON_BUILD_STRING("systemd-fido2")), JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-fido2")),
JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))), JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
JSON_BUILD_PAIR("fido2-credential", JSON_BUILD_BASE64(cid, cid_size)), JSON_BUILD_PAIR("fido2-credential", JSON_BUILD_BASE64(cid, cid_size)),
JSON_BUILD_PAIR("fido2-salt", JSON_BUILD_BASE64(salt, salt_size)), JSON_BUILD_PAIR("fido2-salt", JSON_BUILD_BASE64(salt, salt_size)),
JSON_BUILD_PAIR("fido2-rp", JSON_BUILD_STRING("io.systemd.cryptsetup")), JSON_BUILD_PAIR("fido2-rp", JSON_BUILD_CONST_STRING("io.systemd.cryptsetup")),
JSON_BUILD_PAIR("fido2-clientPin-required", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_PIN))), JSON_BUILD_PAIR("fido2-clientPin-required", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_PIN))),
JSON_BUILD_PAIR("fido2-up-required", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_UP))), JSON_BUILD_PAIR("fido2-up-required", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_UP))),
JSON_BUILD_PAIR("fido2-uv-required", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_UV))))); JSON_BUILD_PAIR("fido2-uv-required", JSON_BUILD_BOOLEAN(FLAGS_SET(lock_with, FIDO2ENROLL_UV)))));

View File

@ -83,7 +83,7 @@ int enroll_pkcs11(
r = json_build(&v, r = json_build(&v,
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("type", JSON_BUILD_STRING("systemd-pkcs11")), JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-pkcs11")),
JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))), JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
JSON_BUILD_PAIR("pkcs11-uri", JSON_BUILD_STRING(uri)), JSON_BUILD_PAIR("pkcs11-uri", JSON_BUILD_STRING(uri)),
JSON_BUILD_PAIR("pkcs11-key", JSON_BUILD_BASE64(encrypted_key, encrypted_key_size)))); JSON_BUILD_PAIR("pkcs11-key", JSON_BUILD_BASE64(encrypted_key, encrypted_key_size))));

View File

@ -76,7 +76,7 @@ int enroll_recovery(
r = json_build(&v, r = json_build(&v,
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("type", JSON_BUILD_STRING("systemd-recovery")), JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-recovery")),
JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))))); JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string)))));
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to prepare recovery key JSON token object: %m"); log_error_errno(r, "Failed to prepare recovery key JSON token object: %m");

View File

@ -19,7 +19,7 @@ static int add_privileged(JsonVariant **v, const char *hashed) {
assert(hashed); assert(hashed);
r = json_build(&e, JSON_BUILD_OBJECT( r = json_build(&e, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("type", JSON_BUILD_STRING("modhex64")), JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("modhex64")),
JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(hashed)))); JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(hashed))));
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to build recover key JSON object: %m"); return log_error_errno(r, "Failed to build recover key JSON object: %m");

View File

@ -2518,7 +2518,7 @@ int home_augment_status(
r = json_build(&status, r = json_build(&status,
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("state", JSON_BUILD_STRING(home_state_to_string(state))), JSON_BUILD_PAIR("state", JSON_BUILD_STRING(home_state_to_string(state))),
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Home")), JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.Home")),
JSON_BUILD_PAIR_CONDITION(disk_size != UINT64_MAX, "diskSize", JSON_BUILD_UNSIGNED(disk_size)), JSON_BUILD_PAIR_CONDITION(disk_size != UINT64_MAX, "diskSize", JSON_BUILD_UNSIGNED(disk_size)),
JSON_BUILD_PAIR_CONDITION(disk_usage != UINT64_MAX, "diskUsage", JSON_BUILD_UNSIGNED(disk_usage)), JSON_BUILD_PAIR_CONDITION(disk_usage != UINT64_MAX, "diskUsage", JSON_BUILD_UNSIGNED(disk_usage)),
JSON_BUILD_PAIR_CONDITION(disk_free != UINT64_MAX, "diskFree", JSON_BUILD_UNSIGNED(disk_free)), JSON_BUILD_PAIR_CONDITION(disk_free != UINT64_MAX, "diskFree", JSON_BUILD_UNSIGNED(disk_free)),

View File

@ -947,6 +947,10 @@ static int manager_connect_bus(Manager *m) {
if (r < 0) if (r < 0)
return r; return r;
r = bus_log_control_api_register(m->bus);
if (r < 0)
return r;
suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX");
if (suffix) if (suffix)
busname = strjoina("org.freedesktop.home1.", suffix); busname = strjoina("org.freedesktop.home1.", suffix);

View File

@ -984,7 +984,7 @@ static int format_luks_token_text(
r = json_build(&v, r = json_build(&v,
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("type", JSON_BUILD_STRING("systemd-homed")), JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-homed")),
JSON_BUILD_PAIR("keyslots", JSON_BUILD_EMPTY_ARRAY), JSON_BUILD_PAIR("keyslots", JSON_BUILD_EMPTY_ARRAY),
JSON_BUILD_PAIR("record", JSON_BUILD_BASE64(encrypted, encrypted_size_out1 + encrypted_size_out2)), JSON_BUILD_PAIR("record", JSON_BUILD_BASE64(encrypted, encrypted_size_out1 + encrypted_size_out2)),
JSON_BUILD_PAIR("iv", JSON_BUILD_BASE64(iv, iv_size)))); JSON_BUILD_PAIR("iv", JSON_BUILD_BASE64(iv, iv_size))));

View File

@ -11,12 +11,13 @@ void password_cache_free(PasswordCache *cache) {
cache->pkcs11_passwords = strv_free_erase(cache->pkcs11_passwords); cache->pkcs11_passwords = strv_free_erase(cache->pkcs11_passwords);
cache->fido2_passwords = strv_free_erase(cache->fido2_passwords); cache->fido2_passwords = strv_free_erase(cache->fido2_passwords);
cache->keyring_passswords = strv_free_erase(cache->keyring_passswords);
} }
void password_cache_load_keyring(UserRecord *h, PasswordCache *cache) { void password_cache_load_keyring(UserRecord *h, PasswordCache *cache) {
_cleanup_(erase_and_freep) void *p = NULL; _cleanup_(erase_and_freep) void *p = NULL;
_cleanup_free_ char *name = NULL; _cleanup_free_ char *name = NULL;
char **strv = NULL; char **strv;
key_serial_t serial; key_serial_t serial;
size_t sz; size_t sz;
int r; int r;

View File

@ -83,7 +83,7 @@ int user_record_synthesize(
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("userName", JSON_BUILD_STRING(user_name)), JSON_BUILD_PAIR("userName", JSON_BUILD_STRING(user_name)),
JSON_BUILD_PAIR_CONDITION(!!rr, "realm", JSON_BUILD_STRING(realm)), JSON_BUILD_PAIR_CONDITION(!!rr, "realm", JSON_BUILD_STRING(realm)),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("regular")), JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("regular")),
JSON_BUILD_PAIR("binding", JSON_BUILD_OBJECT( JSON_BUILD_PAIR("binding", JSON_BUILD_OBJECT(
JSON_BUILD_PAIR(SD_ID128_TO_STRING(mid), JSON_BUILD_OBJECT( JSON_BUILD_PAIR(SD_ID128_TO_STRING(mid), JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("imagePath", JSON_BUILD_STRING(image_path)), JSON_BUILD_PAIR("imagePath", JSON_BUILD_STRING(image_path)),
@ -150,7 +150,7 @@ int group_record_synthesize(GroupRecord *g, UserRecord *h) {
JSON_BUILD_PAIR_CONDITION(h->disposition >= 0, "disposition", JSON_BUILD_STRING(user_disposition_to_string(user_record_disposition(h)))), JSON_BUILD_PAIR_CONDITION(h->disposition >= 0, "disposition", JSON_BUILD_STRING(user_disposition_to_string(user_record_disposition(h)))),
JSON_BUILD_PAIR("status", JSON_BUILD_OBJECT( JSON_BUILD_PAIR("status", JSON_BUILD_OBJECT(
JSON_BUILD_PAIR(SD_ID128_TO_STRING(mid), JSON_BUILD_OBJECT( JSON_BUILD_PAIR(SD_ID128_TO_STRING(mid), JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Home")))))))); JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.Home"))))))));
if (r < 0) if (r < 0)
return r; return r;

View File

@ -1021,30 +1021,6 @@ static uint64_t journal_file_entry_seqnum(
return ret; return ret;
} }
static void journal_file_revert_entry_seqnum(
JournalFile *f,
uint64_t *seqnum,
uint64_t revert_seqnum) {
assert(f);
assert(f->header);
if (revert_seqnum == 0) /* sequence number 0? can't go back */
return;
/* Undoes the effect of journal_file_entry_seqnum() above: if we fail to append an entry to a file,
* let's revert the seqnum we were about to use, so that we can use it on the next entry. */
if (le64toh(f->header->tail_entry_seqnum) == revert_seqnum)
f->header->tail_entry_seqnum = htole64(revert_seqnum - 1);
if (le64toh(f->header->head_entry_seqnum) == revert_seqnum)
f->header->head_entry_seqnum = 0;
if (seqnum && *seqnum == revert_seqnum)
*seqnum = revert_seqnum - 1;
}
int journal_file_append_object( int journal_file_append_object(
JournalFile *f, JournalFile *f,
ObjectType type, ObjectType type,
@ -2000,12 +1976,12 @@ static int journal_file_append_entry_internal(
#if HAVE_GCRYPT #if HAVE_GCRYPT
r = journal_file_hmac_put_object(f, OBJECT_ENTRY, o, np); r = journal_file_hmac_put_object(f, OBJECT_ENTRY, o, np);
if (r < 0) if (r < 0)
goto fail; return r;
#endif #endif
r = journal_file_link_entry(f, o, np); r = journal_file_link_entry(f, o, np);
if (r < 0) if (r < 0)
goto fail; return r;
if (ret) if (ret)
*ret = o; *ret = o;
@ -2013,10 +1989,6 @@ static int journal_file_append_entry_internal(
if (ret_offset) if (ret_offset)
*ret_offset = np; *ret_offset = np;
return 0;
fail:
journal_file_revert_entry_seqnum(f, seqnum, le64toh(o->entry.seqnum));
return r; return r;
} }

View File

@ -149,7 +149,9 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
if ((o->object.flags & OBJECT_COMPRESSED_XZ) && if ((o->object.flags & OBJECT_COMPRESSED_XZ) &&
o->object.type != OBJECT_DATA) { o->object.type != OBJECT_DATA) {
error(offset, "Found compressed object that isn't of type DATA, which is not allowed."); error(offset,
"Found compressed object of type %s that isn't of type data, which is not allowed.",
journal_object_type_to_string(o->object.type));
return -EBADMSG; return -EBADMSG;
} }
@ -291,8 +293,8 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0 || if ((le64toh(o->object.size) - offsetof(HashTableObject, items)) % sizeof(HashItem) != 0 ||
(le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0) { (le64toh(o->object.size) - offsetof(HashTableObject, items)) / sizeof(HashItem) <= 0) {
error(offset, error(offset,
"Invalid %s hash table size: %"PRIu64, "Invalid %s size: %"PRIu64,
o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", journal_object_type_to_string(o->object.type),
le64toh(o->object.size)); le64toh(o->object.size));
return -EBADMSG; return -EBADMSG;
} }
@ -302,7 +304,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
!VALID64(le64toh(o->hash_table.items[i].head_hash_offset))) { !VALID64(le64toh(o->hash_table.items[i].head_hash_offset))) {
error(offset, error(offset,
"Invalid %s hash table item (%"PRIu64"/%"PRIu64") head_hash_offset: "OFSfmt, "Invalid %s hash table item (%"PRIu64"/%"PRIu64") head_hash_offset: "OFSfmt,
o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", journal_object_type_to_string(o->object.type),
i, journal_file_hash_table_n_items(o), i, journal_file_hash_table_n_items(o),
le64toh(o->hash_table.items[i].head_hash_offset)); le64toh(o->hash_table.items[i].head_hash_offset));
return -EBADMSG; return -EBADMSG;
@ -311,7 +313,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
!VALID64(le64toh(o->hash_table.items[i].tail_hash_offset))) { !VALID64(le64toh(o->hash_table.items[i].tail_hash_offset))) {
error(offset, error(offset,
"Invalid %s hash table item (%"PRIu64"/%"PRIu64") tail_hash_offset: "OFSfmt, "Invalid %s hash table item (%"PRIu64"/%"PRIu64") tail_hash_offset: "OFSfmt,
o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", journal_object_type_to_string(o->object.type),
i, journal_file_hash_table_n_items(o), i, journal_file_hash_table_n_items(o),
le64toh(o->hash_table.items[i].tail_hash_offset)); le64toh(o->hash_table.items[i].tail_hash_offset));
return -EBADMSG; return -EBADMSG;
@ -321,7 +323,7 @@ static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o
(o->hash_table.items[i].tail_hash_offset != 0)) { (o->hash_table.items[i].tail_hash_offset != 0)) {
error(offset, error(offset,
"Invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt, "Invalid %s hash table item (%"PRIu64"/%"PRIu64"): head_hash_offset="OFSfmt" tail_hash_offset="OFSfmt,
o->object.type == OBJECT_DATA_HASH_TABLE ? "data" : "field", journal_object_type_to_string(o->object.type),
i, journal_file_hash_table_n_items(o), i, journal_file_hash_table_n_items(o),
le64toh(o->hash_table.items[i].head_hash_offset), le64toh(o->hash_table.items[i].head_hash_offset),
le64toh(o->hash_table.items[i].tail_hash_offset)); le64toh(o->hash_table.items[i].tail_hash_offset));
@ -569,7 +571,7 @@ static int verify_data(
q = le64toh(o->entry_array.items[j]); q = le64toh(o->entry_array.items[j]);
if (q <= last) { if (q <= last) {
error(p, "Data object's entry array not sorted"); error(p, "Data object's entry array not sorted (%"PRIu64" <= %"PRIu64")", q, last);
return -EBADMSG; return -EBADMSG;
} }
last = q; last = q;
@ -655,7 +657,10 @@ static int verify_data_hash_table(
} }
if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) { if (last != le64toh(f->data_hash_table[i].tail_hash_offset)) {
error(p, "Tail hash pointer mismatch in hash table"); error(p,
"Tail hash pointer mismatch in hash table (%"PRIu64" != %"PRIu64")",
last,
le64toh(f->data_hash_table[i].tail_hash_offset));
return -EBADMSG; return -EBADMSG;
} }
} }
@ -987,12 +992,15 @@ int journal_file_verify(
r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o); r = journal_file_move_to_object(f, OBJECT_UNUSED, p, &o);
if (r < 0) { if (r < 0) {
error(p, "Invalid object"); error_errno(p, r, "Invalid object: %m");
goto fail; goto fail;
} }
if (p > le64toh(f->header->tail_object_offset)) { if (p > le64toh(f->header->tail_object_offset)) {
error(offsetof(Header, tail_object_offset), "Invalid tail object pointer"); error(offsetof(Header, tail_object_offset),
"Invalid tail object pointer (%"PRIu64" > %"PRIu64")",
p,
le64toh(f->header->tail_object_offset));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
@ -1008,7 +1016,7 @@ int journal_file_verify(
if (!!(o->object.flags & OBJECT_COMPRESSED_XZ) + if (!!(o->object.flags & OBJECT_COMPRESSED_XZ) +
!!(o->object.flags & OBJECT_COMPRESSED_LZ4) + !!(o->object.flags & OBJECT_COMPRESSED_LZ4) +
!!(o->object.flags & OBJECT_COMPRESSED_ZSTD) > 1) { !!(o->object.flags & OBJECT_COMPRESSED_ZSTD) > 1) {
error(p, "Object has multiple compression flags set"); error(p, "Object has multiple compression flags set (flags: 0x%x)", o->object.flags);
r = -EINVAL; r = -EINVAL;
goto fail; goto fail;
} }
@ -1057,21 +1065,30 @@ int journal_file_verify(
goto fail; goto fail;
if (le64toh(o->entry.realtime) < last_tag_realtime) { if (le64toh(o->entry.realtime) < last_tag_realtime) {
error(p, "Older entry after newer tag"); error(p,
"Older entry after newer tag (%"PRIu64" < %"PRIu64")",
le64toh(o->entry.realtime),
last_tag_realtime);
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (!entry_seqnum_set && if (!entry_seqnum_set &&
le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) { le64toh(o->entry.seqnum) != le64toh(f->header->head_entry_seqnum)) {
error(p, "Head entry sequence number incorrect"); error(p,
"Head entry sequence number incorrect (%"PRIu64" != %"PRIu64")",
le64toh(o->entry.seqnum),
le64toh(f->header->head_entry_seqnum));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (entry_seqnum_set && if (entry_seqnum_set &&
entry_seqnum >= le64toh(o->entry.seqnum)) { entry_seqnum >= le64toh(o->entry.seqnum)) {
error(p, "Entry sequence number out of synchronization"); error(p,
"Entry sequence number out of synchronization (%"PRIu64" >= %"PRIu64")",
entry_seqnum,
le64toh(o->entry.seqnum));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
@ -1082,7 +1099,10 @@ int journal_file_verify(
if (entry_monotonic_set && if (entry_monotonic_set &&
sd_id128_equal(entry_boot_id, o->entry.boot_id) && sd_id128_equal(entry_boot_id, o->entry.boot_id) &&
entry_monotonic > le64toh(o->entry.monotonic)) { entry_monotonic > le64toh(o->entry.monotonic)) {
error(p, "Entry timestamp out of synchronization"); error(p,
"Entry timestamp out of synchronization (%"PRIu64" > %"PRIu64")",
entry_monotonic,
le64toh(o->entry.monotonic));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
@ -1093,7 +1113,10 @@ int journal_file_verify(
if (!entry_realtime_set && if (!entry_realtime_set &&
le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) { le64toh(o->entry.realtime) != le64toh(f->header->head_entry_realtime)) {
error(p, "Head entry realtime timestamp incorrect"); error(p,
"Head entry realtime timestamp incorrect (%"PRIu64" != %"PRIu64")",
le64toh(o->entry.realtime),
le64toh(f->header->head_entry_realtime));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
@ -1147,13 +1170,19 @@ int journal_file_verify(
} }
if (le64toh(o->tag.seqnum) != n_tags + 1) { if (le64toh(o->tag.seqnum) != n_tags + 1) {
error(p, "Tag sequence number out of synchronization"); error(p,
"Tag sequence number out of synchronization (%"PRIu64" != %"PRIu64")",
le64toh(o->tag.seqnum),
n_tags + 1);
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (le64toh(o->tag.epoch) < last_epoch) { if (le64toh(o->tag.epoch) < last_epoch) {
error(p, "Epoch sequence out of synchronization"); error(p,
"Epoch sequence out of synchronization (%"PRIu64" < %"PRIu64")",
le64toh(o->tag.epoch),
last_epoch);
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
@ -1166,7 +1195,10 @@ int journal_file_verify(
rt = f->fss_start_usec + le64toh(o->tag.epoch) * f->fss_interval_usec; rt = f->fss_start_usec + le64toh(o->tag.epoch) * f->fss_interval_usec;
if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) { if (entry_realtime_set && entry_realtime >= rt + f->fss_interval_usec) {
error(p, "tag/entry realtime timestamp out of synchronization"); error(p,
"tag/entry realtime timestamp out of synchronization (%"PRIu64" >= %"PRIu64")",
entry_realtime,
rt + f->fss_interval_usec);
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
@ -1240,60 +1272,83 @@ int journal_file_verify(
}; };
if (!found_last && le64toh(f->header->tail_object_offset) != 0) { if (!found_last && le64toh(f->header->tail_object_offset) != 0) {
error(le64toh(f->header->tail_object_offset), "Tail object pointer dead"); error(le64toh(f->header->tail_object_offset),
"Tail object pointer dead (%"PRIu64" != 0)",
le64toh(f->header->tail_object_offset));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (n_objects != le64toh(f->header->n_objects)) { if (n_objects != le64toh(f->header->n_objects)) {
error(offsetof(Header, n_objects), "Object number mismatch"); error(offsetof(Header, n_objects),
"Object number mismatch (%"PRIu64" != %"PRIu64")",
n_objects,
le64toh(f->header->n_objects));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (n_entries != le64toh(f->header->n_entries)) { if (n_entries != le64toh(f->header->n_entries)) {
error(offsetof(Header, n_entries), "Entry number mismatch"); error(offsetof(Header, n_entries),
"Entry number mismatch (%"PRIu64" != %"PRIu64")",
n_entries,
le64toh(f->header->n_entries));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (JOURNAL_HEADER_CONTAINS(f->header, n_data) && if (JOURNAL_HEADER_CONTAINS(f->header, n_data) &&
n_data != le64toh(f->header->n_data)) { n_data != le64toh(f->header->n_data)) {
error(offsetof(Header, n_data), "Data number mismatch"); error(offsetof(Header, n_data),
"Data number mismatch (%"PRIu64" != %"PRIu64")",
n_data,
le64toh(f->header->n_data));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) && if (JOURNAL_HEADER_CONTAINS(f->header, n_fields) &&
n_fields != le64toh(f->header->n_fields)) { n_fields != le64toh(f->header->n_fields)) {
error(offsetof(Header, n_fields), "Field number mismatch"); error(offsetof(Header, n_fields),
"Field number mismatch (%"PRIu64" != %"PRIu64")",
n_fields,
le64toh(f->header->n_fields));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) && if (JOURNAL_HEADER_CONTAINS(f->header, n_tags) &&
n_tags != le64toh(f->header->n_tags)) { n_tags != le64toh(f->header->n_tags)) {
error(offsetof(Header, n_tags), "Tag number mismatch"); error(offsetof(Header, n_tags),
"Tag number mismatch (%"PRIu64" != %"PRIu64")",
n_tags,
le64toh(f->header->n_tags));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) && if (JOURNAL_HEADER_CONTAINS(f->header, n_entry_arrays) &&
n_entry_arrays != le64toh(f->header->n_entry_arrays)) { n_entry_arrays != le64toh(f->header->n_entry_arrays)) {
error(offsetof(Header, n_entry_arrays), "Entry array number mismatch"); error(offsetof(Header, n_entry_arrays),
"Entry array number mismatch (%"PRIu64" != %"PRIu64")",
n_entry_arrays,
le64toh(f->header->n_entry_arrays));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (!found_main_entry_array && le64toh(f->header->entry_array_offset) != 0) { if (!found_main_entry_array && le64toh(f->header->entry_array_offset) != 0) {
error(0, "Missing entry array"); error(0, "Missing main entry array");
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (entry_seqnum_set && if (entry_seqnum_set &&
entry_seqnum != le64toh(f->header->tail_entry_seqnum)) { entry_seqnum != le64toh(f->header->tail_entry_seqnum)) {
error(offsetof(Header, tail_entry_seqnum), "Invalid tail seqnum"); error(offsetof(Header, tail_entry_seqnum),
"Tail entry sequence number incorrect (%"PRIu64" != %"PRIu64")",
entry_seqnum,
le64toh(f->header->tail_entry_seqnum));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
@ -1301,13 +1356,19 @@ int journal_file_verify(
if (entry_monotonic_set && if (entry_monotonic_set &&
(sd_id128_equal(entry_boot_id, f->header->boot_id) && (sd_id128_equal(entry_boot_id, f->header->boot_id) &&
entry_monotonic != le64toh(f->header->tail_entry_monotonic))) { entry_monotonic != le64toh(f->header->tail_entry_monotonic))) {
error(0, "Invalid tail monotonic timestamp"); error(0,
"Invalid tail monotonic timestamp (%"PRIu64" != %"PRIu64")",
entry_monotonic,
le64toh(f->header->tail_entry_monotonic));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }
if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) { if (entry_realtime_set && entry_realtime != le64toh(f->header->tail_entry_realtime)) {
error(0, "Invalid tail realtime timestamp"); error(0,
"Invalid tail realtime timestamp (%"PRIu64" != %"PRIu64")",
entry_realtime,
le64toh(f->header->tail_entry_realtime));
r = -EBADMSG; r = -EBADMSG;
goto fail; goto fail;
} }

View File

@ -224,9 +224,9 @@ static void context_attach_window(Context *c, Window *w) {
if (w->in_unused) { if (w->in_unused) {
/* Used again? */ /* Used again? */
LIST_REMOVE(unused, c->cache->unused, w);
if (c->cache->last_unused == w) if (c->cache->last_unused == w)
c->cache->last_unused = w->unused_prev; c->cache->last_unused = w->unused_prev;
LIST_REMOVE(unused, c->cache->unused, w);
w->in_unused = false; w->in_unused = false;
} }

View File

@ -27,11 +27,11 @@ static int build_user_json(const char *user_name, uid_t uid, const char *real_na
JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(uid)), JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(uid)),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)),
JSON_BUILD_PAIR_CONDITION(!isempty(real_name), "realName", JSON_BUILD_STRING(real_name)), JSON_BUILD_PAIR_CONDITION(!isempty(real_name), "realName", JSON_BUILD_STRING(real_name)),
JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_STRING("/")), JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_CONST_STRING("/")),
JSON_BUILD_PAIR("shell", JSON_BUILD_STRING(NOLOGIN)), JSON_BUILD_PAIR("shell", JSON_BUILD_STRING(NOLOGIN)),
JSON_BUILD_PAIR("locked", JSON_BUILD_BOOLEAN(true)), JSON_BUILD_PAIR("locked", JSON_BUILD_BOOLEAN(true)),
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Machine")), JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.Machine")),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("container")))))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("container"))))));
} }
static bool user_match_lookup_parameters(LookupParameters *p, const char *name, uid_t uid) { static bool user_match_lookup_parameters(LookupParameters *p, const char *name, uid_t uid) {
@ -198,8 +198,8 @@ static int build_group_json(const char *group_name, gid_t gid, const char *descr
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)), JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(group_name)),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(gid)),
JSON_BUILD_PAIR_CONDITION(!isempty(description), "description", JSON_BUILD_STRING(description)), JSON_BUILD_PAIR_CONDITION(!isempty(description), "description", JSON_BUILD_STRING(description)),
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.Machine")), JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.Machine")),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("container")))))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("container"))))));
} }
static bool group_match_lookup_parameters(LookupParameters *p, const char *name, gid_t gid) { static bool group_match_lookup_parameters(LookupParameters *p, const char *name, gid_t gid) {

View File

@ -1201,8 +1201,8 @@ static int link_get_network(Link *link, Network **ret) {
r = net_match_config( r = net_match_config(
&network->match, &network->match,
link->sd_device, link->sd_device,
link->hw_addr.length == ETH_ALEN ? &link->hw_addr.ether : NULL, &link->hw_addr,
link->permanent_hw_addr.length == ETH_ALEN ? &link->permanent_hw_addr.ether : NULL, &link->permanent_hw_addr,
link->driver, link->driver,
link->iftype, link->iftype,
link->ifname, link->ifname,

View File

@ -56,6 +56,7 @@ typedef struct Link {
struct hw_addr_data hw_addr; struct hw_addr_data hw_addr;
struct hw_addr_data bcast_addr; struct hw_addr_data bcast_addr;
struct hw_addr_data permanent_hw_addr; struct hw_addr_data permanent_hw_addr;
struct hw_addr_data requested_hw_addr;
struct in6_addr ipv6ll_address; struct in6_addr ipv6ll_address;
uint32_t mtu; uint32_t mtu;
uint32_t min_mtu; uint32_t min_mtu;

View File

@ -7,7 +7,7 @@
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
static int property_get_ether_addrs( static int property_get_hw_addrs(
sd_bus *bus, sd_bus *bus,
const char *path, const char *path,
const char *interface, const char *interface,
@ -16,7 +16,7 @@ static int property_get_ether_addrs(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
const struct ether_addr *p; const struct hw_addr_data *p;
Set *s; Set *s;
int r; int r;
@ -31,7 +31,7 @@ static int property_get_ether_addrs(
return r; return r;
SET_FOREACH(p, s) { SET_FOREACH(p, s) {
r = sd_bus_message_append(reply, "s", ETHER_ADDR_TO_STR(p)); r = sd_bus_message_append(reply, "s", HW_ADDR_TO_STR(p));
if (r < 0) if (r < 0)
return r; return r;
} }
@ -44,7 +44,7 @@ static const sd_bus_vtable network_vtable[] = {
SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Description", "s", NULL, offsetof(Network, description), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Network, filename), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchMAC", "as", property_get_ether_addrs, offsetof(Network, match.mac), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchMAC", "as", property_get_hw_addrs, offsetof(Network, match.hw_addr), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match.path), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchPath", "as", NULL, offsetof(Network, match.path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match.driver), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchDriver", "as", NULL, offsetof(Network, match.driver), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match.iftype), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MatchType", "as", NULL, offsetof(Network, match.iftype), SD_BUS_VTABLE_PROPERTY_CONST),

View File

@ -45,8 +45,8 @@ struct ConfigPerfItem;
%struct-type %struct-type
%includes %includes
%% %%
Match.MACAddress, config_parse_ether_addrs, 0, offsetof(Network, match.mac) Match.MACAddress, config_parse_hw_addrs, 0, offsetof(Network, match.hw_addr)
Match.PermanentMACAddress, config_parse_ether_addrs, 0, offsetof(Network, match.permanent_mac) Match.PermanentMACAddress, config_parse_hw_addrs, 0, offsetof(Network, match.permanent_hw_addr)
Match.Path, config_parse_match_strv, 0, offsetof(Network, match.path) Match.Path, config_parse_match_strv, 0, offsetof(Network, match.path)
Match.Driver, config_parse_match_strv, 0, offsetof(Network, match.driver) Match.Driver, config_parse_match_strv, 0, offsetof(Network, match.driver)
Match.Type, config_parse_match_strv, 0, offsetof(Network, match.iftype) Match.Type, config_parse_match_strv, 0, offsetof(Network, match.iftype)
@ -61,7 +61,7 @@ Match.KernelCommandLine, config_parse_net_condition,
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, conditions) Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(Network, conditions)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, conditions) Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, conditions)
Match.Firmware, config_parse_net_condition, CONDITION_FIRMWARE, offsetof(Network, conditions) Match.Firmware, config_parse_net_condition, CONDITION_FIRMWARE, offsetof(Network, conditions)
Link.MACAddress, config_parse_ether_addr, 0, offsetof(Network, mac) Link.MACAddress, config_parse_hw_addr, 0, offsetof(Network, hw_addr)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu) Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(Network, mtu)
Link.Group, config_parse_link_group, 0, 0 Link.Group, config_parse_link_group, 0, 0
Link.ARP, config_parse_tristate, 0, offsetof(Network, arp) Link.ARP, config_parse_tristate, 0, offsetof(Network, arp)

View File

@ -674,7 +674,6 @@ static Network *network_free(Network *network) {
set_free(network->dhcp_allow_listed_ip); set_free(network->dhcp_allow_listed_ip);
set_free(network->dhcp_request_options); set_free(network->dhcp_request_options);
set_free(network->dhcp6_request_options); set_free(network->dhcp6_request_options);
free(network->mac);
free(network->dhcp6_mudurl); free(network->dhcp6_mudurl);
strv_free(network->dhcp6_user_class); strv_free(network->dhcp6_user_class);
strv_free(network->dhcp6_vendor_class); strv_free(network->dhcp6_vendor_class);

View File

@ -94,7 +94,7 @@ struct Network {
Hashmap *stacked_netdev_names; Hashmap *stacked_netdev_names;
/* [Link] section */ /* [Link] section */
struct ether_addr *mac; struct hw_addr_data hw_addr;
uint32_t mtu; uint32_t mtu;
int32_t group; int32_t group;
int arp; int arp;

View File

@ -6,6 +6,7 @@
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
#include "missing_network.h" #include "missing_network.h"
#include "netif-util.h"
#include "netlink-util.h" #include "netlink-util.h"
#include "networkd-address.h" #include "networkd-address.h"
#include "networkd-can.h" #include "networkd-can.h"
@ -183,7 +184,7 @@ static int link_set_mac_allow_retry_handler(sd_netlink *rtnl, sd_netlink_message
return 0; return 0;
} }
/* set_link_mac_handler() also decrement set_link_messages, so once increment the value. */ /* set_link_mac_handler() also decrements set_link_messages, so increment the value once. */
link->set_link_messages++; link->set_link_messages++;
return link_set_mac_handler(rtnl, m, link); return link_set_mac_handler(rtnl, m, link);
} }
@ -463,7 +464,7 @@ static int link_configure(
return log_link_debug_errno(link, r, "Could not append IFLA_GROUP attribute: %m"); return log_link_debug_errno(link, r, "Could not append IFLA_GROUP attribute: %m");
break; break;
case SET_LINK_MAC: case SET_LINK_MAC:
r = sd_netlink_message_append_ether_addr(req, IFLA_ADDRESS, link->network->mac); r = netlink_message_append_hw_addr(req, IFLA_ADDRESS, &link->requested_hw_addr);
if (r < 0) if (r < 0)
return log_link_debug_errno(link, r, "Could not append IFLA_ADDRESS attribute: %m"); return log_link_debug_errno(link, r, "Could not append IFLA_ADDRESS attribute: %m");
break; break;
@ -542,7 +543,7 @@ static bool link_is_ready_to_call_set_link(Request *req) {
break; break;
case SET_LINK_MAC: case SET_LINK_MAC:
if (req->netlink_handler == link_set_mac_handler) { if (req->netlink_handler == link_set_mac_handler) {
/* This is the second trial to set MTU. On the first attempt /* This is the second trial to set hardware address. On the first attempt
* req->netlink_handler points to link_set_mac_allow_retry_handler(). * req->netlink_handler points to link_set_mac_allow_retry_handler().
* The first trial failed as the interface was up. */ * The first trial failed as the interface was up. */
r = link_down(link); r = link_down(link);
@ -777,20 +778,21 @@ int link_request_to_set_group(Link *link) {
} }
int link_request_to_set_mac(Link *link, bool allow_retry) { int link_request_to_set_mac(Link *link, bool allow_retry) {
int r;
assert(link); assert(link);
assert(link->network); assert(link->network);
if (!link->network->mac) if (link->network->hw_addr.length == 0)
return 0; return 0;
if (link->hw_addr.length != sizeof(struct ether_addr)) { link->requested_hw_addr = link->network->hw_addr;
/* Note that for now we only support changing hardware addresses on Ethernet. */ r = net_verify_hardware_address(link->ifname, /* warn_invalid = */ true,
log_link_debug(link, "Size of the hardware address (%zu) does not match the size of MAC address (%zu), ignoring.", link->iftype, &link->hw_addr, &link->requested_hw_addr);
link->hw_addr.length, sizeof(struct ether_addr)); if (r < 0)
return 0; return r;
}
if (ether_addr_equal(&link->hw_addr.ether, link->network->mac)) if (hw_addr_equal(&link->hw_addr, &link->requested_hw_addr))
return 0; return 0;
return link_request_set_link(link, SET_LINK_MAC, return link_request_set_link(link, SET_LINK_MAC,

View File

@ -128,7 +128,7 @@ static int convert_user(
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(allocate_uid)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(allocate_uid)),
JSON_BUILD_PAIR_CONDITION(u->disposition >= 0, "disposition", JSON_BUILD_STRING(user_disposition_to_string(u->disposition))), JSON_BUILD_PAIR_CONDITION(u->disposition >= 0, "disposition", JSON_BUILD_STRING(user_disposition_to_string(u->disposition))),
JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_STRING(h)), JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_STRING(h)),
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.NSpawn")), JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.NSpawn")),
JSON_BUILD_PAIR_CONDITION(!strv_isempty(u->hashed_password), "privileged", JSON_BUILD_OBJECT( JSON_BUILD_PAIR_CONDITION(!strv_isempty(u->hashed_password), "privileged", JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_VARIANT(hp)))))); JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_VARIANT(hp))))));
if (r < 0) if (r < 0)
@ -140,7 +140,7 @@ static int convert_user(
JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(g->group_name)), JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(g->group_name)),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(allocate_uid)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(allocate_uid)),
JSON_BUILD_PAIR_CONDITION(g->disposition >= 0, "disposition", JSON_BUILD_STRING(user_disposition_to_string(g->disposition))), JSON_BUILD_PAIR_CONDITION(g->disposition >= 0, "disposition", JSON_BUILD_STRING(user_disposition_to_string(g->disposition))),
JSON_BUILD_PAIR("service", JSON_BUILD_STRING("io.systemd.NSpawn")))); JSON_BUILD_PAIR("service", JSON_BUILD_CONST_STRING("io.systemd.NSpawn"))));
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to build container group record: %m"); return log_error_errno(r, "Failed to build container group record: %m");

View File

@ -991,9 +991,8 @@ int dissect_image(
designator = PARTITION_XBOOTLDR; designator = PARTITION_XBOOTLDR;
rw = !(pflags & GPT_FLAG_READ_ONLY); rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
}
#ifdef GPT_ROOT_NATIVE } else if (gpt_partition_type_is_root(type_id)) {
else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
@ -1004,12 +1003,12 @@ int dissect_image(
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id)) if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
continue; continue;
designator = PARTITION_ROOT; assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
architecture = native_architecture(); designator = PARTITION_ROOT_OF_ARCH(architecture);
rw = !(pflags & GPT_FLAG_READ_ONLY); rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
} else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY)) { } else if (gpt_partition_type_is_root_verity(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
@ -1028,12 +1027,12 @@ int dissect_image(
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id)) if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id))
continue; continue;
designator = PARTITION_ROOT_VERITY; assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_OF(PARTITION_ROOT_OF_ARCH(architecture));
fstype = "DM_verity_hash"; fstype = "DM_verity_hash";
architecture = native_architecture();
rw = false; rw = false;
} else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY_SIG)) { } else if (gpt_partition_type_is_root_verity_sig(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
@ -1050,78 +1049,12 @@ int dissect_image(
if (verity->root_hash) if (verity->root_hash)
continue; continue;
designator = PARTITION_ROOT_VERITY_SIG; assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_SIG_OF(PARTITION_ROOT_OF_ARCH(architecture));
fstype = "verity_hash_signature"; fstype = "verity_hash_signature";
architecture = native_architecture();
rw = false;
}
#endif
#ifdef GPT_ROOT_SECONDARY
else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
if (pflags & GPT_FLAG_NO_AUTO)
continue;
/* If a root ID is specified, ignore everything but the root id */
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
continue;
designator = PARTITION_ROOT_SECONDARY;
architecture = SECONDARY_ARCHITECTURE;
rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
} else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (pflags & GPT_FLAG_NO_AUTO)
continue;
m->has_verity = true;
/* Don't do verity if no verity config is passed in */
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
continue;
/* If root hash is specified, then ignore everything but the root id */
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id))
continue;
designator = PARTITION_ROOT_SECONDARY_VERITY;
fstype = "DM_verity_hash";
architecture = SECONDARY_ARCHITECTURE;
rw = false; rw = false;
} else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY_SIG)) { } else if (gpt_partition_type_is_usr(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (pflags & GPT_FLAG_NO_AUTO)
continue;
m->has_verity_sig = true;
/* If root hash is specified explicitly, then ignore any embedded signature */
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
continue;
if (verity->root_hash)
continue;
designator = PARTITION_ROOT_SECONDARY_VERITY_SIG;
fstype = "verity_hash_signature";
architecture = native_architecture();
rw = false;
}
#endif
#ifdef GPT_USR_NATIVE
else if (sd_id128_equal(type_id, GPT_USR_NATIVE)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
@ -1132,12 +1065,12 @@ int dissect_image(
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id)) if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id))
continue; continue;
designator = PARTITION_USR; assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
architecture = native_architecture(); designator = PARTITION_USR_OF_ARCH(architecture);
rw = !(pflags & GPT_FLAG_READ_ONLY); rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
} else if (sd_id128_equal(type_id, GPT_USR_NATIVE_VERITY)) { } else if (gpt_partition_type_is_usr_verity(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
@ -1155,12 +1088,12 @@ int dissect_image(
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id)) if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id))
continue; continue;
designator = PARTITION_USR_VERITY; assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_OF(PARTITION_USR_OF_ARCH(architecture));
fstype = "DM_verity_hash"; fstype = "DM_verity_hash";
architecture = native_architecture();
rw = false; rw = false;
} else if (sd_id128_equal(type_id, GPT_USR_NATIVE_VERITY_SIG)) { } else if (gpt_partition_type_is_usr_verity_sig(type_id)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
@ -1177,76 +1110,12 @@ int dissect_image(
if (verity->root_hash) if (verity->root_hash)
continue; continue;
designator = PARTITION_USR_VERITY_SIG; assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0);
designator = PARTITION_VERITY_SIG_OF(PARTITION_USR_OF_ARCH(architecture));
fstype = "verity_hash_signature"; fstype = "verity_hash_signature";
architecture = native_architecture();
rw = false;
}
#endif
#ifdef GPT_USR_SECONDARY
else if (sd_id128_equal(type_id, GPT_USR_SECONDARY)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS);
if (pflags & GPT_FLAG_NO_AUTO)
continue;
/* If a usr ID is specified, ignore everything but the usr id */
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id))
continue;
designator = PARTITION_USR_SECONDARY;
architecture = SECONDARY_ARCHITECTURE;
rw = !(pflags & GPT_FLAG_READ_ONLY);
growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS);
} else if (sd_id128_equal(type_id, GPT_USR_SECONDARY_VERITY)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (pflags & GPT_FLAG_NO_AUTO)
continue;
m->has_verity = true;
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_USR)
continue;
/* If usr hash is specified, then ignore everything but the root id */
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id))
continue;
designator = PARTITION_USR_SECONDARY_VERITY;
fstype = "DM_verity_hash";
architecture = SECONDARY_ARCHITECTURE;
rw = false; rw = false;
} else if (sd_id128_equal(type_id, GPT_USR_SECONDARY_VERITY_SIG)) { } else if (sd_id128_equal(type_id, GPT_SWAP)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY);
if (pflags & GPT_FLAG_NO_AUTO)
continue;
m->has_verity_sig = true;
/* If usr hash is specified explicitly, then ignore any embedded signature */
if (!verity)
continue;
if (verity->designator >= 0 && verity->designator != PARTITION_USR)
continue;
if (verity->root_hash)
continue;
designator = PARTITION_USR_SECONDARY_VERITY_SIG;
fstype = "verity_hash_signature";
architecture = native_architecture();
rw = false;
}
#endif
else if (sd_id128_equal(type_id, GPT_SWAP)) {
check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO); check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO);
@ -1439,8 +1308,8 @@ int dissect_image(
} }
if (m->partitions[PARTITION_ROOT].found) { if (m->partitions[PARTITION_ROOT].found) {
/* If we found the primary arch, then invalidate the secondary arch to avoid any ambiguities, /* If we found the primary arch, then invalidate the secondary and other arch to avoid any
* since we never want to mount the secondary arch in this case. */ * ambiguities, since we never want to mount the secondary or other arch in this case. */
m->partitions[PARTITION_ROOT_SECONDARY].found = false; m->partitions[PARTITION_ROOT_SECONDARY].found = false;
m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false; m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false;
m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found = false; m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found = false;
@ -1448,6 +1317,13 @@ int dissect_image(
m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false; m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false;
m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false; m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false;
m->partitions[PARTITION_ROOT_OTHER].found = false;
m->partitions[PARTITION_ROOT_OTHER_VERITY].found = false;
m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG].found = false;
m->partitions[PARTITION_USR_OTHER].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
} else if (m->partitions[PARTITION_ROOT_VERITY].found || } else if (m->partitions[PARTITION_ROOT_VERITY].found ||
m->partitions[PARTITION_ROOT_VERITY_SIG].found) m->partitions[PARTITION_ROOT_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */ return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */
@ -1455,7 +1331,10 @@ int dissect_image(
else if (m->partitions[PARTITION_ROOT_SECONDARY].found) { else if (m->partitions[PARTITION_ROOT_SECONDARY].found) {
/* No root partition found but there's one for the secondary architecture? Then upgrade /* No root partition found but there's one for the secondary architecture? Then upgrade
* secondary arch to first */ * secondary arch to first and invalidate the other arch. */
log_debug("No root partition found of the native architecture, falling back to a root "
"partition of the secondary architecture.");
m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY]; m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_SECONDARY];
zero(m->partitions[PARTITION_ROOT_SECONDARY]); zero(m->partitions[PARTITION_ROOT_SECONDARY]);
@ -1471,26 +1350,64 @@ int dissect_image(
m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]; m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG];
zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]); zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]);
m->partitions[PARTITION_ROOT_OTHER].found = false;
m->partitions[PARTITION_ROOT_OTHER_VERITY].found = false;
m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG].found = false;
m->partitions[PARTITION_USR_OTHER].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
} else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found || } else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found ||
m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found) m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* as above */ return -EADDRNOTAVAIL; /* as above */
else if (m->partitions[PARTITION_ROOT_OTHER].found) {
/* No root or secondary partition found but there's one for another architecture? Then
* upgrade the other architecture to first. */
log_debug("No root partition found of the native architecture or the secondary architecture, "
"falling back to a root partition of a non-native architecture (%s).",
architecture_to_string(m->partitions[PARTITION_ROOT_OTHER].architecture));
m->partitions[PARTITION_ROOT] = m->partitions[PARTITION_ROOT_OTHER];
zero(m->partitions[PARTITION_ROOT_OTHER]);
m->partitions[PARTITION_ROOT_VERITY] = m->partitions[PARTITION_ROOT_OTHER_VERITY];
zero(m->partitions[PARTITION_ROOT_OTHER_VERITY]);
m->partitions[PARTITION_ROOT_VERITY_SIG] = m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG];
zero(m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG]);
m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_OTHER];
zero(m->partitions[PARTITION_USR_OTHER]);
m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_OTHER_VERITY];
zero(m->partitions[PARTITION_USR_OTHER_VERITY]);
m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_OTHER_VERITY_SIG];
zero(m->partitions[PARTITION_USR_OTHER_VERITY_SIG]);
}
/* Hmm, we found a signature partition but no Verity data? Something is off. */ /* Hmm, we found a signature partition but no Verity data? Something is off. */
if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found) if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
if (m->partitions[PARTITION_USR].found) { if (m->partitions[PARTITION_USR].found) {
/* Invalidate secondary arch /usr/ if we found the primary arch */ /* Invalidate secondary and other arch /usr/ if we found the primary arch */
m->partitions[PARTITION_USR_SECONDARY].found = false; m->partitions[PARTITION_USR_SECONDARY].found = false;
m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false; m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false;
m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false; m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false;
m->partitions[PARTITION_USR_OTHER].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
} else if (m->partitions[PARTITION_USR_VERITY].found || } else if (m->partitions[PARTITION_USR_VERITY].found ||
m->partitions[PARTITION_USR_VERITY_SIG].found) m->partitions[PARTITION_USR_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* as above */ return -EADDRNOTAVAIL; /* as above */
else if (m->partitions[PARTITION_USR_SECONDARY].found) { else if (m->partitions[PARTITION_USR_SECONDARY].found) {
log_debug("No usr partition found of the native architecture, falling back to a usr "
"partition of the secondary architecture.");
/* Upgrade secondary arch to primary */ /* Upgrade secondary arch to primary */
m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY]; m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_SECONDARY];
zero(m->partitions[PARTITION_USR_SECONDARY]); zero(m->partitions[PARTITION_USR_SECONDARY]);
@ -1499,10 +1416,29 @@ int dissect_image(
m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]; m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG];
zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]); zero(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]);
m->partitions[PARTITION_USR_OTHER].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY].found = false;
m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false;
} else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found || } else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found ||
m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found) m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found)
return -EADDRNOTAVAIL; /* as above */ return -EADDRNOTAVAIL; /* as above */
else if (m->partitions[PARTITION_USR_OTHER].found) {
log_debug("No usr partition found of the native architecture or the secondary architecture, "
"falling back to a usr partition of a non-native architecture (%s).",
architecture_to_string(m->partitions[PARTITION_ROOT_OTHER].architecture));
/* Upgrade other arch to primary */
m->partitions[PARTITION_USR] = m->partitions[PARTITION_USR_OTHER];
zero(m->partitions[PARTITION_USR_OTHER]);
m->partitions[PARTITION_USR_VERITY] = m->partitions[PARTITION_USR_OTHER_VERITY];
zero(m->partitions[PARTITION_USR_OTHER_VERITY]);
m->partitions[PARTITION_USR_VERITY_SIG] = m->partitions[PARTITION_USR_OTHER_VERITY_SIG];
zero(m->partitions[PARTITION_USR_OTHER_VERITY_SIG]);
}
/* Hmm, we found a signature partition but no Verity data? Something is off. */ /* Hmm, we found a signature partition but no Verity data? Something is off. */
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found) if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
@ -3500,8 +3436,10 @@ int mount_image_privately_interactively(
static const char *const partition_designator_table[] = { static const char *const partition_designator_table[] = {
[PARTITION_ROOT] = "root", [PARTITION_ROOT] = "root",
[PARTITION_ROOT_SECONDARY] = "root-secondary", [PARTITION_ROOT_SECONDARY] = "root-secondary",
[PARTITION_ROOT_OTHER] = "root-other",
[PARTITION_USR] = "usr", [PARTITION_USR] = "usr",
[PARTITION_USR_SECONDARY] = "usr-secondary", [PARTITION_USR_SECONDARY] = "usr-secondary",
[PARTITION_USR_OTHER] = "usr-other",
[PARTITION_HOME] = "home", [PARTITION_HOME] = "home",
[PARTITION_SRV] = "srv", [PARTITION_SRV] = "srv",
[PARTITION_ESP] = "esp", [PARTITION_ESP] = "esp",
@ -3509,12 +3447,16 @@ static const char *const partition_designator_table[] = {
[PARTITION_SWAP] = "swap", [PARTITION_SWAP] = "swap",
[PARTITION_ROOT_VERITY] = "root-verity", [PARTITION_ROOT_VERITY] = "root-verity",
[PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity", [PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity",
[PARTITION_ROOT_OTHER_VERITY] = "root-other-verity",
[PARTITION_USR_VERITY] = "usr-verity", [PARTITION_USR_VERITY] = "usr-verity",
[PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity", [PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity",
[PARTITION_USR_OTHER_VERITY] = "usr-other-verity",
[PARTITION_ROOT_VERITY_SIG] = "root-verity-sig", [PARTITION_ROOT_VERITY_SIG] = "root-verity-sig",
[PARTITION_ROOT_SECONDARY_VERITY_SIG] = "root-secondary-verity-sig", [PARTITION_ROOT_SECONDARY_VERITY_SIG] = "root-secondary-verity-sig",
[PARTITION_ROOT_OTHER_VERITY_SIG] = "root-other-verity-sig",
[PARTITION_USR_VERITY_SIG] = "usr-verity-sig", [PARTITION_USR_VERITY_SIG] = "usr-verity-sig",
[PARTITION_USR_SECONDARY_VERITY_SIG] = "usr-secondary-verity-sig", [PARTITION_USR_SECONDARY_VERITY_SIG] = "usr-secondary-verity-sig",
[PARTITION_USR_OTHER_VERITY_SIG] = "usr-other-verity-sig",
[PARTITION_TMP] = "tmp", [PARTITION_TMP] = "tmp",
[PARTITION_VAR] = "var", [PARTITION_VAR] = "var",
}; };

View File

@ -5,6 +5,7 @@
#include "sd-id128.h" #include "sd-id128.h"
#include "architecture.h"
#include "list.h" #include "list.h"
#include "loop-util.h" #include "loop-util.h"
#include "macro.h" #include "macro.h"
@ -35,8 +36,10 @@ struct DissectedPartition {
typedef enum PartitionDesignator { typedef enum PartitionDesignator {
PARTITION_ROOT, PARTITION_ROOT,
PARTITION_ROOT_SECONDARY, /* Secondary architecture */ PARTITION_ROOT_SECONDARY, /* Secondary architecture */
PARTITION_ROOT_OTHER,
PARTITION_USR, PARTITION_USR,
PARTITION_USR_SECONDARY, PARTITION_USR_SECONDARY,
PARTITION_USR_OTHER,
PARTITION_HOME, PARTITION_HOME,
PARTITION_SRV, PARTITION_SRV,
PARTITION_ESP, PARTITION_ESP,
@ -44,12 +47,16 @@ typedef enum PartitionDesignator {
PARTITION_SWAP, PARTITION_SWAP,
PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */ PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */
PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */ PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */
PARTITION_ROOT_OTHER_VERITY,
PARTITION_USR_VERITY, PARTITION_USR_VERITY,
PARTITION_USR_SECONDARY_VERITY, PARTITION_USR_SECONDARY_VERITY,
PARTITION_USR_OTHER_VERITY,
PARTITION_ROOT_VERITY_SIG, /* PKCS#7 signature for root hash for the PARTITION_ROOT partition */ PARTITION_ROOT_VERITY_SIG, /* PKCS#7 signature for root hash for the PARTITION_ROOT partition */
PARTITION_ROOT_SECONDARY_VERITY_SIG, /* ditto for the PARTITION_ROOT_SECONDARY partition */ PARTITION_ROOT_SECONDARY_VERITY_SIG, /* ditto for the PARTITION_ROOT_SECONDARY partition */
PARTITION_ROOT_OTHER_VERITY_SIG,
PARTITION_USR_VERITY_SIG, PARTITION_USR_VERITY_SIG,
PARTITION_USR_SECONDARY_VERITY_SIG, PARTITION_USR_SECONDARY_VERITY_SIG,
PARTITION_USR_OTHER_VERITY_SIG,
PARTITION_TMP, PARTITION_TMP,
PARTITION_VAR, PARTITION_VAR,
_PARTITION_DESIGNATOR_MAX, _PARTITION_DESIGNATOR_MAX,
@ -65,16 +72,22 @@ static inline bool PARTITION_DESIGNATOR_VERSIONED(PartitionDesignator d) {
return IN_SET(d, return IN_SET(d,
PARTITION_ROOT, PARTITION_ROOT,
PARTITION_ROOT_SECONDARY, PARTITION_ROOT_SECONDARY,
PARTITION_ROOT_OTHER,
PARTITION_USR, PARTITION_USR,
PARTITION_USR_SECONDARY, PARTITION_USR_SECONDARY,
PARTITION_USR_OTHER,
PARTITION_ROOT_VERITY, PARTITION_ROOT_VERITY,
PARTITION_ROOT_SECONDARY_VERITY, PARTITION_ROOT_SECONDARY_VERITY,
PARTITION_ROOT_OTHER_VERITY,
PARTITION_USR_VERITY, PARTITION_USR_VERITY,
PARTITION_USR_SECONDARY_VERITY, PARTITION_USR_SECONDARY_VERITY,
PARTITION_USR_OTHER_VERITY,
PARTITION_ROOT_VERITY_SIG, PARTITION_ROOT_VERITY_SIG,
PARTITION_ROOT_SECONDARY_VERITY_SIG, PARTITION_ROOT_SECONDARY_VERITY_SIG,
PARTITION_ROOT_OTHER_VERITY_SIG,
PARTITION_USR_VERITY_SIG, PARTITION_USR_VERITY_SIG,
PARTITION_USR_SECONDARY_VERITY_SIG); PARTITION_USR_SECONDARY_VERITY_SIG,
PARTITION_USR_OTHER_VERITY_SIG);
} }
static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) { static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) {
@ -86,12 +99,18 @@ static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) {
case PARTITION_ROOT_SECONDARY: case PARTITION_ROOT_SECONDARY:
return PARTITION_ROOT_SECONDARY_VERITY; return PARTITION_ROOT_SECONDARY_VERITY;
case PARTITION_ROOT_OTHER:
return PARTITION_ROOT_OTHER_VERITY;
case PARTITION_USR: case PARTITION_USR:
return PARTITION_USR_VERITY; return PARTITION_USR_VERITY;
case PARTITION_USR_SECONDARY: case PARTITION_USR_SECONDARY:
return PARTITION_USR_SECONDARY_VERITY; return PARTITION_USR_SECONDARY_VERITY;
case PARTITION_USR_OTHER:
return PARTITION_USR_OTHER_VERITY;
default: default:
return _PARTITION_DESIGNATOR_INVALID; return _PARTITION_DESIGNATOR_INVALID;
} }
@ -106,17 +125,55 @@ static inline PartitionDesignator PARTITION_VERITY_SIG_OF(PartitionDesignator p)
case PARTITION_ROOT_SECONDARY: case PARTITION_ROOT_SECONDARY:
return PARTITION_ROOT_SECONDARY_VERITY_SIG; return PARTITION_ROOT_SECONDARY_VERITY_SIG;
case PARTITION_ROOT_OTHER:
return PARTITION_ROOT_OTHER_VERITY_SIG;
case PARTITION_USR: case PARTITION_USR:
return PARTITION_USR_VERITY_SIG; return PARTITION_USR_VERITY_SIG;
case PARTITION_USR_SECONDARY: case PARTITION_USR_SECONDARY:
return PARTITION_USR_SECONDARY_VERITY_SIG; return PARTITION_USR_SECONDARY_VERITY_SIG;
case PARTITION_USR_OTHER:
return PARTITION_USR_OTHER_VERITY_SIG;
default: default:
return _PARTITION_DESIGNATOR_INVALID; return _PARTITION_DESIGNATOR_INVALID;
} }
} }
static inline PartitionDesignator PARTITION_ROOT_OF_ARCH(Architecture arch) {
switch (arch) {
case native_architecture():
return PARTITION_ROOT;
#ifdef ARCHITECTURE_SECONDARY
case ARCHITECTURE_SECONDARY:
return PARTITION_ROOT_SECONDARY;
#endif
default:
return PARTITION_ROOT_OTHER;
}
}
static inline PartitionDesignator PARTITION_USR_OF_ARCH(Architecture arch) {
switch (arch) {
case native_architecture():
return PARTITION_USR;
#ifdef ARCHITECTURE_SECONDARY
case ARCHITECTURE_SECONDARY:
return PARTITION_USR_SECONDARY;
#endif
default:
return PARTITION_USR_OTHER;
}
}
typedef enum DissectImageFlags { typedef enum DissectImageFlags {
DISSECT_IMAGE_DEVICE_READ_ONLY = 1 << 0, /* Make device read-only */ DISSECT_IMAGE_DEVICE_READ_ONLY = 1 << 0, /* Make device read-only */
DISSECT_IMAGE_DISCARD_ON_LOOP = 1 << 1, /* Turn on "discard" if on a loop device and file system supports it */ DISSECT_IMAGE_DISCARD_ON_LOOP = 1 << 1, /* Turn on "discard" if on a loop device and file system supports it */

View File

@ -15,12 +15,12 @@
#endif #endif
#define _GPT_ARCH_SEXTET(arch, name) \ #define _GPT_ARCH_SEXTET(arch, name) \
{ GPT_ROOT_##arch, "root-" name }, \ { GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .is_root = true }, \
{ GPT_ROOT_##arch##_VERITY, "root-" name "-verity" }, \ { GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .is_root_verity = true }, \
{ GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig" }, \ { GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ARCHITECTURE_##arch, .is_root_verity_sig = true }, \
{ GPT_USR_##arch, "usr-" name }, \ { GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .is_usr = true }, \
{ GPT_USR_##arch##_VERITY, "usr-" name "-verity" }, \ { GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .is_usr_verity = true }, \
{ GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig" } { GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .is_usr_verity_sig = true }
const GptPartitionType gpt_partition_type_table[] = { const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(ALPHA, "alpha"), _GPT_ARCH_SEXTET(ALPHA, "alpha"),
@ -28,12 +28,21 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(ARM, "arm"), _GPT_ARCH_SEXTET(ARM, "arm"),
_GPT_ARCH_SEXTET(ARM64, "arm64"), _GPT_ARCH_SEXTET(ARM64, "arm64"),
_GPT_ARCH_SEXTET(IA64, "ia64"), _GPT_ARCH_SEXTET(IA64, "ia64"),
_GPT_ARCH_SEXTET(LOONGARCH64, "loongarch64"),
// TODO: Replace with `_GPT_ARCH_SEXTET(LOONGARCH64, "loongarch64")` once
// https://github.com/systemd/systemd/pull/21288 is merged. */
{ GPT_ROOT_LOONGARCH64, "root-loongarch64", _ARCHITECTURE_INVALID, .is_root = true },
{ GPT_ROOT_LOONGARCH64_VERITY, "root-loongarch64-verity", _ARCHITECTURE_INVALID, .is_root_verity = true },
{ GPT_ROOT_LOONGARCH64_VERITY_SIG, "root-loongarch64-verity-sig", _ARCHITECTURE_INVALID, .is_root_verity_sig = true },
{ GPT_USR_LOONGARCH64, "usr-loongarch64", _ARCHITECTURE_INVALID, .is_usr = true },
{ GPT_USR_LOONGARCH64_VERITY, "usr-loongarch64-verity", _ARCHITECTURE_INVALID, .is_usr_verity = true },
{ GPT_USR_LOONGARCH64_VERITY_SIG, "usr-loongarch64-verity-sig", _ARCHITECTURE_INVALID, .is_usr_verity_sig = true },
_GPT_ARCH_SEXTET(MIPS_LE, "mips-le"), _GPT_ARCH_SEXTET(MIPS_LE, "mips-le"),
_GPT_ARCH_SEXTET(MIPS64_LE, "mips64-le"), _GPT_ARCH_SEXTET(MIPS64_LE, "mips64-le"),
_GPT_ARCH_SEXTET(PPC, "ppc"), _GPT_ARCH_SEXTET(PPC, "ppc"),
_GPT_ARCH_SEXTET(PPC64, "ppc64"), _GPT_ARCH_SEXTET(PPC64, "ppc64"),
_GPT_ARCH_SEXTET(PPC64LE, "ppc64-le"), _GPT_ARCH_SEXTET(PPC64_LE, "ppc64-le"),
_GPT_ARCH_SEXTET(RISCV32, "riscv32"), _GPT_ARCH_SEXTET(RISCV32, "riscv32"),
_GPT_ARCH_SEXTET(RISCV64, "riscv64"), _GPT_ARCH_SEXTET(RISCV64, "riscv64"),
_GPT_ARCH_SEXTET(S390, "s390"), _GPT_ARCH_SEXTET(S390, "s390"),
@ -42,49 +51,29 @@ const GptPartitionType gpt_partition_type_table[] = {
_GPT_ARCH_SEXTET(X86, "x86"), _GPT_ARCH_SEXTET(X86, "x86"),
_GPT_ARCH_SEXTET(X86_64, "x86-64"), _GPT_ARCH_SEXTET(X86_64, "x86-64"),
#ifdef GPT_ROOT_NATIVE #ifdef GPT_ROOT_NATIVE
{ GPT_ROOT_NATIVE, "root" }, { GPT_ROOT_NATIVE, "root", native_architecture(), .is_root = true },
{ GPT_ROOT_NATIVE_VERITY, "root-verity" }, { GPT_ROOT_NATIVE_VERITY, "root-verity", native_architecture(), .is_root_verity = true },
{ GPT_ROOT_NATIVE_VERITY_SIG, "root-verity-sig" }, { GPT_ROOT_NATIVE_VERITY_SIG, "root-verity-sig", native_architecture(), .is_root_verity_sig = true },
{ GPT_USR_NATIVE, "usr" }, { GPT_USR_NATIVE, "usr", native_architecture(), .is_usr = true },
{ GPT_USR_NATIVE_VERITY, "usr-verity" }, { GPT_USR_NATIVE_VERITY, "usr-verity", native_architecture(), .is_usr_verity = true },
{ GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig" }, { GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig", native_architecture(), .is_usr_verity_sig = true },
#endif #endif
#ifdef GPT_ROOT_SECONDARY #ifdef GPT_ROOT_SECONDARY
_GPT_ARCH_SEXTET(SECONDARY, "secondary"), _GPT_ARCH_SEXTET(SECONDARY, "secondary"),
#endif #endif
{ GPT_ESP, "esp" }, { GPT_ESP, "esp", _ARCHITECTURE_INVALID },
{ GPT_XBOOTLDR, "xbootldr" }, { GPT_XBOOTLDR, "xbootldr", _ARCHITECTURE_INVALID },
{ GPT_SWAP, "swap" }, { GPT_SWAP, "swap", _ARCHITECTURE_INVALID },
{ GPT_HOME, "home" }, { GPT_HOME, "home", _ARCHITECTURE_INVALID },
{ GPT_SRV, "srv" }, { GPT_SRV, "srv", _ARCHITECTURE_INVALID },
{ GPT_VAR, "var" }, { GPT_VAR, "var", _ARCHITECTURE_INVALID },
{ GPT_TMP, "tmp" }, { GPT_TMP, "tmp", _ARCHITECTURE_INVALID },
{ GPT_USER_HOME, "user-home" }, { GPT_USER_HOME, "user-home", _ARCHITECTURE_INVALID },
{ GPT_LINUX_GENERIC, "linux-generic" }, { GPT_LINUX_GENERIC, "linux-generic", _ARCHITECTURE_INVALID },
{} {}
}; };
#define _GPT_ALL_ARCHES(type,suffix) \
GPT_##type##_ALPHA##suffix, \
GPT_##type##_ARC##suffix, \
GPT_##type##_ARM##suffix, \
GPT_##type##_ARM64##suffix, \
GPT_##type##_IA64##suffix, \
GPT_##type##_LOONGARCH64##suffix, \
GPT_##type##_MIPS_LE##suffix, \
GPT_##type##_MIPS64_LE##suffix, \
GPT_##type##_PPC##suffix, \
GPT_##type##_PPC64##suffix, \
GPT_##type##_PPC64LE##suffix, \
GPT_##type##_RISCV32##suffix, \
GPT_##type##_RISCV64##suffix, \
GPT_##type##_S390##suffix, \
GPT_##type##_S390X##suffix, \
GPT_##type##_TILEGX##suffix, \
GPT_##type##_X86##suffix, \
GPT_##type##_X86_64##suffix
const char *gpt_partition_type_uuid_to_string(sd_id128_t id) { const char *gpt_partition_type_uuid_to_string(sd_id128_t id) {
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++) for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
if (sd_id128_equal(id, gpt_partition_type_table[i].uuid)) if (sd_id128_equal(id, gpt_partition_type_table[i].uuid))
@ -121,6 +110,14 @@ int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) {
return sd_id128_from_string(s, ret); return sd_id128_from_string(s, ret);
} }
Architecture gpt_partition_type_uuid_to_arch(sd_id128_t id) {
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
if (sd_id128_equal(id, gpt_partition_type_table[i].uuid))
return gpt_partition_type_table[i].arch;
return _ARCHITECTURE_INVALID;
}
int gpt_partition_label_valid(const char *s) { int gpt_partition_label_valid(const char *s) {
_cleanup_free_ char16_t *recoded = NULL; _cleanup_free_ char16_t *recoded = NULL;
@ -131,20 +128,36 @@ int gpt_partition_label_valid(const char *s) {
return char16_strlen(recoded) <= GPT_LABEL_MAX; return char16_strlen(recoded) <= GPT_LABEL_MAX;
} }
static GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) {
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
if (sd_id128_equal(id, gpt_partition_type_table[i].uuid))
return gpt_partition_type_table[i];
return (GptPartitionType) { .uuid = id, .arch = _ARCHITECTURE_INVALID };
}
bool gpt_partition_type_is_root(sd_id128_t id) { bool gpt_partition_type_is_root(sd_id128_t id) {
return sd_id128_in_set(id, _GPT_ALL_ARCHES(ROOT,)); return gpt_partition_type_from_uuid(id).is_root;
} }
bool gpt_partition_type_is_root_verity(sd_id128_t id) { bool gpt_partition_type_is_root_verity(sd_id128_t id) {
return sd_id128_in_set(id, _GPT_ALL_ARCHES(ROOT, _VERITY)); return gpt_partition_type_from_uuid(id).is_root_verity;
}
bool gpt_partition_type_is_root_verity_sig(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_root_verity_sig;
} }
bool gpt_partition_type_is_usr(sd_id128_t id) { bool gpt_partition_type_is_usr(sd_id128_t id) {
return sd_id128_in_set(id, _GPT_ALL_ARCHES(USR,)); return gpt_partition_type_from_uuid(id).is_usr;
} }
bool gpt_partition_type_is_usr_verity(sd_id128_t id) { bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
return sd_id128_in_set(id, _GPT_ALL_ARCHES(USR, _VERITY)); return gpt_partition_type_from_uuid(id).is_usr_verity;
}
bool gpt_partition_type_is_usr_verity_sig(sd_id128_t id) {
return gpt_partition_type_from_uuid(id).is_usr_verity_sig;
} }
bool gpt_partition_type_knows_read_only(sd_id128_t id) { bool gpt_partition_type_knows_read_only(sd_id128_t id) {

View File

@ -5,6 +5,7 @@
#include "sd-id128.h" #include "sd-id128.h"
#include "architecture.h"
#include "id128-util.h" #include "id128-util.h"
#define GPT_ROOT_ALPHA SD_ID128_MAKE(65,23,f8,ae,3e,b1,4e,2a,a0,5a,18,b6,95,ae,65,6f) #define GPT_ROOT_ALPHA SD_ID128_MAKE(65,23,f8,ae,3e,b1,4e,2a,a0,5a,18,b6,95,ae,65,6f)
@ -17,7 +18,7 @@
#define GPT_ROOT_MIPS64_LE SD_ID128_MAKE(70,0b,da,43,7a,34,45,07,b1,79,ee,b9,3d,7a,7c,a3) #define GPT_ROOT_MIPS64_LE SD_ID128_MAKE(70,0b,da,43,7a,34,45,07,b1,79,ee,b9,3d,7a,7c,a3)
#define GPT_ROOT_PPC SD_ID128_MAKE(1d,e3,f1,ef,fa,98,47,b5,8d,cd,4a,86,0a,65,4d,78) #define GPT_ROOT_PPC SD_ID128_MAKE(1d,e3,f1,ef,fa,98,47,b5,8d,cd,4a,86,0a,65,4d,78)
#define GPT_ROOT_PPC64 SD_ID128_MAKE(91,2a,de,1d,a8,39,49,13,89,64,a1,0e,ee,08,fb,d2) #define GPT_ROOT_PPC64 SD_ID128_MAKE(91,2a,de,1d,a8,39,49,13,89,64,a1,0e,ee,08,fb,d2)
#define GPT_ROOT_PPC64LE SD_ID128_MAKE(c3,1c,45,e6,3f,39,41,2e,80,fb,48,09,c4,98,05,99) #define GPT_ROOT_PPC64_LE SD_ID128_MAKE(c3,1c,45,e6,3f,39,41,2e,80,fb,48,09,c4,98,05,99)
#define GPT_ROOT_RISCV32 SD_ID128_MAKE(60,d5,a7,fe,8e,7d,43,5c,b7,14,3d,d8,16,21,44,e1) #define GPT_ROOT_RISCV32 SD_ID128_MAKE(60,d5,a7,fe,8e,7d,43,5c,b7,14,3d,d8,16,21,44,e1)
#define GPT_ROOT_RISCV64 SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24) #define GPT_ROOT_RISCV64 SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24)
#define GPT_ROOT_S390 SD_ID128_MAKE(08,a7,ac,ea,62,4c,4a,20,91,e8,6e,0f,a6,7d,23,f9) #define GPT_ROOT_S390 SD_ID128_MAKE(08,a7,ac,ea,62,4c,4a,20,91,e8,6e,0f,a6,7d,23,f9)
@ -35,7 +36,7 @@
#define GPT_USR_MIPS64_LE SD_ID128_MAKE(c9,7c,1f,32,ba,06,40,b4,9f,22,23,60,61,b0,8a,a8) #define GPT_USR_MIPS64_LE SD_ID128_MAKE(c9,7c,1f,32,ba,06,40,b4,9f,22,23,60,61,b0,8a,a8)
#define GPT_USR_PPC SD_ID128_MAKE(7d,14,fe,c5,cc,71,41,5d,9d,6c,06,bf,0b,3c,3e,af) #define GPT_USR_PPC SD_ID128_MAKE(7d,14,fe,c5,cc,71,41,5d,9d,6c,06,bf,0b,3c,3e,af)
#define GPT_USR_PPC64 SD_ID128_MAKE(2c,97,39,e2,f0,68,46,b3,9f,d0,01,c5,a9,af,bc,ca) #define GPT_USR_PPC64 SD_ID128_MAKE(2c,97,39,e2,f0,68,46,b3,9f,d0,01,c5,a9,af,bc,ca)
#define GPT_USR_PPC64LE SD_ID128_MAKE(15,bb,03,af,77,e7,4d,4a,b1,2b,c0,d0,84,f7,49,1c) #define GPT_USR_PPC64_LE SD_ID128_MAKE(15,bb,03,af,77,e7,4d,4a,b1,2b,c0,d0,84,f7,49,1c)
#define GPT_USR_RISCV32 SD_ID128_MAKE(b9,33,fb,22,5c,3f,4f,91,af,90,e2,bb,0f,a5,07,02) #define GPT_USR_RISCV32 SD_ID128_MAKE(b9,33,fb,22,5c,3f,4f,91,af,90,e2,bb,0f,a5,07,02)
#define GPT_USR_RISCV64 SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d) #define GPT_USR_RISCV64 SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d)
#define GPT_USR_S390 SD_ID128_MAKE(cd,0f,86,9b,d0,fb,4c,a0,b1,41,9e,a8,7c,c7,8d,66) #define GPT_USR_S390 SD_ID128_MAKE(cd,0f,86,9b,d0,fb,4c,a0,b1,41,9e,a8,7c,c7,8d,66)
@ -54,7 +55,7 @@
#define GPT_ROOT_LOONGARCH64_VERITY SD_ID128_MAKE(f3,39,3b,22,e9,af,46,13,a9,48,9d,3b,fb,d0,c5,35) #define GPT_ROOT_LOONGARCH64_VERITY SD_ID128_MAKE(f3,39,3b,22,e9,af,46,13,a9,48,9d,3b,fb,d0,c5,35)
#define GPT_ROOT_MIPS_LE_VERITY SD_ID128_MAKE(d7,d1,50,d2,2a,04,4a,33,8f,12,16,65,12,05,ff,7b) #define GPT_ROOT_MIPS_LE_VERITY SD_ID128_MAKE(d7,d1,50,d2,2a,04,4a,33,8f,12,16,65,12,05,ff,7b)
#define GPT_ROOT_MIPS64_LE_VERITY SD_ID128_MAKE(16,b4,17,f8,3e,06,4f,57,8d,d2,9b,52,32,f4,1a,a6) #define GPT_ROOT_MIPS64_LE_VERITY SD_ID128_MAKE(16,b4,17,f8,3e,06,4f,57,8d,d2,9b,52,32,f4,1a,a6)
#define GPT_ROOT_PPC64LE_VERITY SD_ID128_MAKE(90,6b,d9,44,45,89,4a,ae,a4,e4,dd,98,39,17,44,6a) #define GPT_ROOT_PPC64_LE_VERITY SD_ID128_MAKE(90,6b,d9,44,45,89,4a,ae,a4,e4,dd,98,39,17,44,6a)
#define GPT_ROOT_PPC64_VERITY SD_ID128_MAKE(92,25,a9,a3,3c,19,4d,89,b4,f6,ee,ff,88,f1,76,31) #define GPT_ROOT_PPC64_VERITY SD_ID128_MAKE(92,25,a9,a3,3c,19,4d,89,b4,f6,ee,ff,88,f1,76,31)
#define GPT_ROOT_PPC_VERITY SD_ID128_MAKE(98,cf,e6,49,15,88,46,dc,b2,f0,ad,d1,47,42,49,25) #define GPT_ROOT_PPC_VERITY SD_ID128_MAKE(98,cf,e6,49,15,88,46,dc,b2,f0,ad,d1,47,42,49,25)
#define GPT_ROOT_RISCV32_VERITY SD_ID128_MAKE(ae,02,53,be,11,67,40,07,ac,68,43,92,6c,14,c5,de) #define GPT_ROOT_RISCV32_VERITY SD_ID128_MAKE(ae,02,53,be,11,67,40,07,ac,68,43,92,6c,14,c5,de)
@ -72,7 +73,7 @@
#define GPT_USR_LOONGARCH64_VERITY SD_ID128_MAKE(f4,6b,2c,26,59,ae,48,f0,91,06,c5,0e,d4,7f,67,3d) #define GPT_USR_LOONGARCH64_VERITY SD_ID128_MAKE(f4,6b,2c,26,59,ae,48,f0,91,06,c5,0e,d4,7f,67,3d)
#define GPT_USR_MIPS_LE_VERITY SD_ID128_MAKE(46,b9,8d,8d,b5,5c,4e,8f,aa,b3,37,fc,a7,f8,07,52) #define GPT_USR_MIPS_LE_VERITY SD_ID128_MAKE(46,b9,8d,8d,b5,5c,4e,8f,aa,b3,37,fc,a7,f8,07,52)
#define GPT_USR_MIPS64_LE_VERITY SD_ID128_MAKE(3c,3d,61,fe,b5,f3,41,4d,bb,71,87,39,a6,94,a4,ef) #define GPT_USR_MIPS64_LE_VERITY SD_ID128_MAKE(3c,3d,61,fe,b5,f3,41,4d,bb,71,87,39,a6,94,a4,ef)
#define GPT_USR_PPC64LE_VERITY SD_ID128_MAKE(ee,2b,99,83,21,e8,41,53,86,d9,b6,90,1a,54,d1,ce) #define GPT_USR_PPC64_LE_VERITY SD_ID128_MAKE(ee,2b,99,83,21,e8,41,53,86,d9,b6,90,1a,54,d1,ce)
#define GPT_USR_PPC64_VERITY SD_ID128_MAKE(bd,b5,28,a5,a2,59,47,5f,a8,7d,da,53,fa,73,6a,07) #define GPT_USR_PPC64_VERITY SD_ID128_MAKE(bd,b5,28,a5,a2,59,47,5f,a8,7d,da,53,fa,73,6a,07)
#define GPT_USR_PPC_VERITY SD_ID128_MAKE(df,76,5d,00,27,0e,49,e5,bc,75,f4,7b,b2,11,8b,09) #define GPT_USR_PPC_VERITY SD_ID128_MAKE(df,76,5d,00,27,0e,49,e5,bc,75,f4,7b,b2,11,8b,09)
#define GPT_USR_RISCV32_VERITY SD_ID128_MAKE(cb,1e,e4,e3,8c,d0,41,36,a0,a4,aa,61,a3,2e,87,30) #define GPT_USR_RISCV32_VERITY SD_ID128_MAKE(cb,1e,e4,e3,8c,d0,41,36,a0,a4,aa,61,a3,2e,87,30)
@ -92,7 +93,7 @@
#define GPT_ROOT_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(5a,fb,67,eb,ec,c8,4f,85,ae,8e,ac,1e,7c,50,e7,d0) #define GPT_ROOT_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(5a,fb,67,eb,ec,c8,4f,85,ae,8e,ac,1e,7c,50,e7,d0)
#define GPT_ROOT_MIPS_LE_VERITY_SIG SD_ID128_MAKE(c9,19,cc,1f,44,56,4e,ff,91,8c,f7,5e,94,52,5c,a5) #define GPT_ROOT_MIPS_LE_VERITY_SIG SD_ID128_MAKE(c9,19,cc,1f,44,56,4e,ff,91,8c,f7,5e,94,52,5c,a5)
#define GPT_ROOT_MIPS64_LE_VERITY_SIG SD_ID128_MAKE(90,4e,58,ef,5c,65,4a,31,9c,57,6a,f5,fc,7c,5d,e7) #define GPT_ROOT_MIPS64_LE_VERITY_SIG SD_ID128_MAKE(90,4e,58,ef,5c,65,4a,31,9c,57,6a,f5,fc,7c,5d,e7)
#define GPT_ROOT_PPC64LE_VERITY_SIG SD_ID128_MAKE(d4,a2,36,e7,e8,73,4c,07,bf,1d,bf,6c,f7,f1,c3,c6) #define GPT_ROOT_PPC64_LE_VERITY_SIG SD_ID128_MAKE(d4,a2,36,e7,e8,73,4c,07,bf,1d,bf,6c,f7,f1,c3,c6)
#define GPT_ROOT_PPC64_VERITY_SIG SD_ID128_MAKE(f5,e2,c2,0c,45,b2,4f,fa,bc,e9,2a,60,73,7e,1a,af) #define GPT_ROOT_PPC64_VERITY_SIG SD_ID128_MAKE(f5,e2,c2,0c,45,b2,4f,fa,bc,e9,2a,60,73,7e,1a,af)
#define GPT_ROOT_PPC_VERITY_SIG SD_ID128_MAKE(1b,31,b5,aa,ad,d9,46,3a,b2,ed,bd,46,7f,c8,57,e7) #define GPT_ROOT_PPC_VERITY_SIG SD_ID128_MAKE(1b,31,b5,aa,ad,d9,46,3a,b2,ed,bd,46,7f,c8,57,e7)
#define GPT_ROOT_RISCV32_VERITY_SIG SD_ID128_MAKE(3a,11,2a,75,87,29,43,80,b4,cf,76,4d,79,93,44,48) #define GPT_ROOT_RISCV32_VERITY_SIG SD_ID128_MAKE(3a,11,2a,75,87,29,43,80,b4,cf,76,4d,79,93,44,48)
@ -110,7 +111,7 @@
#define GPT_USR_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(b0,24,f3,15,d3,30,44,4c,84,61,44,bb,de,52,4e,99) #define GPT_USR_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(b0,24,f3,15,d3,30,44,4c,84,61,44,bb,de,52,4e,99)
#define GPT_USR_MIPS_LE_VERITY_SIG SD_ID128_MAKE(3e,23,ca,0b,a4,bc,4b,4e,80,87,5a,b6,a2,6a,a8,a9) #define GPT_USR_MIPS_LE_VERITY_SIG SD_ID128_MAKE(3e,23,ca,0b,a4,bc,4b,4e,80,87,5a,b6,a2,6a,a8,a9)
#define GPT_USR_MIPS64_LE_VERITY_SIG SD_ID128_MAKE(f2,c2,c7,ee,ad,cc,43,51,b5,c6,ee,98,16,b6,6e,16) #define GPT_USR_MIPS64_LE_VERITY_SIG SD_ID128_MAKE(f2,c2,c7,ee,ad,cc,43,51,b5,c6,ee,98,16,b6,6e,16)
#define GPT_USR_PPC64LE_VERITY_SIG SD_ID128_MAKE(c8,bf,bd,1e,26,8e,45,21,8b,ba,bf,31,4c,39,95,57) #define GPT_USR_PPC64_LE_VERITY_SIG SD_ID128_MAKE(c8,bf,bd,1e,26,8e,45,21,8b,ba,bf,31,4c,39,95,57)
#define GPT_USR_PPC64_VERITY_SIG SD_ID128_MAKE(0b,88,88,63,d7,f8,4d,9e,97,66,23,9f,ce,4d,58,af) #define GPT_USR_PPC64_VERITY_SIG SD_ID128_MAKE(0b,88,88,63,d7,f8,4d,9e,97,66,23,9f,ce,4d,58,af)
#define GPT_USR_PPC_VERITY_SIG SD_ID128_MAKE(70,07,89,1d,d3,71,4a,80,86,a4,5c,b8,75,b9,30,2e) #define GPT_USR_PPC_VERITY_SIG SD_ID128_MAKE(70,07,89,1d,d3,71,4a,80,86,a4,5c,b8,75,b9,30,2e)
#define GPT_USR_RISCV32_VERITY_SIG SD_ID128_MAKE(c3,83,6a,13,31,37,45,ba,b5,83,b1,6c,50,fe,5e,b4) #define GPT_USR_RISCV32_VERITY_SIG SD_ID128_MAKE(c3,83,6a,13,31,37,45,ba,b5,83,b1,6c,50,fe,5e,b4)
@ -186,12 +187,12 @@
# define GPT_USR_NATIVE_VERITY_SIG GPT_USR_LOONGARCH64_VERITY_SIG # define GPT_USR_NATIVE_VERITY_SIG GPT_USR_LOONGARCH64_VERITY_SIG
#elif defined(__powerpc__) && defined(__PPC64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #elif defined(__powerpc__) && defined(__PPC64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define GPT_ROOT_NATIVE GPT_ROOT_PPC64LE # define GPT_ROOT_NATIVE GPT_ROOT_PPC64_LE
# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_PPC64LE_VERITY # define GPT_ROOT_NATIVE_VERITY GPT_ROOT_PPC64_LE_VERITY
# define GPT_ROOT_NATIVE_VERITY_SIG GPT_ROOT_PPC64LE_VERITY_SIG # define GPT_ROOT_NATIVE_VERITY_SIG GPT_ROOT_PPC64_LE_VERITY_SIG
# define GPT_USR_NATIVE GPT_USR_PPC64LE # define GPT_USR_NATIVE GPT_USR_PPC64_LE
# define GPT_USR_NATIVE_VERITY GPT_USR_PPC64LE_VERITY # define GPT_USR_NATIVE_VERITY GPT_USR_PPC64_LE_VERITY
# define GPT_USR_NATIVE_VERITY_SIG GPT_USR_PPC64LE_VERITY_SIG # define GPT_USR_NATIVE_VERITY_SIG GPT_USR_PPC64_LE_VERITY_SIG
#elif defined(__powerpc__) && defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #elif defined(__powerpc__) && defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
# define GPT_ROOT_NATIVE GPT_ROOT_PPC64 # define GPT_ROOT_NATIVE GPT_ROOT_PPC64
# define GPT_ROOT_NATIVE_VERITY GPT_ROOT_PPC64_VERITY # define GPT_ROOT_NATIVE_VERITY GPT_ROOT_PPC64_VERITY
@ -288,9 +289,19 @@ const char *gpt_partition_type_uuid_to_string_harder(
char buffer[static ID128_UUID_STRING_MAX]); char buffer[static ID128_UUID_STRING_MAX]);
int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret); int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret);
Architecture gpt_partition_type_uuid_to_arch(sd_id128_t id);
typedef struct GptPartitionType { typedef struct GptPartitionType {
sd_id128_t uuid; sd_id128_t uuid;
const char *name; const char *name;
Architecture arch;
bool is_root:1;
bool is_root_verity:1;
bool is_root_verity_sig:1;
bool is_usr:1;
bool is_usr_verity:1;
bool is_usr_verity_sig:1;
} GptPartitionType; } GptPartitionType;
extern const GptPartitionType gpt_partition_type_table[]; extern const GptPartitionType gpt_partition_type_table[];
@ -299,8 +310,10 @@ int gpt_partition_label_valid(const char *s);
bool gpt_partition_type_is_root(sd_id128_t id); bool gpt_partition_type_is_root(sd_id128_t id);
bool gpt_partition_type_is_root_verity(sd_id128_t id); bool gpt_partition_type_is_root_verity(sd_id128_t id);
bool gpt_partition_type_is_root_verity_sig(sd_id128_t id);
bool gpt_partition_type_is_usr(sd_id128_t id); bool gpt_partition_type_is_usr(sd_id128_t id);
bool gpt_partition_type_is_usr_verity(sd_id128_t id); bool gpt_partition_type_is_usr_verity(sd_id128_t id);
bool gpt_partition_type_is_usr_verity_sig(sd_id128_t id);
bool gpt_partition_type_knows_read_only(sd_id128_t id); bool gpt_partition_type_knows_read_only(sd_id128_t id);
bool gpt_partition_type_knows_growfs(sd_id128_t id); bool gpt_partition_type_knows_growfs(sd_id128_t id);

View File

@ -515,7 +515,6 @@ static void json_variant_set(JsonVariant *a, JsonVariant *b) {
static void json_variant_copy_source(JsonVariant *v, JsonVariant *from) { static void json_variant_copy_source(JsonVariant *v, JsonVariant *from) {
assert(v); assert(v);
assert(from);
if (!json_variant_is_regular(from)) if (!json_variant_is_regular(from))
return; return;

View File

@ -259,6 +259,7 @@ enum {
#define JSON_BUILD_HEX(p, n) _JSON_BUILD_HEX, (const void*) { p }, (size_t) { n } #define JSON_BUILD_HEX(p, n) _JSON_BUILD_HEX, (const void*) { p }, (size_t) { n }
#define JSON_BUILD_ID128(id) _JSON_BUILD_ID128, (const sd_id128_t*) { &(id) } #define JSON_BUILD_ID128(id) _JSON_BUILD_ID128, (const sd_id128_t*) { &(id) }
#define JSON_BUILD_BYTE_ARRAY(v, n) _JSON_BUILD_BYTE_ARRAY, (const void*) { v }, (size_t) { n } #define JSON_BUILD_BYTE_ARRAY(v, n) _JSON_BUILD_BYTE_ARRAY, (const void*) { v }, (size_t) { n }
#define JSON_BUILD_CONST_STRING(s) _JSON_BUILD_VARIANT, JSON_VARIANT_STRING_CONST(s)
int json_build(JsonVariant **ret, ...); int json_build(JsonVariant **ret, ...);
int json_buildv(JsonVariant **ret, va_list ap); int json_buildv(JsonVariant **ret, va_list ap);

View File

@ -17,8 +17,8 @@ void net_match_clear(NetMatch *match) {
if (!match) if (!match)
return; return;
match->mac = set_free(match->mac); match->hw_addr = set_free(match->hw_addr);
match->permanent_mac = set_free(match->permanent_mac); match->permanent_hw_addr = set_free(match->permanent_hw_addr);
match->path = strv_free(match->path); match->path = strv_free(match->path);
match->driver = strv_free(match->driver); match->driver = strv_free(match->driver);
match->iftype = strv_free(match->iftype); match->iftype = strv_free(match->iftype);
@ -33,8 +33,8 @@ bool net_match_is_empty(const NetMatch *match) {
assert(match); assert(match);
return return
set_isempty(match->mac) && set_isempty(match->hw_addr) &&
set_isempty(match->permanent_mac) && set_isempty(match->permanent_hw_addr) &&
strv_isempty(match->path) && strv_isempty(match->path) &&
strv_isempty(match->driver) && strv_isempty(match->driver) &&
strv_isempty(match->iftype) && strv_isempty(match->iftype) &&
@ -122,8 +122,8 @@ static int net_condition_test_property(char * const *match_property, sd_device *
int net_match_config( int net_match_config(
const NetMatch *match, const NetMatch *match,
sd_device *device, sd_device *device,
const struct ether_addr *mac, const struct hw_addr_data *hw_addr,
const struct ether_addr *permanent_mac, const struct hw_addr_data *permanent_hw_addr,
const char *driver, const char *driver,
unsigned short iftype, unsigned short iftype,
const char *ifname, const char *ifname,
@ -150,13 +150,12 @@ int net_match_config(
(void) sd_device_get_sysname(device, &ifname); (void) sd_device_get_sysname(device, &ifname);
} }
if (match->mac && (!mac || !set_contains(match->mac, mac))) if (match->hw_addr && (!hw_addr || !set_contains(match->hw_addr, hw_addr)))
return false; return false;
if (match->permanent_mac && if (match->permanent_hw_addr &&
(!permanent_mac || (!permanent_hw_addr ||
ether_addr_is_null(permanent_mac) || !set_contains(match->permanent_hw_addr, permanent_hw_addr)))
!set_contains(match->permanent_mac, permanent_mac)))
return false; return false;
if (!net_condition_test_strv(match->path, path)) if (!net_condition_test_strv(match->path, path))

View File

@ -11,8 +11,8 @@
#include "set.h" #include "set.h"
typedef struct NetMatch { typedef struct NetMatch {
Set *mac; Set *hw_addr;
Set *permanent_mac; Set *permanent_hw_addr;
char **path; char **path;
char **driver; char **driver;
char **iftype; char **iftype;
@ -29,8 +29,8 @@ bool net_match_is_empty(const NetMatch *match);
int net_match_config( int net_match_config(
const NetMatch *match, const NetMatch *match,
sd_device *device, sd_device *device,
const struct ether_addr *mac, const struct hw_addr_data *hw_addr,
const struct ether_addr *permanent_mac, const struct hw_addr_data *permanent_hw_addr,
const char *driver, const char *driver,
unsigned short iftype, unsigned short iftype,
const char *ifname, const char *ifname,

View File

@ -1,7 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <linux/if_arp.h>
#include "arphrd-util.h" #include "arphrd-util.h"
#include "device-util.h" #include "device-util.h"
#include "log-link.h"
#include "memory-util.h"
#include "netif-util.h" #include "netif-util.h"
#include "siphash24.h" #include "siphash24.h"
#include "sparse-endian.h" #include "sparse-endian.h"
@ -99,3 +103,91 @@ int net_get_unique_predictable_data_from_name(
*ret = htole64(siphash24(v, sz, key->bytes)); *ret = htole64(siphash24(v, sz, key->bytes));
return 0; return 0;
} }
typedef struct Link {
const char *ifname;
} Link;
int net_verify_hardware_address(
const char *ifname,
bool warn_invalid,
uint16_t iftype,
const struct hw_addr_data *ib_hw_addr, /* current or parent HW address */
struct hw_addr_data *new_hw_addr) {
Link link = { .ifname = ifname };
assert(new_hw_addr);
if (new_hw_addr->length == 0)
return 0;
if (new_hw_addr->length != arphrd_to_hw_addr_len(iftype)) {
if (warn_invalid)
log_link_warning(&link,
"Specified MAC address with invalid length (%zu, expected %zu), refusing.",
new_hw_addr->length, arphrd_to_hw_addr_len(iftype));
return -EINVAL;
}
switch (iftype) {
case ARPHRD_ETHER:
/* see eth_random_addr() in the kernel */
if (ether_addr_is_null(&new_hw_addr->ether)) {
if (warn_invalid)
log_link_warning(&link, "Specified MAC address is null, refusing.");
return -EINVAL;
}
if (ether_addr_is_broadcast(&new_hw_addr->ether)) {
if (warn_invalid)
log_link_warning(&link, "Specified MAC address is broadcast, refusing.");
return -EINVAL;
}
if (ether_addr_is_multicast(&new_hw_addr->ether)) {
if (warn_invalid)
log_link_warning(&link, "Specified MAC address has multicast bit set, clearing the bit.");
new_hw_addr->bytes[0] &= 0xfe;
}
if (!ether_addr_is_local(&new_hw_addr->ether)) {
if (warn_invalid)
log_link_warning(&link, "Specified MAC address has not local assignment bit set, setting the bit.");
new_hw_addr->bytes[0] |= 0x02;
}
break;
case ARPHRD_INFINIBAND:
/* see ipoib_check_lladdr() in the kernel */
assert(ib_hw_addr);
assert(ib_hw_addr->length == INFINIBAND_ALEN);
if (warn_invalid &&
(!memeqzero(new_hw_addr->bytes, INFINIBAND_ALEN - 8) ||
memcmp(new_hw_addr->bytes, ib_hw_addr->bytes, INFINIBAND_ALEN - 8) != 0))
log_link_warning(&link, "Only the last 8 bytes of the InifniBand MAC address can be changed, ignoring the first 12 bytes.");
if (memeqzero(new_hw_addr->bytes + INFINIBAND_ALEN - 8, 8)) {
if (warn_invalid)
log_link_warning(&link, "The last 8 bytes of the InfiniBand MAC address cannot be null, refusing.");
return -EINVAL;
}
memcpy(new_hw_addr->bytes, ib_hw_addr->bytes, INFINIBAND_ALEN - 8);
break;
default:
if (warn_invalid)
log_link_warning(&link, "Unsupported interface type %s%u to set MAC address, refusing.",
strna(arphrd_to_name(iftype)), iftype);
return -EINVAL;
}
return 0;
}

View File

@ -7,7 +7,15 @@
#include "sd-device.h" #include "sd-device.h"
#include "sd-id128.h" #include "sd-id128.h"
#include "ether-addr-util.h"
int net_get_type_string(sd_device *device, uint16_t iftype, char **ret); int net_get_type_string(sd_device *device, uint16_t iftype, char **ret);
const char *net_get_persistent_name(sd_device *device); const char *net_get_persistent_name(sd_device *device);
int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *ret); int net_get_unique_predictable_data(sd_device *device, bool use_sysname, uint64_t *ret);
int net_get_unique_predictable_data_from_name(const char *name, const sd_id128_t *key, uint64_t *ret); int net_get_unique_predictable_data_from_name(const char *name, const sd_id128_t *key, uint64_t *ret);
int net_verify_hardware_address(
const char *ifname,
bool warn_invalid,
uint16_t iftype,
const struct hw_addr_data *ib_hw_addr,
struct hw_addr_data *new_hw_addr);

View File

@ -1257,7 +1257,7 @@ int tpm2_make_luks2_json(
r = json_build(&v, r = json_build(&v,
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("type", JSON_BUILD_STRING("systemd-tpm2")), JSON_BUILD_PAIR("type", JSON_BUILD_CONST_STRING("systemd-tpm2")),
JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))), JSON_BUILD_PAIR("keyslots", JSON_BUILD_ARRAY(JSON_BUILD_STRING(keyslot_as_string))),
JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob, blob_size)), JSON_BUILD_PAIR("tpm2-blob", JSON_BUILD_BASE64(blob, blob_size)),
JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(a)), JSON_BUILD_PAIR("tpm2-pcrs", JSON_BUILD_VARIANT(a)),

View File

@ -600,22 +600,22 @@ static int userdb_process(
static int synthetic_root_user_build(UserRecord **ret) { static int synthetic_root_user_build(UserRecord **ret) {
return user_record_build( return user_record_build(
ret, ret,
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_STRING("root")), JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_CONST_STRING("root")),
JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(0)), JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(0)),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(0)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(0)),
JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_STRING("/root")), JSON_BUILD_PAIR("homeDirectory", JSON_BUILD_CONST_STRING("/root")),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic")))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
} }
static int synthetic_nobody_user_build(UserRecord **ret) { static int synthetic_nobody_user_build(UserRecord **ret) {
return user_record_build( return user_record_build(
ret, ret,
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_STRING(NOBODY_USER_NAME)), JSON_BUILD_OBJECT(JSON_BUILD_PAIR("userName", JSON_BUILD_CONST_STRING(NOBODY_USER_NAME)),
JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(UID_NOBODY)), JSON_BUILD_PAIR("uid", JSON_BUILD_UNSIGNED(UID_NOBODY)),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)),
JSON_BUILD_PAIR("shell", JSON_BUILD_STRING(NOLOGIN)), JSON_BUILD_PAIR("shell", JSON_BUILD_CONST_STRING(NOLOGIN)),
JSON_BUILD_PAIR("locked", JSON_BUILD_BOOLEAN(true)), JSON_BUILD_PAIR("locked", JSON_BUILD_BOOLEAN(true)),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic")))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
} }
int userdb_by_name(const char *name, UserDBFlags flags, UserRecord **ret) { int userdb_by_name(const char *name, UserDBFlags flags, UserRecord **ret) {
@ -878,17 +878,17 @@ int userdb_iterator_get(UserDBIterator *iterator, UserRecord **ret) {
static int synthetic_root_group_build(GroupRecord **ret) { static int synthetic_root_group_build(GroupRecord **ret) {
return group_record_build( return group_record_build(
ret, ret,
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING("root")), JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_CONST_STRING("root")),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(0)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(0)),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic")))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
} }
static int synthetic_nobody_group_build(GroupRecord **ret) { static int synthetic_nobody_group_build(GroupRecord **ret) {
return group_record_build( return group_record_build(
ret, ret,
JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_STRING(NOBODY_GROUP_NAME)), JSON_BUILD_OBJECT(JSON_BUILD_PAIR("groupName", JSON_BUILD_CONST_STRING(NOBODY_GROUP_NAME)),
JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)), JSON_BUILD_PAIR("gid", JSON_BUILD_UNSIGNED(GID_NOBODY)),
JSON_BUILD_PAIR("disposition", JSON_BUILD_STRING("intrinsic")))); JSON_BUILD_PAIR("disposition", JSON_BUILD_CONST_STRING("intrinsic"))));
} }
int groupdb_by_name(const char *name, UserDBFlags flags, GroupRecord **ret) { int groupdb_by_name(const char *name, UserDBFlags flags, GroupRecord **ret) {

View File

@ -390,7 +390,7 @@ static void test_json(void) {
assert_se(json_build(&w, assert_se(json_build(&w,
JSON_BUILD_ARRAY( JSON_BUILD_ARRAY(
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("foo_bar", JSON_BUILD_STRING("v1")), JSON_BUILD_PAIR("foo_bar", JSON_BUILD_CONST_STRING("v1")),
JSON_BUILD_PAIR("quux", JSON_BUILD_UNSIGNED(4711)), JSON_BUILD_PAIR("quux", JSON_BUILD_UNSIGNED(4711)),
JSON_BUILD_PAIR("zzz", JSON_BUILD_BOOLEAN(true))), JSON_BUILD_PAIR("zzz", JSON_BUILD_BOOLEAN(true))),
JSON_BUILD_OBJECT( JSON_BUILD_OBJECT(

View File

@ -47,6 +47,8 @@ static void test_gpt_types_against_architectures(void) {
assert_se(gpt_partition_type_is_usr(id)); assert_se(gpt_partition_type_is_usr(id));
if (streq(prefix, "usr-") && streq(suffix, "-verity")) if (streq(prefix, "usr-") && streq(suffix, "-verity"))
assert_se(gpt_partition_type_is_usr_verity(id)); assert_se(gpt_partition_type_is_usr_verity(id));
assert_se(gpt_partition_type_uuid_to_arch(id) == a);
} }
} }
} }

View File

@ -333,16 +333,16 @@ static void test_build(void) {
assert_se(json_build(&a, JSON_BUILD_OBJECT( assert_se(json_build(&a, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")), JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")),
JSON_BUILD_PAIR("z", JSON_BUILD_STRING("a")), JSON_BUILD_PAIR("z", JSON_BUILD_CONST_STRING("a")),
JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c")) JSON_BUILD_PAIR("b", JSON_BUILD_CONST_STRING("c"))
)) >= 0); )) >= 0);
assert_se(json_build(&b, JSON_BUILD_OBJECT( assert_se(json_build(&b, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")), JSON_BUILD_PAIR("x", JSON_BUILD_STRING("y")),
JSON_BUILD_PAIR_CONDITION(false, "p", JSON_BUILD_STRING("q")), JSON_BUILD_PAIR_CONDITION(false, "p", JSON_BUILD_STRING("q")),
JSON_BUILD_PAIR_CONDITION(true, "z", JSON_BUILD_STRING("a")), JSON_BUILD_PAIR_CONDITION(true, "z", JSON_BUILD_CONST_STRING("a")),
JSON_BUILD_PAIR_CONDITION(false, "j", JSON_BUILD_ARRAY(JSON_BUILD_STRING("k"), JSON_BUILD_STRING("u"), JSON_BUILD_STRING("i"))), JSON_BUILD_PAIR_CONDITION(false, "j", JSON_BUILD_ARRAY(JSON_BUILD_STRING("k"), JSON_BUILD_CONST_STRING("u"), JSON_BUILD_CONST_STRING("i"))),
JSON_BUILD_PAIR("b", JSON_BUILD_STRING("c")) JSON_BUILD_PAIR("b", JSON_BUILD_CONST_STRING("c"))
)) >= 0); )) >= 0);
assert_se(json_variant_equal(a, b)); assert_se(json_variant_equal(a, b));
@ -435,8 +435,8 @@ static void test_normalize(void) {
assert_se(json_build(&v, JSON_BUILD_OBJECT( assert_se(json_build(&v, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("b", JSON_BUILD_STRING("x")), JSON_BUILD_PAIR("b", JSON_BUILD_STRING("x")),
JSON_BUILD_PAIR("c", JSON_BUILD_STRING("y")), JSON_BUILD_PAIR("c", JSON_BUILD_CONST_STRING("y")),
JSON_BUILD_PAIR("a", JSON_BUILD_STRING("z")))) >= 0); JSON_BUILD_PAIR("a", JSON_BUILD_CONST_STRING("z")))) >= 0);
assert_se(!json_variant_is_sorted(v)); assert_se(!json_variant_is_sorted(v));
assert_se(!json_variant_is_normalized(v)); assert_se(!json_variant_is_normalized(v));
@ -569,6 +569,29 @@ static void test_float(void) {
test_float_match(w); test_float_match(w);
} }
static void test_equal_text(JsonVariant *v, const char *text) {
_cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
assert_se(json_parse(text, 0, &w, NULL, NULL) >= 0);
assert_se(json_variant_equal(v, w) || (!v && json_variant_is_null(w)));
}
static void test_set_field(void) {
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
log_info("/* %s */", __func__);
test_equal_text(v, "null");
assert_se(json_variant_set_field(&v, "foo", NULL) >= 0);
test_equal_text(v, "{\"foo\" : null}");
assert_se(json_variant_set_field(&v, "bar", JSON_VARIANT_STRING_CONST("quux")) >= 0);
test_equal_text(v, "{\"foo\" : null, \"bar\" : \"quux\"}");
assert_se(json_variant_set_field(&v, "foo", JSON_VARIANT_STRING_CONST("quux2")) >= 0);
test_equal_text(v, "{\"foo\" : \"quux2\", \"bar\" : \"quux\"}");
assert_se(json_variant_set_field(&v, "bar", NULL) >= 0);
test_equal_text(v, "{\"foo\" : \"quux2\", \"bar\" : null}");
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_setup_logging(LOG_DEBUG); test_setup_logging(LOG_DEBUG);
@ -622,6 +645,7 @@ int main(int argc, char *argv[]) {
test_normalize(); test_normalize();
test_bisect(); test_bisect();
test_float(); test_float();
test_set_field();
return 0; return 0;
} }

View File

@ -126,7 +126,7 @@ static void flood_test(const char *address) {
assert_se(varlink_set_description(c, "overload-client") >= 0); assert_se(varlink_set_description(c, "overload-client") >= 0);
assert_se(varlink_attach_event(c, e, k) >= 0); assert_se(varlink_attach_event(c, e, k) >= 0);
assert_se(varlink_bind_reply(c, overload_reply) >= 0); assert_se(varlink_bind_reply(c, overload_reply) >= 0);
assert_se(varlink_invokeb(c, "io.test.Overload", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("foo", JSON_BUILD_STRING("bar")))) >= 0); assert_se(varlink_invokeb(c, "io.test.Overload", JSON_BUILD_OBJECT(JSON_BUILD_PAIR("foo", JSON_BUILD_CONST_STRING("bar")))) >= 0);
/* Unblock it */ /* Unblock it */
log_debug("Unblocking server..."); log_debug("Unblocking server...");

View File

@ -21,8 +21,8 @@ struct ConfigPerfItem;
%struct-type %struct-type
%includes %includes
%% %%
Match.MACAddress, config_parse_ether_addrs, 0, offsetof(LinkConfig, match.mac) Match.MACAddress, config_parse_hw_addrs, 0, offsetof(LinkConfig, match.hw_addr)
Match.PermanentMACAddress, config_parse_ether_addrs, 0, offsetof(LinkConfig, match.permanent_mac) Match.PermanentMACAddress, config_parse_hw_addrs, 0, offsetof(LinkConfig, match.permanent_hw_addr)
Match.OriginalName, config_parse_match_ifnames, 0, offsetof(LinkConfig, match.ifname) Match.OriginalName, config_parse_match_ifnames, 0, offsetof(LinkConfig, match.ifname)
Match.Path, config_parse_match_strv, 0, offsetof(LinkConfig, match.path) Match.Path, config_parse_match_strv, 0, offsetof(LinkConfig, match.path)
Match.Driver, config_parse_match_strv, 0, offsetof(LinkConfig, match.driver) Match.Driver, config_parse_match_strv, 0, offsetof(LinkConfig, match.driver)

View File

@ -386,9 +386,7 @@ int link_config_get(LinkConfigContext *ctx, sd_netlink **rtnl, sd_device *device
(void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type); (void) link_unsigned_attribute(device, "name_assign_type", &name_assign_type);
LIST_FOREACH(links, link, ctx->links) { LIST_FOREACH(links, link, ctx->links) {
r = net_match_config(&link->match, device, r = net_match_config(&link->match, device, &hw_addr, &permanent_hw_addr,
hw_addr.length == ETH_ALEN ? &hw_addr.ether : NULL,
permanent_hw_addr.length == ETH_ALEN ? &permanent_hw_addr.ether : NULL,
NULL, iftype, NULL, NULL, 0, NULL, NULL); NULL, iftype, NULL, NULL, 0, NULL, NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -2704,7 +2704,8 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
output = check_output('ip link show dummy98') output = check_output('ip link show dummy98')
print(output) print(output)
self.assertRegex(output, '00:01:02:aa:bb:cc') # 00:01:02:aa:bb:cc was requested, and the local bit is set by networkd.
self.assertRegex(output, '02:01:02:aa:bb:cc')
def test_ip_link_unmanaged(self): def test_ip_link_unmanaged(self):
copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev') copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')

View File

@ -26,6 +26,7 @@ inspect() {
systemd-analyze log-level debug systemd-analyze log-level debug
systemd-analyze log-target console systemd-analyze log-target console
systemctl service-log-level systemd-homed debug
# Create a tmpfs to use as backing store for the home dir. That way we can enforce a size limit nicely. # Create a tmpfs to use as backing store for the home dir. That way we can enforce a size limit nicely.
mkdir -p /home-pool mkdir -p /home-pool
@ -68,7 +69,7 @@ inspect test-user
PASSWORD=xEhErW0ndafV4s homectl activate test-user PASSWORD=xEhErW0ndafV4s homectl activate test-user
inspect test-user inspect test-user
PASSWORD=xEhErW0ndafV4s homectl deactivate test-user homectl deactivate test-user
inspect test-user inspect test-user
PASSWORD=xEhErW0ndafV4s homectl update test-user --real-name="Offline test" PASSWORD=xEhErW0ndafV4s homectl update test-user --real-name="Offline test"
@ -77,7 +78,7 @@ inspect test-user
PASSWORD=xEhErW0ndafV4s homectl activate test-user PASSWORD=xEhErW0ndafV4s homectl activate test-user
inspect test-user inspect test-user
PASSWORD=xEhErW0ndafV4s homectl deactivate test-user homectl deactivate test-user
inspect test-user inspect test-user
# Do some resize tests, but only if we run on real kernels, as quota inside of containers will fail # Do some resize tests, but only if we run on real kernels, as quota inside of containers will fail
@ -109,7 +110,7 @@ if ! systemd-detect-virt -cq ; then
PASSWORD=xEhErW0ndafV4s homectl resize test-user 256M PASSWORD=xEhErW0ndafV4s homectl resize test-user 256M
inspect test-user inspect test-user
PASSWORD=xEhErW0ndafV4s homectl deactivate test-user homectl deactivate test-user
inspect test-user inspect test-user
fi fi

View File

@ -17,6 +17,9 @@ disown
systemd-notify --ready systemd-notify --ready
# Run the stop/kill command
\$1 &
# process tree: systemd -> bash -> sleep # process tree: systemd -> bash -> sleep
sleep infinity sleep infinity
EOF EOF
@ -24,14 +27,12 @@ chmod +x /tmp/test56-exit-cgroup.sh
# service should be stopped cleanly # service should be stopped cleanly
systemd-run --wait --unit=one -p Type=notify -p ExitType=cgroup \ systemd-run --wait --unit=one -p Type=notify -p ExitType=cgroup \
-p ExecStartPost='bash -c "systemctl stop one &"' \ /tmp/test56-exit-cgroup.sh 'systemctl stop one'
/tmp/test56-exit-cgroup.sh
# same thing with a truthy exec condition # same thing with a truthy exec condition
systemd-run --wait --unit=two -p Type=notify -p ExitType=cgroup \ systemd-run --wait --unit=two -p Type=notify -p ExitType=cgroup \
-p ExecCondition=true \ -p ExecCondition=true \
-p ExecStartPost='bash -c "systemctl stop two &"' \ /tmp/test56-exit-cgroup.sh 'systemctl stop two'
/tmp/test56-exit-cgroup.sh
# false exec condition: systemd-run should exit immediately with status code: 1 # false exec condition: systemd-run should exit immediately with status code: 1
systemd-run --wait --unit=three -p Type=notify -p ExitType=cgroup \ systemd-run --wait --unit=three -p Type=notify -p ExitType=cgroup \
@ -41,8 +42,7 @@ systemd-run --wait --unit=three -p Type=notify -p ExitType=cgroup \
# service should exit uncleanly (main process exits with SIGKILL) # service should exit uncleanly (main process exits with SIGKILL)
systemd-run --wait --unit=four -p Type=notify -p ExitType=cgroup \ systemd-run --wait --unit=four -p Type=notify -p ExitType=cgroup \
-p ExecStartPost='bash -c "systemctl kill --signal 9 four &"' \ /tmp/test56-exit-cgroup.sh 'systemctl kill --signal 9 four' \
/tmp/test56-exit-cgroup.sh \
&& { echo 'unexpected success'; exit 1; } && { echo 'unexpected success'; exit 1; }
@ -58,18 +58,19 @@ sleep infinity &
((sleep infinity); true) & ((sleep infinity); true) &
systemd-notify --ready systemd-notify --ready
# Run the stop/kill command after this bash process exits
(sleep 1; \$1) &
EOF EOF
chmod +x /tmp/test56-exit-cgroup-parentless.sh chmod +x /tmp/test56-exit-cgroup-parentless.sh
# service should be stopped cleanly # service should be stopped cleanly
systemd-run --wait --unit=five -p Type=notify -p ExitType=cgroup \ systemd-run --wait --unit=five -p Type=notify -p ExitType=cgroup \
-p ExecStartPost='bash -c "systemctl stop five &"' \ /tmp/test56-exit-cgroup-parentless.sh 'systemctl stop five'
/tmp/test56-exit-cgroup-parentless.sh
# service should still exit cleanly despite SIGKILL (the main process already exited cleanly) # service should still exit cleanly despite SIGKILL (the main process already exited cleanly)
systemd-run --wait --unit=six -p Type=notify -p ExitType=cgroup \ systemd-run --wait --unit=six -p Type=notify -p ExitType=cgroup \
-p ExecStartPost='bash -c "systemctl kill --signal 9 six &"' \ /tmp/test56-exit-cgroup-parentless.sh 'systemctl kill --signal 9 six'
/tmp/test56-exit-cgroup-parentless.sh
systemd-analyze log-level info systemd-analyze log-level info

View File

@ -21,7 +21,7 @@ ARCHITECTURES = {
'MIPS64_LE': '64-bit MIPS LittleEndian (mips64el)', 'MIPS64_LE': '64-bit MIPS LittleEndian (mips64el)',
'PPC': '32-bit PowerPC', 'PPC': '32-bit PowerPC',
'PPC64': '64-bit PowerPC BigEndian', 'PPC64': '64-bit PowerPC BigEndian',
'PPC64LE': '64-bit PowerPC LittleEndian', 'PPC64_LE': '64-bit PowerPC LittleEndian',
'RISCV32': 'RISC-V 32-bit', 'RISCV32': 'RISC-V 32-bit',
'RISCV64': 'RISC-V 64-bit', 'RISCV64': 'RISC-V 64-bit',
'S390': 's390', 'S390': 's390',
@ -146,7 +146,7 @@ def extract(file):
if not m: if not m:
continue continue
if m2 := re.match(r'^(ROOT|USR)_([A-Z0-9]+|X86_64|MIPS_LE|MIPS64_LE)(|_VERITY|_VERITY_SIG)\s+SD_ID128_MAKE\((.*)\)', m.group(1)): if m2 := re.match(r'^(ROOT|USR)_([A-Z0-9]+|X86_64|PPC64_LE|MIPS_LE|MIPS64_LE)(|_VERITY|_VERITY_SIG)\s+SD_ID128_MAKE\((.*)\)', m.group(1)):
type, arch, suffix, u = m2.groups() type, arch, suffix, u = m2.groups()
u = uuid.UUID(u.replace(',', '')) u = uuid.UUID(u.replace(',', ''))
assert arch in ARCHITECTURES assert arch in ARCHITECTURES