From 5a7d7e05b83f7f5056f187d4076e2c640ad3adae Mon Sep 17 00:00:00 2001 From: Marc Hartmayer Date: Fri, 20 Oct 2023 13:44:29 +0000 Subject: [PATCH] genprotimg: make sure the kernel command line is always null-terminated Make sure that the kernel command line used for the Secure Execution boot image is always null-terminated. Before this change, users had to ensure that the provided kernel cmdline was null-terminated, which was error-prone. But since the default s390x Linux kernel command line is set to `root=/dev/ram0 ro` the remaining reserved memory for the kernel command line is zeroed out. Therefore, the problem only shows up if the used kernel command line is shorter than the default kernel command line. Fixes: 65b9fc442c1a ("genprotimg: introduce new tool for the creation of PV images") Reviewed-by: Steffen Eiden Signed-off-by: Marc Hartmayer Signed-off-by: Steffen Eiden --- genprotimg/src/pv/pv_image.c | 21 ++++++++++++++++++++- genprotimg/src/utils/buffer.c | 9 +++++++++ genprotimg/src/utils/buffer.h | 4 ++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/genprotimg/src/pv/pv_image.c b/genprotimg/src/pv/pv_image.c index 75aeb5e4..94ebb620 100644 --- a/genprotimg/src/pv/pv_image.c +++ b/genprotimg/src/pv/pv_image.c @@ -684,7 +684,26 @@ gint pv_img_add_component(PvImage *img, const PvArg *arg, GError **err) { g_autoptr(PvComponent) comp = NULL; - comp = pv_component_new_file(arg->type, arg->path, err); + switch (arg->type) { + case PV_COMP_TYPE_INITRD: + case PV_COMP_TYPE_KERNEL: + case PV_COMP_TYPE_STAGE3B: + comp = pv_component_new_file(arg->type, arg->path, err); + break; + case PV_COMP_TYPE_CMDLINE: { + g_autoptr(PvBuffer) buf = NULL; + g_autofree char *data = NULL; + gsize length; + + if (!g_file_get_contents(arg->path, &data, &length, err)) + return -1; + + /* Add one for the null terminator */ + buf = pv_buffer_take(g_steal_pointer(&data), length + 1); + comp = pv_component_new_buf(arg->type, buf, err); + } break; + } + if (!comp) return -1; diff --git a/genprotimg/src/utils/buffer.c b/genprotimg/src/utils/buffer.c index 509dc0de..d7a10844 100644 --- a/genprotimg/src/utils/buffer.c +++ b/genprotimg/src/utils/buffer.c @@ -26,6 +26,15 @@ PvBuffer *pv_buffer_alloc(gsize size) return ret; } +PvBuffer *pv_buffer_take(char *data, gsize size) +{ + PvBuffer *ret = g_new0(PvBuffer, 1); + + ret->data = data; + ret->size = size; + return ret; +} + PvBuffer *pv_buffer_dup(const PvBuffer *buf, gboolean page_aligned) { PvBuffer *ret; diff --git a/genprotimg/src/utils/buffer.h b/genprotimg/src/utils/buffer.h index 824b72cb..3fb870a0 100644 --- a/genprotimg/src/utils/buffer.h +++ b/genprotimg/src/utils/buffer.h @@ -21,6 +21,10 @@ typedef struct PvBuffer { } PvBuffer; PvBuffer *pv_buffer_alloc(gsize size); +/* After this call @data belongs to the PvBuffer and must no longer be modified + * by the caller. + */ +PvBuffer *pv_buffer_take(char *data, gsize size); void pv_buffer_free(PvBuffer *buf); void pv_buffer_clear(PvBuffer **buf); gint pv_buffer_write(const PvBuffer *buf, FILE *file, GError **err);