You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
systemd/SOURCES/0709-bootctl-rework-random-...

121 lines
4.5 KiB

From e12d41f584e33c0183a47d6c7211ccbf23f3e6a4 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 19 Dec 2022 22:26:30 +0100
Subject: [PATCH] bootctl: rework random seed logic to use open_mkdir_at() and
openat()
This doesn't really fix anything, but in general we should put stronger
emphasis on operating via dir fds rather than paths more (in particular
when writing files as opposed to consuming them).
No real change in behaviour.
(cherry picked from commit 6b97b267bf990b2ec553efae229b7996dc262996)
Related: RHEL-16952
---
src/boot/bootctl.c | 57 +++++++++++++++++++++++-----------------------
1 file changed, 29 insertions(+), 28 deletions(-)
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index c994be272b..9bb99eeec1 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -31,6 +31,7 @@
#include "fileio.h"
#include "find-esp.h"
#include "fs-util.h"
+#include "io-util.h"
#include "glyph-util.h"
#include "main-func.h"
#include "mkdir.h"
@@ -1983,53 +1984,47 @@ static int verb_list(int argc, char *argv[], void *userdata) {
}
static int install_random_seed(const char *esp) {
- _cleanup_(unlink_and_freep) char *tmp = NULL;
+ _cleanup_close_ int esp_fd = -EBADF, loader_dir_fd = -EBADF, fd = -EBADF;
+ _cleanup_free_ char *tmp = NULL;
uint8_t buffer[RANDOM_EFI_SEED_SIZE];
- _cleanup_free_ char *path = NULL;
- _cleanup_close_ int fd = -1;
size_t token_size;
- ssize_t n;
int r;
assert(esp);
- path = path_join(esp, "/loader/random-seed");
- if (!path)
- return log_oom();
+ esp_fd = open(esp, O_DIRECTORY|O_RDONLY|O_CLOEXEC);
+ if (esp_fd < 0)
+ return log_error_errno(errno, "Failed to open ESP directory '%s': %m", esp);
+
+ loader_dir_fd = open_mkdir_at(esp_fd, "loader", O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOFOLLOW, 0775);
+ if (loader_dir_fd < 0)
+ return log_error_errno(loader_dir_fd, "Failed to open loader directory '%s/loader': %m", esp);
r = crypto_random_bytes(buffer, sizeof(buffer));
if (r < 0)
return log_error_errno(r, "Failed to acquire random seed: %m");
- /* Normally create_subdirs() should already have created everything we need, but in case "bootctl
- * random-seed" is called we want to just create the minimum we need for it, and not the full
- * list. */
- r = mkdir_parents(path, 0755);
- if (r < 0)
- return log_error_errno(r, "Failed to create parent directory for %s: %m", path);
-
- r = tempfn_random(path, "bootctl", &tmp);
- if (r < 0)
+ if (tempfn_random("random-seed", "bootctl", &tmp) < 0)
return log_oom();
- fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
- if (fd < 0) {
- tmp = mfree(tmp);
+ fd = openat(loader_dir_fd, tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
+ if (fd < 0)
return log_error_errno(fd, "Failed to open random seed file for writing: %m");
- }
- n = write(fd, buffer, sizeof(buffer));
- if (n < 0)
- return log_error_errno(errno, "Failed to write random seed file: %m");
- if ((size_t) n != sizeof(buffer))
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while writing random seed file.");
+ r = loop_write(fd, buffer, sizeof(buffer), /* do_poll= */ false);
+ if (r < 0) {
+ log_error_errno(r, "Failed to write random seed file: %m");
+ goto fail;
+ }
- if (rename(tmp, path) < 0)
- return log_error_errno(errno, "Failed to move random seed file into place: %m");
+ if (renameat(loader_dir_fd, tmp, loader_dir_fd, "random-seed") < 0) {
+ r = log_error_errno(errno, "Failed to move random seed file into place: %m");
+ goto fail;
+ }
tmp = mfree(tmp);
- log_info("Random seed file %s successfully written (%zu bytes).", path, sizeof(buffer));
+ log_info("Random seed file %s/loader/random-seed successfully written (%zu bytes).", esp, sizeof(buffer));
if (!arg_touch_variables)
return 0;
@@ -2092,6 +2087,12 @@ static int install_random_seed(const char *esp) {
}
return 0;
+
+fail:
+ if (tmp)
+ (void) unlinkat(loader_dir_fd, tmp, 0);
+
+ return r;
}
static int sync_everything(void) {