Compare commits

...

8 Commits

Author SHA1 Message Date
Yu Watanabe 6c70336064
Merge a050031d05 into 5bed97dd57 2024-11-26 13:46:58 +00:00
Winterhuman 5bed97dd57
man/systemd-system.conf: Correct "struct" to "strict" (#35364) 2024-11-26 22:41:49 +09:00
Luca Boccassi c4d7a13c06 cryptsetup: convert pkcs11/fido2 to iovec for key handling
key-data might be NULL. Fixes crash:

0  0x0000559c62120530 in attach_luks_or_plain_or_bitlk (cd=0x559c6b192830, name=0x7ffd57981dc4 "root", token_type=TOKEN_FIDO2, key_file=0x0, key_data=0x0, passwords=0x0, flags=524296, until=0)
    at ../src/cryptsetup/cryptsetup.c:2234
        pass_volume_key = false
        r = 1469577760
        __func__ = '\000' <repeats 29 times>
1  0x0000559c6212279c in run (argc=6, argv=0x7ffd5797fe98) at ../src/cryptsetup/cryptsetup.c:2597
        discovered_key_data = {iov_base = 0x0, iov_len = 0}
        key_data = 0x0
        token_type = TOKEN_FIDO2
        destroy_key_file = 0x0
        flags = 524296
        until = 0
        passphrase_type = PASSPHRASE_NONE
        volume = 0x7ffd57981dc4 "root"
        source = 0x7ffd57981dc9 "/dev/disk/by-uuid/8372fb39-9ba4-461a-a618-07dcaae66280"
        status = CRYPT_INACTIVE
        tries = 0
        key_file = 0x0
        config = 0x7ffd57981e05 "luks,discard,fido2-device=auto,x-initrd.attach"
        use_cached_passphrase = true
        try_discover_key = true
        discovered_key_fn = 0x7ffd5797fa70 "root.key"
        passwords = 0x0
        cd = 0x559c6b192830
        verb = 0x7ffd57981dbd "attach"
        r = 0
        __func__ = "\000\000\000"
2  0x0000559c621231e6 in main (argc=6, argv=0x7ffd5797fe98) at ../src/cryptsetup/cryptsetup.c:2674
        r = 32553
        __func__ = "\000\000\000\000"

Follow-up for 53b6c99018
2024-11-26 22:04:24 +09:00
Abderrahim Kitouni 0ae6f4843e updatectl: fix DBus method signature for SetFeatureEnabled
The signature was changed to 'sit' in sysupdated during review, but updatectl
kept using 'sbt'
2024-11-26 22:03:41 +09:00
Yu Watanabe 1ea1a79aa1 Revert "Revert "man: use MIT-0 license for example codes in daemon(7)""
This reverts commit 7a9d0abe4d.
2024-11-26 12:26:10 +01:00
Luca Boccassi 7a9d0abe4d Revert "man: use MIT-0 license for example codes in daemon(7)"
This reverts commit 6046cc3660.
2024-11-26 19:47:21 +09:00
Yu Watanabe 6046cc3660 man: use MIT-0 license for example codes in daemon(7)
This page contains many short example codes. I do not think we should
add SPDX-License-Identifier for all codes.

Closes #35356.
2024-11-26 11:12:08 +01:00
Yu Watanabe a050031d05 udev-node: replace existing symlink with the same priority only when explicitly requested
History:
- Before 331aa7aa15, a symlink creation
  requested by a new event replaced an existing symlink with the same
  priority.
- With 331aa7aa15 (v254), if an existing symlink
  has the same priority with the newly requested one, then the new request
  was skipped, and the existing symlink was kept. But this caused #28141.
- With 7ec5ce5673 (v255, and backported to v254.6),
  the behavior is restored prior to the 331aa7aa15.
  But, it is pointed out that the replacing symlink may be dangerous.
  See discussion in https://github.com/systemd/systemd/pull/34482#issuecomment-2362115374.

This introduce .UDEV_REPLACE_SYMLINK_WITH_SAME_PRIORITY flag, and set the flag
for dm devices. Why? We need to consider several points:
- On boot time, devices appear in random order. So, if e.g. sda and sdb
  requests the same symlink, then there are no way to guarantee which
  device will own the symlink, as these devices will be processed by
  udevd in parallel. Since, there are no guarantee, we can change the
  logic which device will win to own the symlink, that is, the first
  wins (with this PR) or the last wins (the current behavior).
- After the system is booted, e.g. when a USB stick (sdb) is inserted and
  it requests a symlink which is currently owned by sda. In that case,
  the current behavior makes the new device (sdb) steal the ownership of
  the symlink. But, that may be problematic as a user or a program may
  assume that the symlink is persistent, and data may be lost or stolen.
  We can easily create such hackish USB stick by creating a partition
  which has the same partition UUID on the stick.
  With this commit, new devices cannot override the ownership of the symlink,
  so such the issue will not be triggered anymore.
- As you can see the change in the test code for integrity in this commit,
  this commit is also important for dm-integrity. Without this PR, the data
  partition and the DM devices both request the same partition UUID symlink,
  and the data device gained the ownership, as a synthetic event for the
  underlying data device is triggered after the DM device is activated,
  and it steels the ownership from the DM device. People may mistakenly
  mounts the underlying data device rather than the DM device, and may causes
  data loss or corruption. With this PR, the underlying device will not
  gain the symlink, and blkid command always returns the DM device.
- Unfortunately, this re-introduce issue #28468, which is triggered for
  spurious ISO images. But, it can be easily avoided by reapplying the
  'workaround' done by df1dccd255.

Fixes #31448.
Replaces #34482, #33572, #32981.
2024-09-25 14:09:23 +02:00
12 changed files with 63 additions and 41 deletions

View File

@ -684,6 +684,15 @@ fi</programlisting>
<citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para> <citerefentry><refentrytitle>file-hierarchy</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
</refsect1> </refsect1>
<refsect1>
<title>Notes</title>
<para>
All example codes in this page are licensed under <literal>MIT No Attribution</literal>
(SPDX-License-Identifier: MIT-0).
</para>
</refsect1>
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para><simplelist type="inline"> <para><simplelist type="inline">

View File

@ -302,7 +302,7 @@
and running in an initrd equivalent to true, otherwise false. This implements a restricted subset of and running in an initrd equivalent to true, otherwise false. This implements a restricted subset of
the per-unit setting of the same name, see the per-unit setting of the same name, see
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
details: currently, the <literal>full</literal> or <literal>struct</literal> values are not details: currently, the <literal>full</literal> or <literal>strict</literal> values are not
supported.</para> supported.</para>
<xi:include href="version-info.xml" xpointer="v256"/></listitem> <xi:include href="version-info.xml" xpointer="v256"/></listitem>

View File

@ -136,6 +136,12 @@ KERNEL!="sr*|mmcblk[0-9]boot[0-9]", IMPORT{builtin}="blkid"
LABEL="persistent_storage_blkid_probe_end" LABEL="persistent_storage_blkid_probe_end"
{% endif %} {% endif %}
# Decrease devlink priority for whole disk of ISO hybrid images, and make the
# priority for partitions in the image relatively higher. This is for the case
# that a disk and one of its partition have the same label or so.
# See issue #28468.
ENV{ID_FS_TYPE}=="iso9660", ENV{DEVTYPE}=="disk", OPTIONS+="link_priority=-10"
# by-label/by-uuid links (filesystem metadata) # by-label/by-uuid links (filesystem metadata)
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}" ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_UUID_ENC}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID_ENC}"
ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}" ENV{ID_FS_USAGE}=="filesystem|other|crypto", ENV{ID_FS_LABEL_ENC}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_ENC}"

View File

@ -22,6 +22,10 @@ SUBSYSTEM=="ubi", TAG+="systemd"
SUBSYSTEM=="block", TAG+="systemd" SUBSYSTEM=="block", TAG+="systemd"
# Make dm devices can replace existing symlinks with the same priority.
# Otherwise, activating a device while another is being deactivated may fail.
SUBSYSTEM=="block", KERNEL=="dm-*", ENV{.UDEV_REPLACE_SYMLINK_WITH_SAME_PRIORITY}="1"
# When a dm device is first created, it's just an empty container. Ignore it. # When a dm device is first created, it's just an empty container. Ignore it.
# DM_NAME is not set in this case, but it's set on spurious "add" events that occur later. # DM_NAME is not set in this case, but it's set on spurious "add" events that occur later.
SUBSYSTEM=="block", ACTION=="add", KERNEL=="dm-*", ENV{DM_NAME}!="?*", ENV{SYSTEMD_READY}="0" SUBSYSTEM=="block", ACTION=="add", KERNEL=="dm-*", ENV{DM_NAME}!="?*", ENV{SYSTEMD_READY}="0"

View File

@ -16,6 +16,7 @@
#include "fileio.h" #include "fileio.h"
#include "format-util.h" #include "format-util.h"
#include "hexdecoct.h" #include "hexdecoct.h"
#include "iovec-util.h"
#include "macro.h" #include "macro.h"
#include "memory-util.h" #include "memory-util.h"
#include "parse-util.h" #include "parse-util.h"
@ -31,8 +32,7 @@ int decrypt_pkcs11_key(
const char *key_file, /* We either expect key_file and associated parameters to be set (for file keys) … */ const char *key_file, /* We either expect key_file and associated parameters to be set (for file keys) … */
size_t key_file_size, size_t key_file_size,
uint64_t key_file_offset, uint64_t key_file_offset,
const void *key_data, /* … or key_data and key_data_size (for literal keys) */ const struct iovec *key_data, /* … or literal keys via key_data */
size_t key_data_size,
usec_t until, usec_t until,
AskPasswordFlags askpw_flags, AskPasswordFlags askpw_flags,
void **ret_decrypted_key, void **ret_decrypted_key,
@ -47,15 +47,15 @@ int decrypt_pkcs11_key(
assert(friendly_name); assert(friendly_name);
assert(pkcs11_uri); assert(pkcs11_uri);
assert(key_file || key_data); assert(key_file || iovec_is_set(key_data));
assert(ret_decrypted_key); assert(ret_decrypted_key);
assert(ret_decrypted_key_size); assert(ret_decrypted_key_size);
/* The functions called here log about all errors, except for EAGAIN which means "token not found right now" */ /* The functions called here log about all errors, except for EAGAIN which means "token not found right now" */
if (key_data) { if (iovec_is_set(key_data)) {
data.encrypted_key = (void*) key_data; data.encrypted_key = (void*) key_data->iov_base;
data.encrypted_key_size = key_data_size; data.encrypted_key_size = key_data->iov_len;
data.free_encrypted_key = false; data.free_encrypted_key = false;
} else { } else {

View File

@ -16,8 +16,7 @@ int decrypt_pkcs11_key(
const char *key_file, const char *key_file,
size_t key_file_size, size_t key_file_size,
uint64_t key_file_offset, uint64_t key_file_offset,
const void *key_data, const struct iovec *key_data,
size_t key_data_size,
usec_t until, usec_t until,
AskPasswordFlags askpw_flags, AskPasswordFlags askpw_flags,
void **ret_decrypted_key, void **ret_decrypted_key,
@ -39,8 +38,7 @@ static inline int decrypt_pkcs11_key(
const char *key_file, const char *key_file,
size_t key_file_size, size_t key_file_size,
uint64_t key_file_offset, uint64_t key_file_offset,
const void *key_data, const struct iovec *key_data,
size_t key_data_size,
usec_t until, usec_t until,
AskPasswordFlags askpw_flags, AskPasswordFlags askpw_flags,
void **ret_decrypted_key, void **ret_decrypted_key,

View File

@ -1471,8 +1471,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
struct crypt_device *cd, struct crypt_device *cd,
const char *name, const char *name,
const char *key_file, const char *key_file,
const void *key_data, const struct iovec *key_data,
size_t key_data_size,
usec_t until, usec_t until,
uint32_t flags, uint32_t flags,
bool pass_volume_key) { bool pass_volume_key) {
@ -1489,7 +1488,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
assert(name); assert(name);
assert(arg_fido2_device || arg_fido2_device_auto); assert(arg_fido2_device || arg_fido2_device_auto);
if (arg_fido2_cid && !key_file && !key_data) if (arg_fido2_cid && !key_file && !iovec_is_set(key_data))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"FIDO2 mode with manual parameters selected, but no keyfile specified, refusing."); "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
@ -1513,7 +1512,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
arg_fido2_rp_id, arg_fido2_rp_id,
arg_fido2_cid, arg_fido2_cid_size, arg_fido2_cid, arg_fido2_cid_size,
key_file, arg_keyfile_size, arg_keyfile_offset, key_file, arg_keyfile_size, arg_keyfile_offset,
key_data, key_data_size, key_data,
until, until,
arg_fido2_manual_flags, arg_fido2_manual_flags,
"cryptsetup.fido2-pin", "cryptsetup.fido2-pin",
@ -1623,8 +1622,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
struct crypt_device *cd, struct crypt_device *cd,
const char *name, const char *name,
const char *key_file, const char *key_file,
const void *key_data, const struct iovec *key_data,
size_t key_data_size,
usec_t until, usec_t until,
uint32_t flags, uint32_t flags,
bool pass_volume_key) { bool pass_volume_key) {
@ -1635,6 +1633,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
_cleanup_(erase_and_freep) void *decrypted_key = NULL; _cleanup_(erase_and_freep) void *decrypted_key = NULL;
_cleanup_(sd_event_unrefp) sd_event *event = NULL; _cleanup_(sd_event_unrefp) sd_event *event = NULL;
_cleanup_free_ void *discovered_key = NULL; _cleanup_free_ void *discovered_key = NULL;
struct iovec discovered_key_data = {};
int keyslot = arg_key_slot, r; int keyslot = arg_key_slot, r;
const char *uri = NULL; const char *uri = NULL;
bool use_libcryptsetup_plugin = use_token_plugins(); bool use_libcryptsetup_plugin = use_token_plugins();
@ -1653,13 +1652,13 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
return r; return r;
uri = discovered_uri; uri = discovered_uri;
key_data = discovered_key; discovered_key_data = IOVEC_MAKE(discovered_key, discovered_key_size);
key_data_size = discovered_key_size; key_data = &discovered_key_data;
} }
} else { } else {
uri = arg_pkcs11_uri; uri = arg_pkcs11_uri;
if (!key_file && !key_data) if (!key_file && !iovec_is_set(key_data))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PKCS#11 mode selected but no key file specified, refusing."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PKCS#11 mode selected but no key file specified, refusing.");
} }
@ -1682,7 +1681,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
friendly, friendly,
uri, uri,
key_file, arg_keyfile_size, arg_keyfile_offset, key_file, arg_keyfile_size, arg_keyfile_offset,
key_data, key_data_size, key_data,
until, until,
arg_ask_password_flags, arg_ask_password_flags,
&decrypted_key, &decrypted_key_size); &decrypted_key, &decrypted_key_size);
@ -2231,9 +2230,9 @@ static int attach_luks_or_plain_or_bitlk(
if (token_type == TOKEN_TPM2) if (token_type == TOKEN_TPM2)
return attach_luks_or_plain_or_bitlk_by_tpm2(cd, name, key_file, key_data, until, flags, pass_volume_key); return attach_luks_or_plain_or_bitlk_by_tpm2(cd, name, key_file, key_data, until, flags, pass_volume_key);
if (token_type == TOKEN_FIDO2) if (token_type == TOKEN_FIDO2)
return attach_luks_or_plain_or_bitlk_by_fido2(cd, name, key_file, key_data->iov_base, key_data->iov_len, until, flags, pass_volume_key); return attach_luks_or_plain_or_bitlk_by_fido2(cd, name, key_file, key_data, until, flags, pass_volume_key);
if (token_type == TOKEN_PKCS11) if (token_type == TOKEN_PKCS11)
return attach_luks_or_plain_or_bitlk_by_pkcs11(cd, name, key_file, key_data->iov_base, key_data->iov_len, until, flags, pass_volume_key); return attach_luks_or_plain_or_bitlk_by_pkcs11(cd, name, key_file, key_data, until, flags, pass_volume_key);
if (key_data) if (key_data)
return attach_luks_or_plain_or_bitlk_by_key_data(cd, name, key_data, flags, pass_volume_key); return attach_luks_or_plain_or_bitlk_by_key_data(cd, name, key_data, flags, pass_volume_key);
if (key_file) if (key_file)

View File

@ -24,8 +24,7 @@ int acquire_fido2_key(
const char *key_file, const char *key_file,
size_t key_file_size, size_t key_file_size,
uint64_t key_file_offset, uint64_t key_file_offset,
const void *key_data, const struct iovec *key_data,
size_t key_data_size,
usec_t until, usec_t until,
Fido2EnrollFlags required, Fido2EnrollFlags required,
const char *askpw_credential, const char *askpw_credential,
@ -45,10 +44,10 @@ int acquire_fido2_key(
"Local verification is required to unlock this volume, but the 'headless' parameter was set."); "Local verification is required to unlock this volume, but the 'headless' parameter was set.");
assert(cid); assert(cid);
assert(key_file || key_data); assert(key_file || iovec_is_set(key_data));
if (key_data) if (iovec_is_set(key_data))
salt = IOVEC_MAKE(key_data, key_data_size); salt = *key_data;
else { else {
if (key_file_size > 0) if (key_file_size > 0)
log_debug("Ignoring 'keyfile-size=' option for a FIDO2 salt file."); log_debug("Ignoring 'keyfile-size=' option for a FIDO2 salt file.");
@ -252,7 +251,7 @@ int acquire_fido2_key_auto(
/* key_file= */ NULL, /* salt is read from LUKS header instead of key_file */ /* key_file= */ NULL, /* salt is read from LUKS header instead of key_file */
/* key_file_size= */ 0, /* key_file_size= */ 0,
/* key_file_offset= */ 0, /* key_file_offset= */ 0,
salt, salt_size, &IOVEC_MAKE(salt, salt_size),
until, until,
required, required,
"cryptsetup.fido2-pin", "cryptsetup.fido2-pin",

View File

@ -20,8 +20,7 @@ int acquire_fido2_key(
const char *key_file, const char *key_file,
size_t key_file_size, size_t key_file_size,
uint64_t key_file_offset, uint64_t key_file_offset,
const void *key_data, const struct iovec *key_data,
size_t key_data_size,
usec_t until, usec_t until,
Fido2EnrollFlags required, Fido2EnrollFlags required,
const char *askpw_credential, const char *askpw_credential,
@ -52,8 +51,7 @@ static inline int acquire_fido2_key(
const char *key_file, const char *key_file,
size_t key_file_size, size_t key_file_size,
uint64_t key_file_offset, uint64_t key_file_offset,
const void *key_data, const struct iovec *key_data,
size_t key_data_size,
usec_t until, usec_t until,
Fido2EnrollFlags required, Fido2EnrollFlags required,
const char *askpw_credential, const char *askpw_credential,

View File

@ -1414,7 +1414,7 @@ static int verb_enable(int argc, char **argv, void *userdata) {
"SetFeatureEnabled", "SetFeatureEnabled",
&error, &error,
/* reply= */ NULL, /* reply= */ NULL,
"sbt", "sit",
*feature, *feature,
(int) enable, (int) enable,
UINT64_C(0)); UINT64_C(0));

View File

@ -462,6 +462,18 @@ static int link_update(sd_device *dev, const char *slink, bool add) {
* another device. Hence, it is not necessary to recreate it. */ * another device. Hence, it is not necessary to recreate it. */
return 0; return 0;
/* When the priorities are equivalent, replace symlink only when it is
* explicitly requested. This is necessary for DM devices, otherwise
* activating a device while another is being deactivated may fail. See issue
* #28141. However, in general, replacing symlink with a same-priority device
* is dangerous. For example, when managing or assembling multiple disks,
* when fdisk or wipefs is called, we trigger synthesized events and that can
* replace existing symlinks, and unexpected device may be used and data may
* be lost. */
if (current_prio == prio &&
device_get_property_bool(dev, ".UDEV_REPLACE_SYMLINK_WITH_SAME_PRIORITY") <= 0)
return 0;
/* This device has the equal or a higher priority than the current. Let's /* This device has the equal or a higher priority than the current. Let's
* create the devlink to our device node. */ * create the devlink to our device node. */
return node_create_symlink(dev, /* devnode = */ NULL, slink); return node_create_symlink(dev, /* devnode = */ NULL, slink);

View File

@ -34,6 +34,9 @@ ${DM_NAME} ${loop} - integrity-algorithm=$1
EOF EOF
} }
udevadm settle
udevadm control --log-level=debug
image_dir="$(mktemp -d -t -p / integrity.tmp.XXXXXX)" image_dir="$(mktemp -d -t -p / integrity.tmp.XXXXXX)"
if [ -z "${image_dir}" ] || [ ! -d "${image_dir}" ]; then if [ -z "${image_dir}" ] || [ ! -d "${image_dir}" ]; then
echo "mktemp under / failed" echo "mktemp under / failed"
@ -93,13 +96,7 @@ do
# Check the signature on the FS to ensure we can retrieve it and that is matches # Check the signature on the FS to ensure we can retrieve it and that is matches
if [ -e "${FULL_DM_DEV_NAME}" ]; then if [ -e "${FULL_DM_DEV_NAME}" ]; then
# If a separate device is used for the metadata storage, then blkid will return one of the loop devices if [ "$(blkid -U "${FS_UUID}")" != "${FULL_DM_DEV_NAME}" ]; then
if [ "${separate_data}" -eq 1 ]; then
dev_name="$(integritysetup status ${DM_NAME} | grep '^\s*device:' | awk '{print $2}')"
else
dev_name="${FULL_DM_DEV_NAME}"
fi
if [ "${dev_name}" != "$(blkid -U "${FS_UUID}")" ]; then
echo "Failed to locate FS with matching UUID!" echo "Failed to locate FS with matching UUID!"
exit 1 exit 1
fi fi