]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot/random-seed: create \loader\ dir if missing when seeding
authordongshengyuan <545258830@qq.com>
Tue, 30 Jun 2026 01:47:22 +0000 (09:47 +0800)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 30 Jun 2026 12:26:59 +0000 (13:26 +0100)
When the random seed file doesn't exist but we have good entropy
(seeded_by_efi=true), we attempt to create it. This requires a handle
to the \loader\ directory, which may not exist on systems using
UKI+EFISTUB without systemd-boot installed.

Obtain the directory handle by first trying a read-only open; if that
returns EFI_NOT_FOUND, create the directory. We deliberately avoid
requesting write access on an already-present directory because some
firmware implementations return EFI_INVALID_PARAMETER for a
WRITE|CREATE open on an existing directory — this would be logged at
LOG_ERR and abort seed creation on systems where \loader\ exists but
random-seed does not (the normal systemd-boot layout).

Once a handle to \loader\ is obtained, open the seed file relative to
that handle rather than using the full path from root.

Introduced-by: c0e7046c17 ("boot: log about RO I/O errors at debug level.")
Fixes: #42801
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
src/boot/random-seed.c

index d2ed63f0e359ed7a412270d6332766fbbe869599..e10e765b7fe9c4e9d6ba810875e13fb3b3ffa848 100644 (file)
@@ -205,11 +205,35 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir) {
                         0);
         if (err == EFI_NOT_FOUND && seeded_by_efi) {
 
-                /* If the file does not exist, but we are reasonably well seeded, create the seed file */
+                /* If the file does not exist, but we are reasonably well seeded, create the seed
+                 * file. Get a handle to the \loader\ directory — open it read-only if it already
+                 * exists, or create it (requiring write access) only when it is missing (e.g. on
+                 * systems using UKI+EFISTUB without systemd-boot installed). We avoid requesting
+                 * write access on an already-present directory because some firmware
+                 * implementations refuse it, which would abort seed creation unnecessarily. */
+                _cleanup_file_close_ EFI_FILE *dir_handle = NULL;
                 err = root_dir->Open(
                                 root_dir,
+                                &dir_handle,
+                                (char16_t *) u"\\loader",
+                                EFI_FILE_MODE_READ,
+                                0);
+                if (err == EFI_NOT_FOUND)
+                        err = root_dir->Open(
+                                        root_dir,
+                                        &dir_handle,
+                                        (char16_t *) u"\\loader",
+                                        EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+                                        EFI_FILE_DIRECTORY);
+                if (err != EFI_SUCCESS)
+                        return log_full(err,
+                                        EFI_STATUS_IS_WRITE_REFUSED(err) ? LOG_DEBUG : LOG_ERR,
+                                        "Failed to open or create loader directory: %m");
+
+                err = dir_handle->Open(
+                                dir_handle,
                                 &handle,
-                                (char16_t *) u"\\loader\\random-seed",
+                                (char16_t *) u"random-seed",
                                 EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
                                 0);
                 if (err != EFI_SUCCESS)