From a79e94aa58a1b112d95ae27e4931bf5a8817ef05 Mon Sep 17 00:00:00 2001 From: DaanDeMeyer Date: Thu, 3 Jul 2025 14:13:03 +0200 Subject: [PATCH] vmspawn: Pass credentials via files Credentials data can get potentially very large. Passing it all via the command line is rather messy. Let's pass all the credential data via files instead to both make the final command line less verbose and reduce the chance of us running into command line size limits if many or large credentials are used. --- src/vmspawn/vmspawn.c | 77 +++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index c5fe0d54d76..3d48b5a0de8 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -1036,7 +1036,9 @@ static int cmdline_add_vsock(char ***cmdline, int vsock_fd) { return 0; } -static int cmdline_add_kernel_cmdline(char ***cmdline, const char *kernel) { +static int cmdline_add_kernel_cmdline(char ***cmdline, const char *kernel, const char *smbios_dir) { + int r; + assert(cmdline); if (strv_isempty(arg_kernel_cmdline_extra)) @@ -1055,28 +1057,32 @@ static int cmdline_add_kernel_cmdline(char ***cmdline, const char *kernel) { return 0; } - _cleanup_free_ char *escaped_kcl = NULL; - escaped_kcl = escape_qemu_value(kcl); - if (!escaped_kcl) - return log_oom(); - - if (strv_extend(cmdline, "-smbios") < 0) - return log_oom(); + FOREACH_STRING(id, "io.systemd.stub.kernel-cmdline-extra", "io.systemd.boot.kernel-cmdline-extra") { + _cleanup_free_ char *p = path_join(smbios_dir, id); + if (!p) + return log_oom(); - if (strv_extendf(cmdline, "type=11,value=io.systemd.stub.kernel-cmdline-extra=%s", escaped_kcl) < 0) - return log_oom(); + r = write_string_filef( + p, + WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_AVOID_NEWLINE|WRITE_STRING_FILE_MODE_0600, + "%s=%s", id, kcl); + if (r < 0) + return log_error_errno(r, "Failed to write smbios kernel command line to file: %m"); - if (strv_extend(cmdline, "-smbios") < 0) - return log_oom(); + if (strv_extend(cmdline, "-smbios") < 0) + return log_oom(); - if (strv_extendf(cmdline, "type=11,value=io.systemd.boot.kernel-cmdline-extra=%s", escaped_kcl) < 0) - return log_oom(); + if (strv_extendf(cmdline, "type=11,path=%s", p) < 0) + return log_oom(); + } } return 0; } -static int cmdline_add_smbios11(char ***cmdline) { +static int cmdline_add_smbios11(char ***cmdline, const char* smbios_dir) { + int r; + assert(cmdline); if (strv_isempty(arg_smbios11)) @@ -1088,15 +1094,22 @@ static int cmdline_add_smbios11(char ***cmdline) { } STRV_FOREACH(i, arg_smbios11) { - _cleanup_free_ char *escaped = NULL; - escaped = escape_qemu_value(*i); - if (!escaped) - return log_oom(); + _cleanup_(unlink_and_freep) char *p = NULL; + + r = tempfn_random_child(smbios_dir, "smbios11", &p); + if (r < 0) + return r; + + r = write_string_file( + p, *i, + WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_AVOID_NEWLINE|WRITE_STRING_FILE_MODE_0600); + if (r < 0) + return log_error_errno(r, "Failed to write smbios data to smbios file %s: %m", p); if (strv_extend(cmdline, "-smbios") < 0) return log_oom(); - if (strv_extendf(cmdline, "type=11,value=%s", escaped) < 0) + if (strv_extendf(cmdline, "type=11,path=%s", p) < 0) return log_oom(); } @@ -2386,11 +2399,16 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { return log_oom(); } - r = cmdline_add_kernel_cmdline(&cmdline, kernel); + _cleanup_(rm_rf_physical_and_freep) char *smbios_dir = NULL; + r = mkdtemp_malloc("/var/tmp/vmspawn-smbios-XXXXXX", &smbios_dir); + if (r < 0) + return log_error_errno(r, "Failed to create temporary directory: %m"); + + r = cmdline_add_kernel_cmdline(&cmdline, kernel, smbios_dir); if (r < 0) return r; - r = cmdline_add_smbios11(&cmdline); + r = cmdline_add_smbios11(&cmdline, smbios_dir); if (r < 0) return r; @@ -2586,18 +2604,29 @@ static int run_virtual_machine(int kvm_device_fd, int vhost_device_fd) { if (ARCHITECTURE_SUPPORTS_SMBIOS) FOREACH_ARRAY(cred, arg_credentials.credentials, arg_credentials.n_credentials) { - _cleanup_free_ char *cred_data_b64 = NULL; + _cleanup_free_ char *p = NULL, *cred_data_b64 = NULL; ssize_t n; n = base64mem(cred->data, cred->size, &cred_data_b64); if (n < 0) return log_oom(); + p = path_join(smbios_dir, cred->id); + if (!p) + return log_oom(); + + r = write_string_filef( + p, + WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_AVOID_NEWLINE|WRITE_STRING_FILE_MODE_0600, + "io.systemd.credential.binary:%s=%s", cred->id, cred_data_b64); + if (r < 0) + return log_error_errno(r, "Failed to write smbios credential file %s: %m", p); + r = strv_extend(&cmdline, "-smbios"); if (r < 0) return log_oom(); - r = strv_extendf(&cmdline, "type=11,value=io.systemd.credential.binary:%s=%s", cred->id, cred_data_b64); + r = strv_extendf(&cmdline, "type=11,path=%s", p); if (r < 0) return log_oom(); } -- 2.47.3