mirror of
https://github.com/systemd/systemd.git
synced 2025-02-15 09:57:39 +03:00
dissect: ignore udev database entries from before the loopback attachment
This tries to shorten the race of device reuse a bit more: let's ignore udev database entries that are older than the time where we started to use a loopback device. This doesn't fix the whole loopback device raciness mess, but it makes the race window a bit shorter.
This commit is contained in:
parent
8ede1e86b2
commit
4a62257d68
@ -1864,6 +1864,7 @@ int setup_namespace(
|
||||
&verity,
|
||||
root_image_options,
|
||||
loop_device->uevent_seqnum_not_before,
|
||||
loop_device->timestamp_not_before,
|
||||
dissect_image_flags,
|
||||
&dissected_image);
|
||||
if (r < 0)
|
||||
|
@ -782,6 +782,7 @@ static int run(int argc, char *argv[]) {
|
||||
&arg_verity_settings,
|
||||
NULL,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
arg_flags,
|
||||
&m);
|
||||
if (r < 0)
|
||||
|
@ -673,6 +673,7 @@ static int enumerate_partitions(dev_t devnum) {
|
||||
fd,
|
||||
NULL, NULL,
|
||||
UINT64_MAX,
|
||||
USEC_INFINITY,
|
||||
DISSECT_IMAGE_GPT_ONLY|
|
||||
DISSECT_IMAGE_NO_UDEV|
|
||||
DISSECT_IMAGE_USR_NO_ROOT,
|
||||
|
@ -5484,6 +5484,7 @@ static int run(int argc, char *argv[]) {
|
||||
&arg_verity_settings,
|
||||
NULL,
|
||||
loop->uevent_seqnum_not_before,
|
||||
loop->timestamp_not_before,
|
||||
dissect_image_flags,
|
||||
&dissected_image);
|
||||
if (r == -ENOPKG) {
|
||||
|
@ -396,6 +396,7 @@ static int portable_extract_by_path(
|
||||
d->fd,
|
||||
NULL, NULL,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
DISSECT_IMAGE_READ_ONLY |
|
||||
DISSECT_IMAGE_GENERIC_ROOT |
|
||||
DISSECT_IMAGE_REQUIRE_ROOT |
|
||||
|
@ -1202,6 +1202,7 @@ int image_read_metadata(Image *i) {
|
||||
d->fd,
|
||||
NULL, NULL,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
DISSECT_IMAGE_GENERIC_ROOT |
|
||||
DISSECT_IMAGE_REQUIRE_ROOT |
|
||||
DISSECT_IMAGE_RELAX_VAR_CHECK |
|
||||
|
@ -123,10 +123,6 @@ static int enumerator_for_parent(sd_device *d, sd_device_enumerator **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_enumerator_allow_uninitialized(e);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_device_enumerator_add_match_subsystem(e, "block", true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -229,6 +225,7 @@ static int device_is_partition(sd_device *d, sd_device *expected_parent, blkid_p
|
||||
static int find_partition(
|
||||
sd_device *parent,
|
||||
blkid_partition pp,
|
||||
usec_t timestamp_not_before,
|
||||
sd_device **ret) {
|
||||
|
||||
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
|
||||
@ -244,6 +241,18 @@ static int find_partition(
|
||||
return r;
|
||||
|
||||
FOREACH_DEVICE(e, q) {
|
||||
uint64_t usec;
|
||||
|
||||
r = sd_device_get_usec_initialized(q, &usec);
|
||||
if (r == -EBUSY) /* Not initialized yet */
|
||||
continue;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (timestamp_not_before != USEC_INFINITY &&
|
||||
usec < timestamp_not_before) /* udev database entry older than our attachment? Then it's not ours */
|
||||
continue;
|
||||
|
||||
r = device_is_partition(q, parent, pp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -310,6 +319,7 @@ static int wait_for_partition_device(
|
||||
blkid_partition pp,
|
||||
usec_t deadline,
|
||||
uint64_t uevent_seqnum_not_before,
|
||||
usec_t timestamp_not_before,
|
||||
sd_device **ret) {
|
||||
|
||||
_cleanup_(sd_event_source_unrefp) sd_event_source *timeout_source = NULL;
|
||||
@ -321,7 +331,7 @@ static int wait_for_partition_device(
|
||||
assert(pp);
|
||||
assert(ret);
|
||||
|
||||
r = find_partition(parent, pp, ret);
|
||||
r = find_partition(parent, pp, timestamp_not_before, ret);
|
||||
if (r != -ENXIO)
|
||||
return r;
|
||||
|
||||
@ -360,7 +370,7 @@ static int wait_for_partition_device(
|
||||
return r;
|
||||
|
||||
/* Check again, the partition might have appeared in the meantime */
|
||||
r = find_partition(parent, pp, ret);
|
||||
r = find_partition(parent, pp, timestamp_not_before, ret);
|
||||
if (r != -ENXIO)
|
||||
return r;
|
||||
|
||||
@ -510,6 +520,7 @@ int dissect_image(
|
||||
const VeritySettings *verity,
|
||||
const MountOptions *mount_options,
|
||||
uint64_t uevent_seqnum_not_before,
|
||||
usec_t timestamp_not_before,
|
||||
DissectImageFlags flags,
|
||||
DissectedImage **ret) {
|
||||
|
||||
@ -762,7 +773,7 @@ int dissect_image(
|
||||
if (!pp)
|
||||
return errno_or_else(EIO);
|
||||
|
||||
r = wait_for_partition_device(d, pp, deadline, uevent_seqnum_not_before, &q);
|
||||
r = wait_for_partition_device(d, pp, deadline, uevent_seqnum_not_before, timestamp_not_before, &q);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2598,6 +2609,7 @@ int dissect_image_and_warn(
|
||||
const VeritySettings *verity,
|
||||
const MountOptions *mount_options,
|
||||
uint64_t uevent_seqnum_not_before,
|
||||
usec_t timestamp_not_before,
|
||||
DissectImageFlags flags,
|
||||
DissectedImage **ret) {
|
||||
|
||||
@ -2612,7 +2624,7 @@ int dissect_image_and_warn(
|
||||
name = buffer;
|
||||
}
|
||||
|
||||
r = dissect_image(fd, verity, mount_options, uevent_seqnum_not_before, flags, ret);
|
||||
r = dissect_image(fd, verity, mount_options, uevent_seqnum_not_before, timestamp_not_before, flags, ret);
|
||||
switch (r) {
|
||||
|
||||
case -EOPNOTSUPP:
|
||||
@ -2720,7 +2732,7 @@ int mount_image_privately_interactively(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up loopback device: %m");
|
||||
|
||||
r = dissect_image_and_warn(d->fd, image, &verity, NULL, d->uevent_seqnum_not_before, flags, &dissected_image);
|
||||
r = dissect_image_and_warn(d->fd, image, &verity, NULL, d->uevent_seqnum_not_before, d->timestamp_not_before, flags, &dissected_image);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2812,6 +2824,7 @@ int verity_dissect_and_mount(
|
||||
&verity,
|
||||
options,
|
||||
loop_device->uevent_seqnum_not_before,
|
||||
loop_device->timestamp_not_before,
|
||||
dissect_image_flags,
|
||||
&dissected_image);
|
||||
/* No partition table? Might be a single-filesystem image, try again */
|
||||
@ -2821,6 +2834,7 @@ int verity_dissect_and_mount(
|
||||
&verity,
|
||||
options,
|
||||
loop_device->uevent_seqnum_not_before,
|
||||
loop_device->timestamp_not_before,
|
||||
dissect_image_flags | DISSECT_IMAGE_NO_PARTITION_TABLE,
|
||||
&dissected_image);
|
||||
if (r < 0)
|
||||
|
@ -159,8 +159,8 @@ 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 uevent_seqnum_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
int dissect_image_and_warn(int fd, const char *name, const VeritySettings *verity, const MountOptions *mount_options, uint64_t uevent_seqnum_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
int dissect_image(int fd, const VeritySettings *verity, const MountOptions *mount_options, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
int dissect_image_and_warn(int fd, const char *name, const VeritySettings *verity, const MountOptions *mount_options, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
|
||||
DissectedImage* dissected_image_unref(DissectedImage *m);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);
|
||||
|
@ -533,6 +533,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
|
||||
&verity_settings,
|
||||
NULL,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
flags,
|
||||
&m);
|
||||
if (r < 0)
|
||||
|
@ -51,7 +51,7 @@ static void* thread_func(void *ptr) {
|
||||
|
||||
log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted);
|
||||
|
||||
r = dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, DISSECT_IMAGE_READ_ONLY, &dissected);
|
||||
r = dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, loop->timestamp_not_before, DISSECT_IMAGE_READ_ONLY, &dissected);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed dissect loopback device %s: %m", loop->node);
|
||||
assert_se(r >= 0);
|
||||
@ -188,7 +188,7 @@ int main(int argc, char *argv[]) {
|
||||
sfdisk = NULL;
|
||||
|
||||
assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, LO_FLAGS_PARTSCAN, &loop) >= 0);
|
||||
assert_se(dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, 0, &dissected) >= 0);
|
||||
assert_se(dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
|
||||
|
||||
assert_se(dissected->partitions[PARTITION_ESP].found);
|
||||
assert_se(dissected->partitions[PARTITION_ESP].node);
|
||||
@ -212,7 +212,7 @@ int main(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_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, 0, &dissected) >= 0);
|
||||
assert_se(dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
|
||||
|
||||
assert_se(mkdtemp_malloc(NULL, &mounted) >= 0);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user