mirror of
https://github.com/systemd/systemd.git
synced 2026-11-06 05:17:24 +00:00
initrd-cpio: add a variant that returns the credentials cpio in memory
systemd-firstboot wants to wrap the archive into a PE section rather than pass a file to a VMM, hence split the memory part out of the temp file writer, which becomes a wrapper around it.
This commit is contained in:
1 parent
ad151a463d
commit
f6b4e316e8
3 files changed
+57
-11
No files matched your search
+30
-11
@@ -9,6 +9,7 @@
|
||||
#include "fs-util.h"
|
||||
#include "initrd-cpio.h"
|
||||
#include "io-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "log.h"
|
||||
#include "machine-credential.h"
|
||||
#include "memory-util.h"
|
||||
@@ -117,13 +118,11 @@ static void append_cpio_trailer(FILE *f) {
|
||||
fwrite(trailer, 1, sizeof trailer, f);
|
||||
}
|
||||
|
||||
int initrd_cpio_credentials_to_tempfile(
|
||||
int initrd_cpio_credentials_to_memory(
|
||||
const MachineCredentialContext *creds,
|
||||
char **ret_path) {
|
||||
struct iovec *ret) {
|
||||
|
||||
_cleanup_(memstream_done) MemStream m = {};
|
||||
_cleanup_(unlink_and_freep) char *path = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_(erase_and_freep) char *buf = NULL; /* holds plaintext credential bytes; scrub on free */
|
||||
size_t buf_size = 0;
|
||||
uint32_t inode = 1;
|
||||
@@ -131,12 +130,7 @@ int initrd_cpio_credentials_to_tempfile(
|
||||
int r;
|
||||
|
||||
assert(creds);
|
||||
assert(ret_path);
|
||||
|
||||
if (creds->n_credentials == 0) {
|
||||
*ret_path = NULL;
|
||||
return 0;
|
||||
}
|
||||
assert(ret);
|
||||
|
||||
f = memstream_init(&m);
|
||||
if (!f)
|
||||
@@ -168,6 +162,31 @@ int initrd_cpio_credentials_to_tempfile(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to finalize credentials cpio: %m");
|
||||
|
||||
*ret = IOVEC_MAKE(TAKE_PTR(buf), buf_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int initrd_cpio_credentials_to_tempfile(
|
||||
const MachineCredentialContext *creds,
|
||||
char **ret_path) {
|
||||
|
||||
_cleanup_(unlink_and_freep) char *path = NULL;
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
_cleanup_(iovec_done_erase) struct iovec cpio = {}; /* holds plaintext credential bytes; scrub on free */
|
||||
int r;
|
||||
|
||||
assert(creds);
|
||||
assert(ret_path);
|
||||
|
||||
if (creds->n_credentials == 0) {
|
||||
*ret_path = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = initrd_cpio_credentials_to_memory(creds, &cpio);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = tempfn_random_child(NULL, "credentials-cpio", &path);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate temp file name: %m");
|
||||
@@ -176,7 +195,7 @@ int initrd_cpio_credentials_to_tempfile(
|
||||
if (fd < 0)
|
||||
return log_error_errno(fd, "Failed to create temp file %s: %m", path);
|
||||
|
||||
r = loop_write(fd, buf, buf_size);
|
||||
r = loop_write(fd, cpio.iov_base, cpio.iov_len);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write credentials cpio: %m");
|
||||
|
||||
|
||||
@@ -12,3 +12,8 @@
|
||||
int initrd_cpio_credentials_to_tempfile(
|
||||
const MachineCredentialContext *creds,
|
||||
char **ret_path);
|
||||
|
||||
/* Same, but returns the archive in memory. An archive is built even if there are no credentials. */
|
||||
int initrd_cpio_credentials_to_memory(
|
||||
const MachineCredentialContext *creds,
|
||||
struct iovec *ret);
|
||||
@@ -9,12 +9,34 @@
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "initrd-cpio.h"
|
||||
#include "iovec-util.h"
|
||||
#include "machine-credential.h"
|
||||
#include "path-util.h"
|
||||
#include "rm-rf.h"
|
||||
#include "tests.h"
|
||||
#include "tmpfile-util.h"
|
||||
|
||||
TEST(initrd_cpio_credentials_to_memory) {
|
||||
_cleanup_(machine_credential_context_done) MachineCredentialContext creds = {};
|
||||
_cleanup_(iovec_done) struct iovec empty = {}, archive = {};
|
||||
|
||||
/* Without credentials the archive still carries the directories and the trailer */
|
||||
ASSERT_OK(initrd_cpio_credentials_to_memory(&creds, &empty));
|
||||
ASSERT_NOT_NULL(empty.iov_base);
|
||||
ASSERT_GT(empty.iov_len, 0U);
|
||||
ASSERT_EQ(empty.iov_len % 4, 0U);
|
||||
ASSERT_NOT_NULL(memmem(empty.iov_base, empty.iov_len, "TRAILER!!!", STRLEN("TRAILER!!!")));
|
||||
ASSERT_NOT_NULL(memmem(empty.iov_base, empty.iov_len, ".extra/system_credentials", STRLEN(".extra/system_credentials")));
|
||||
|
||||
ASSERT_OK(machine_credential_add(&creds, "foo", "hello", 5));
|
||||
ASSERT_OK(initrd_cpio_credentials_to_memory(&creds, &archive));
|
||||
ASSERT_NOT_NULL(archive.iov_base);
|
||||
ASSERT_GT(archive.iov_len, empty.iov_len);
|
||||
ASSERT_NOT_NULL(memmem(archive.iov_base, archive.iov_len, ".extra/system_credentials/foo.cred", STRLEN(".extra/system_credentials/foo.cred")));
|
||||
ASSERT_NOT_NULL(memmem(archive.iov_base, archive.iov_len, "hello", STRLEN("hello")));
|
||||
ASSERT_NULL(memmem(empty.iov_base, empty.iov_len, "foo.cred", STRLEN("foo.cred")));
|
||||
}
|
||||
|
||||
TEST_RET(initrd_cpio_credentials_basic) {
|
||||
struct stat st;
|
||||
size_t foo_size, bar_size;
|
||||
|
||||
Reference in new issue
Block a user