mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
Use original filename for extension name check
The loading of an extension image from a symlink "NAME.raw" to "NAME-VERSION.raw" failed because the release file name check worked with the backing file of the loop device which already resolves the symlink and thus the found name "NAME-VERSION" mismatched "NAME". Pass the original filename and use it instead of the backing file when available. This fixes the loading of "NAME.raw" extensions which are a symlink to "NAME-VERSION.raw" as, e.g., may be the case when systemd-sysupdate manages multiple versions. Fixes https://github.com/systemd/systemd/issues/24293
This commit is contained in:
parent
6f2cea06bf
commit
e374439f4b
@ -2065,6 +2065,7 @@ int setup_namespace(
|
||||
|
||||
r = dissect_loop_device(
|
||||
loop_device,
|
||||
root_image,
|
||||
&verity,
|
||||
root_image_options,
|
||||
dissect_image_flags,
|
||||
|
@ -710,6 +710,7 @@ static int enumerate_partitions(dev_t devnum) {
|
||||
|
||||
r = dissect_image(
|
||||
fd,
|
||||
NULL,
|
||||
NULL, NULL,
|
||||
/* diskseq= */ 0,
|
||||
UINT64_MAX,
|
||||
|
@ -367,6 +367,7 @@ static int portable_extract_by_path(
|
||||
|
||||
r = dissect_loop_device(
|
||||
d,
|
||||
path,
|
||||
NULL, NULL,
|
||||
DISSECT_IMAGE_READ_ONLY |
|
||||
DISSECT_IMAGE_GENERIC_ROOT |
|
||||
|
@ -1198,6 +1198,7 @@ int image_read_metadata(Image *i) {
|
||||
|
||||
r = dissect_loop_device(
|
||||
d,
|
||||
i->path,
|
||||
NULL, NULL,
|
||||
DISSECT_IMAGE_GENERIC_ROOT |
|
||||
DISSECT_IMAGE_REQUIRE_ROOT |
|
||||
|
@ -193,6 +193,7 @@ static int make_partition_devname(
|
||||
|
||||
int dissect_image(
|
||||
int fd,
|
||||
const char *original_path,
|
||||
const VeritySettings *verity,
|
||||
const MountOptions *mount_options,
|
||||
uint64_t diskseq,
|
||||
@ -307,15 +308,29 @@ int dissect_image(
|
||||
r = sd_device_get_sysname(d, &sysname);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get device sysname: %m");
|
||||
if (startswith(sysname, "loop")) {
|
||||
_cleanup_free_ char *name_stripped = NULL;
|
||||
if (original_path) {
|
||||
_cleanup_free_ char *extracted_filename = NULL, *name_stripped = NULL;
|
||||
r = path_extract_filename(original_path, &extracted_filename);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = raw_strip_suffixes(extracted_filename, &name_stripped);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
free_and_replace(m->image_name, name_stripped);
|
||||
} else if (startswith(sysname, "loop")) {
|
||||
_cleanup_free_ char *extracted_filename = NULL, *name_stripped = NULL;
|
||||
const char *full_path;
|
||||
|
||||
/* Note that the backing_file reference resolves symlinks, while for sysext images we want the original path */
|
||||
r = sd_device_get_sysattr_value(d, "loop/backing_file", &full_path);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to lookup image name via loop device backing file sysattr, ignoring: %m");
|
||||
else {
|
||||
r = raw_strip_suffixes(basename(full_path), &name_stripped);
|
||||
r = path_extract_filename(full_path, &extracted_filename);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = raw_strip_suffixes(extracted_filename, &name_stripped);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -2812,7 +2827,7 @@ int dissect_loop_device_and_warn(
|
||||
if (!name)
|
||||
name = ASSERT_PTR(loop->node);
|
||||
|
||||
r = dissect_loop_device(loop, verity, mount_options, flags, ret);
|
||||
r = dissect_loop_device(loop, name, verity, mount_options, flags, ret);
|
||||
switch (r) {
|
||||
|
||||
case -EOPNOTSUPP:
|
||||
@ -3078,6 +3093,7 @@ int verity_dissect_and_mount(
|
||||
|
||||
r = dissect_loop_device(
|
||||
loop_device,
|
||||
src,
|
||||
&verity,
|
||||
options,
|
||||
dissect_image_flags,
|
||||
@ -3086,6 +3102,7 @@ int verity_dissect_and_mount(
|
||||
if (!verity.data_path && r == -ENOPKG)
|
||||
r = dissect_loop_device(
|
||||
loop_device,
|
||||
src,
|
||||
&verity,
|
||||
options,
|
||||
dissect_image_flags | DISSECT_IMAGE_NO_PARTITION_TABLE,
|
||||
|
@ -253,10 +253,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all);
|
||||
const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator);
|
||||
|
||||
int probe_filesystem(const char *node, char **ret_fstype);
|
||||
int dissect_image(int fd, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
static inline int dissect_loop_device(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) {
|
||||
int dissect_image(int fd, const char *original_path, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
static inline int dissect_loop_device(const LoopDevice *loop, const char *original_path, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) {
|
||||
assert(loop);
|
||||
return dissect_image(loop->fd, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret);
|
||||
return dissect_image(loop->fd, original_path, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret);
|
||||
}
|
||||
int dissect_loop_device_and_warn(const char *name, const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret);
|
||||
|
||||
|
@ -39,6 +39,7 @@ static void* thread_func(void *ptr) {
|
||||
_cleanup_(loop_device_unrefp) LoopDevice *loop = NULL;
|
||||
_cleanup_(umount_and_rmdir_and_freep) char *mounted = NULL;
|
||||
_cleanup_(dissected_image_unrefp) DissectedImage *dissected = NULL;
|
||||
_cleanup_free_ char *path = NULL;
|
||||
|
||||
if (now(CLOCK_MONOTONIC) >= end) {
|
||||
log_notice("Time's up, exiting thread's loop");
|
||||
@ -56,7 +57,12 @@ static void* thread_func(void *ptr) {
|
||||
|
||||
log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted);
|
||||
|
||||
r = dissect_loop_device(loop, NULL, NULL, DISSECT_IMAGE_READ_ONLY, &dissected);
|
||||
r = fd_get_path(fd, &path);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to get path from fd: %m");
|
||||
assert_se(r >= 0);
|
||||
|
||||
r = dissect_loop_device(loop, path, NULL, NULL, DISSECT_IMAGE_READ_ONLY, &dissected);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed dissect loopback device %s: %m", loop->node);
|
||||
assert_se(r >= 0);
|
||||
@ -220,7 +226,7 @@ static int run(int argc, char *argv[]) {
|
||||
pthread_t threads[arg_n_threads];
|
||||
sd_id128_t id;
|
||||
|
||||
assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0);
|
||||
assert_se(dissect_loop_device(loop, p, NULL, NULL, 0, &dissected) >= 0);
|
||||
|
||||
assert_se(dissected->partitions[PARTITION_ESP].found);
|
||||
assert_se(dissected->partitions[PARTITION_ESP].node);
|
||||
@ -244,7 +250,7 @@ static int run(int argc, char *argv[]) {
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_HOME].node, "ext4", "home", id, true) >= 0);
|
||||
|
||||
dissected = dissected_image_unref(dissected);
|
||||
assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0);
|
||||
assert_se(dissect_loop_device(loop, p, NULL, NULL, 0, &dissected) >= 0);
|
||||
|
||||
assert_se(mkdtemp_malloc(NULL, &mounted) >= 0);
|
||||
|
||||
|
@ -318,6 +318,11 @@ systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.r
|
||||
systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /opt/script1.sh | grep -q -F "extension-release.app2"
|
||||
systemd-run -P --property ExtensionImages="/usr/share/app0.raw /usr/share/app1.raw" --property RootImage="${image}.raw" cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1"
|
||||
systemd-run -P --property ExtensionImages=/usr/share/app-nodistro.raw --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
|
||||
# Check that using a symlink to NAME-VERSION.raw works as long as the symlink has the correct name NAME.raw
|
||||
mkdir -p /usr/share/symlink-test/
|
||||
cp /usr/share/app-nodistro.raw /usr/share/symlink-test/app-nodistro-v1.raw
|
||||
ln -fs /usr/share/symlink-test/app-nodistro-v1.raw /usr/share/symlink-test/app-nodistro.raw
|
||||
systemd-run -P --property ExtensionImages=/usr/share/symlink-test/app-nodistro.raw --property RootImage="${image}.raw" cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1"
|
||||
cat >/run/systemd/system/testservice-50e.service <<EOF
|
||||
[Service]
|
||||
MountAPIVFS=yes
|
||||
|
Loading…
Reference in New Issue
Block a user