* [PATCH] kexec: restore functionality to preserve fd xattrs for uncompressed kernel images
@ 2026-05-07 21:54 Alejandro Hernandez
2026-05-19 9:41 ` Simon Horman
0 siblings, 1 reply; 3+ messages in thread
From: Alejandro Hernandez @ 2026-05-07 21:54 UTC (permalink / raw)
To: kexec
Since commit 714fa115 xattrs attached to a kernel image file (such as IMA
signatures) are not being preserved, do_kexec_file_load() was modified to use
memfd_create() which now passes an anonymous file descriptor to
kexec_file_load(). This change eliminated the filesystem inode identity of the
original kernel file, hence attributes are no longer visible to the kernel IMA
appraisal handler during kexec_file_load, causing IMA policy enforcement to fail
even for validly signed kernel images.
This patch attempts to restore such behavior although, only does it for
uncompressed kernel images. To do this, we first figure out if the image file is
compressed or not and call each method accordingly.
Compressed images continue to use memfd and cannot carry forward the original fd
security attributes, since their decompressed bytes do not match the signed
artifact. Proper handling of compressed images with IMA would require either
signing the decompressed artifact or kernel-side support for decompression
within the kexec_file_load path.
Signed-off-by: Alejandro Hernandez Samaniego <alhe@linux.microsoft.com>
---
kexec/kexec.c | 42 +++++++++++++++++++++++++++++++++++-------
1 file changed, 35 insertions(+), 7 deletions(-)
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 08edfca..a388762 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -1328,17 +1328,41 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
kernel = argv[fileind];
- /* slurp in the input kernel */
+ /* Hold original fd with its xattrs */
+ kernel_fd = open(kernel, O_RDONLY);
+ if (kernel_fd == -1) {
+ fprintf(stderr, "Failed to open file %s:%s\n", kernel,
+ strerror(errno));
+ return EFAILED;
+ }
+
+ /* Compressed vs Uncompressed */
+ struct stat kernel_stat;
+ off_t kernel_file_size = -1;
+ if (fstat(kernel_fd, &kernel_stat) == 0)
+ kernel_file_size = kernel_stat.st_size;
+
+ /* slurp in the input kernel */
kernel_buf = slurp_decompress_file(kernel, &kernel_size);
if (!kernel_buf) {
fprintf(stderr, "Failed to decompress file %s:%s\n", kernel,
strerror(errno));
+ close(kernel_fd);
return EFAILED;
}
- kernel_fd = copybuf_memfd(kernel_buf, kernel_size);
- if (kernel_fd < 0) {
- fprintf(stderr, "Failed to copy decompressed buf\n");
- return EFAILED;
+
+ if (kernel_file_size != kernel_size) {
+ close(kernel_fd);
+ kernel_fd = copybuf_memfd(kernel_buf, kernel_size);
+ if (kernel_fd < 0) {
+ fprintf(stderr, "Failed to copy decompressed buf\n");
+ return EFAILED;
+ }
+ dbgprintf("%s: compressed input, using memfd kernel fd %d\n",
+ __func__, kernel_fd);
+ } else {
+ dbgprintf("%s: using original kernel file fd %d\n",
+ __func__, kernel_fd);
}
for (i = 0; i < file_types; i++) {
@@ -1361,11 +1385,15 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
}
/*
- * image type specific load functioin detect the capsule kernel type
+ * image type specific load function detect the capsule kernel type
* and create another fd for file load. For example the zboot kernel.
*/
- if (info.kernel_fd != -1)
+ if (info.kernel_fd != -1) {
+ dbgprintf("%s: using image-specific kernel fd %d\n",
+ __func__, info.kernel_fd);
+ close(kernel_fd);
kernel_fd = info.kernel_fd;
+ }
/*
* If there is no initramfs, set KEXEC_FILE_NO_INITRAMFS flag so that
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] kexec: restore functionality to preserve fd xattrs for uncompressed kernel images
2026-05-07 21:54 [PATCH] kexec: restore functionality to preserve fd xattrs for uncompressed kernel images Alejandro Hernandez
@ 2026-05-19 9:41 ` Simon Horman
2026-05-22 17:09 ` Alejandro Hernandez
0 siblings, 1 reply; 3+ messages in thread
From: Simon Horman @ 2026-05-19 9:41 UTC (permalink / raw)
To: Alejandro Hernandez; +Cc: kexec
On Thu, May 07, 2026 at 09:54:17PM +0000, Alejandro Hernandez wrote:
> Since commit 714fa115 xattrs attached to a kernel image file (such as IMA
> signatures) are not being preserved, do_kexec_file_load() was modified to use
> memfd_create() which now passes an anonymous file descriptor to
> kexec_file_load(). This change eliminated the filesystem inode identity of the
> original kernel file, hence attributes are no longer visible to the kernel IMA
> appraisal handler during kexec_file_load, causing IMA policy enforcement to fail
> even for validly signed kernel images.
>
> This patch attempts to restore such behavior although, only does it for
> uncompressed kernel images. To do this, we first figure out if the image file is
> compressed or not and call each method accordingly.
>
> Compressed images continue to use memfd and cannot carry forward the original fd
> security attributes, since their decompressed bytes do not match the signed
> artifact. Proper handling of compressed images with IMA would require either
> signing the decompressed artifact or kernel-side support for decompression
> within the kexec_file_load path.
>
> Signed-off-by: Alejandro Hernandez Samaniego <alhe@linux.microsoft.com>
Hi Alejandro,
Thanks for the patch.
Overall this looks good to me. But I'm wondering if you could spin a v2
to address a minor code-style issue I have noted inline.
> ---
> kexec/kexec.c | 42 +++++++++++++++++++++++++++++++++++-------
> 1 file changed, 35 insertions(+), 7 deletions(-)
>
> diff --git a/kexec/kexec.c b/kexec/kexec.c
> index 08edfca..a388762 100644
> --- a/kexec/kexec.c
> +++ b/kexec/kexec.c
> @@ -1328,17 +1328,41 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
>
> kernel = argv[fileind];
>
> - /* slurp in the input kernel */
> + /* Hold original fd with its xattrs */
> + kernel_fd = open(kernel, O_RDONLY);
> + if (kernel_fd == -1) {
> + fprintf(stderr, "Failed to open file %s:%s\n", kernel,
> + strerror(errno));
> + return EFAILED;
> + }
> +
> + /* Compressed vs Uncompressed */
> + struct stat kernel_stat;
> + off_t kernel_file_size = -1;
I would prefer if we stuck to declaring local variables
at the top of this function.
> + if (fstat(kernel_fd, &kernel_stat) == 0)
> + kernel_file_size = kernel_stat.st_size;
> +
> + /* slurp in the input kernel */
> kernel_buf = slurp_decompress_file(kernel, &kernel_size);
> if (!kernel_buf) {
> fprintf(stderr, "Failed to decompress file %s:%s\n", kernel,
> strerror(errno));
> + close(kernel_fd);
> return EFAILED;
> }
...
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH] kexec: restore functionality to preserve fd xattrs for uncompressed kernel images
2026-05-19 9:41 ` Simon Horman
@ 2026-05-22 17:09 ` Alejandro Hernandez
0 siblings, 0 replies; 3+ messages in thread
From: Alejandro Hernandez @ 2026-05-22 17:09 UTC (permalink / raw)
To: Simon Horman; +Cc: kexec
On 5/19/2026 3:41 AM, Simon Horman wrote:
> On Thu, May 07, 2026 at 09:54:17PM +0000, Alejandro Hernandez wrote:
>> Since commit 714fa115 xattrs attached to a kernel image file (such as IMA
>> signatures) are not being preserved, do_kexec_file_load() was modified to use
>> memfd_create() which now passes an anonymous file descriptor to
>> kexec_file_load(). This change eliminated the filesystem inode identity of the
>> original kernel file, hence attributes are no longer visible to the kernel IMA
>> appraisal handler during kexec_file_load, causing IMA policy enforcement to fail
>> even for validly signed kernel images.
>>
>> This patch attempts to restore such behavior although, only does it for
>> uncompressed kernel images. To do this, we first figure out if the image file is
>> compressed or not and call each method accordingly.
>>
>> Compressed images continue to use memfd and cannot carry forward the original fd
>> security attributes, since their decompressed bytes do not match the signed
>> artifact. Proper handling of compressed images with IMA would require either
>> signing the decompressed artifact or kernel-side support for decompression
>> within the kexec_file_load path.
>>
>> Signed-off-by: Alejandro Hernandez Samaniego <alhe@linux.microsoft.com>
> Hi Alejandro,
>
> Thanks for the patch.
>
> Overall this looks good to me. But I'm wondering if you could spin a v2
> to address a minor code-style issue I have noted inline.
Hey Simon,
Thanks for the review, sure thing, I will send a v2
Alejandro
>
>> ---
>> kexec/kexec.c | 42 +++++++++++++++++++++++++++++++++++-------
>> 1 file changed, 35 insertions(+), 7 deletions(-)
>>
>> diff --git a/kexec/kexec.c b/kexec/kexec.c
>> index 08edfca..a388762 100644
>> --- a/kexec/kexec.c
>> +++ b/kexec/kexec.c
>> @@ -1328,17 +1328,41 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
>>
>> kernel = argv[fileind];
>>
>> - /* slurp in the input kernel */
>> + /* Hold original fd with its xattrs */
>> + kernel_fd = open(kernel, O_RDONLY);
>> + if (kernel_fd == -1) {
>> + fprintf(stderr, "Failed to open file %s:%s\n", kernel,
>> + strerror(errno));
>> + return EFAILED;
>> + }
>> +
>> + /* Compressed vs Uncompressed */
>> + struct stat kernel_stat;
>> + off_t kernel_file_size = -1;
> I would prefer if we stuck to declaring local variables
> at the top of this function.
>
>> + if (fstat(kernel_fd, &kernel_stat) == 0)
>> + kernel_file_size = kernel_stat.st_size;
>> +
>> + /* slurp in the input kernel */
>> kernel_buf = slurp_decompress_file(kernel, &kernel_size);
>> if (!kernel_buf) {
>> fprintf(stderr, "Failed to decompress file %s:%s\n", kernel,
>> strerror(errno));
>> + close(kernel_fd);
>> return EFAILED;
>> }
> ...
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-22 17:09 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-07 21:54 [PATCH] kexec: restore functionality to preserve fd xattrs for uncompressed kernel images Alejandro Hernandez
2026-05-19 9:41 ` Simon Horman
2026-05-22 17:09 ` Alejandro Hernandez
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.