* [PATCH] kexec: return -ENOEXEC from image probe functions on mismatch
@ 2026-08-13 7:06 Mukesh Pilaniya
2026-08-13 13:13 ` Philipp Rudo
0 siblings, 1 reply; 2+ messages in thread
From: Mukesh Pilaniya @ 2026-08-13 7:06 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, Mark Rutland, Huacai Chen,
WANG Xuerui, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Andrew Morton, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Tao Liu, Philipp Rudo
Cc: linux-arm-kernel, linux-kernel, loongarch, linux-riscv, kexec,
Mukesh Pilaniya
Several kexec_file_load() image probe functions return -EINVAL when
they do not recognize the image format. A probe function that rejects
an image should return -ENOEXEC to indicate that the image is not a
recognized executable format. -EINVAL implies a problem with the
syscall parameters, not with image recognition.
kexec_image_probe_default() iterates through registered loaders and
returns the last probe's error code to the caller. That error
propagates as the kexec_file_load() return value to userspace.
Returning -EINVAL from a probe when no loader matches is semantically
incorrect and misleads userspace about the nature of the failure.
Return -ENOEXEC from all probe functions and their helpers when the
image format is not recognized.
Signed-off-by: Mukesh Pilaniya <mpilaniy@redhat.com>
---
branch: next-20260812
base commit: 28d012efb4327f9c75d5e042a7c91e9a542efa98
---
arch/arm64/kernel/kexec_image.c | 4 ++--
arch/loongarch/kernel/kexec_efi.c | 4 ++--
arch/riscv/kernel/kexec_image.c | 4 ++--
kernel/kexec_elf.c | 4 ++--
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
index b70f4df15a1a..101259874d44 100644
--- a/arch/arm64/kernel/kexec_image.c
+++ b/arch/arm64/kernel/kexec_image.c
@@ -25,10 +25,10 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len)
(const struct arm64_image_header *)(kernel_buf);
if (!h || (kernel_len < sizeof(*h)))
- return -EINVAL;
+ return -ENOEXEC;
if (memcmp(&h->magic, ARM64_IMAGE_MAGIC, sizeof(h->magic)))
- return -EINVAL;
+ return -ENOEXEC;
return 0;
}
diff --git a/arch/loongarch/kernel/kexec_efi.c b/arch/loongarch/kernel/kexec_efi.c
index 5ee78ebb1546..28a1d0420ba3 100644
--- a/arch/loongarch/kernel/kexec_efi.c
+++ b/arch/loongarch/kernel/kexec_efi.c
@@ -24,12 +24,12 @@ static int efi_kexec_probe(const char *kernel_buf, unsigned long kernel_len)
if (!h || (kernel_len < sizeof(*h))) {
kexec_dprintk("No LoongArch image header.\n");
- return -EINVAL;
+ return -ENOEXEC;
}
if (!loongarch_header_check_dos_sig(h)) {
kexec_dprintk("No LoongArch PE image header.\n");
- return -EINVAL;
+ return -ENOEXEC;
}
return 0;
diff --git a/arch/riscv/kernel/kexec_image.c b/arch/riscv/kernel/kexec_image.c
index 51dc89259f16..963a25f5b55b 100644
--- a/arch/riscv/kernel/kexec_image.c
+++ b/arch/riscv/kernel/kexec_image.c
@@ -20,7 +20,7 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len)
const struct riscv_image_header *h = (const struct riscv_image_header *)kernel_buf;
if (!h || kernel_len < sizeof(*h))
- return -EINVAL;
+ return -ENOEXEC;
/* According to Documentation/arch/riscv/boot-image-header.rst,
* use "magic2" field to check when version >= 0.2.
@@ -28,7 +28,7 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len)
if (h->version >= RISCV_HEADER_VERSION &&
memcmp(&h->magic2, RISCV_IMAGE_MAGIC2, sizeof(h->magic2)))
- return -EINVAL;
+ return -ENOEXEC;
return 0;
}
diff --git a/kernel/kexec_elf.c b/kernel/kexec_elf.c
index 3a5c25b2adc9..89a444a00693 100644
--- a/kernel/kexec_elf.c
+++ b/kernel/kexec_elf.c
@@ -172,7 +172,7 @@ static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
default:
pr_debug("Unknown ELF class.\n");
- return -EINVAL;
+ return -ENOEXEC;
}
return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
@@ -236,7 +236,7 @@ static int elf_read_phdr(const char *buf, size_t len,
default:
pr_debug("Unknown ELF class.\n");
- return -EINVAL;
+ return -ENOEXEC;
}
return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
---
base-commit: 28d012efb4327f9c75d5e042a7c91e9a542efa98
change-id: 20260813-mpilaniy-ffb0cc92c313
Best regards,
--
Mukesh Pilaniya <mpilaniy@redhat.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] kexec: return -ENOEXEC from image probe functions on mismatch
2026-08-13 7:06 [PATCH] kexec: return -ENOEXEC from image probe functions on mismatch Mukesh Pilaniya
@ 2026-08-13 13:13 ` Philipp Rudo
0 siblings, 0 replies; 2+ messages in thread
From: Philipp Rudo @ 2026-08-13 13:13 UTC (permalink / raw)
To: Mukesh Pilaniya
Cc: Catalin Marinas, Will Deacon, Mark Rutland, Huacai Chen,
WANG Xuerui, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Alexandre Ghiti, Andrew Morton, Baoquan He, Mike Rapoport,
Pasha Tatashin, Pratyush Yadav, Tao Liu, linux-arm-kernel,
linux-kernel, loongarch, linux-riscv, kexec
Hi Mukesh,
the patch looks good to me.
There is also a corresponding kexec-tools patch, which was accidentally
opened as a Github PR (https://github.com/horms/kexec-tools/pull/12).
It will be sent to kexec@lists.infradead.org shortly.
Thanks
Reviewed-by: Philipp Rudo <prudo@redhat.com>
On Thu, 13 Aug 2026 12:36:29 +0530
Mukesh Pilaniya <mpilaniy@redhat.com> wrote:
> Several kexec_file_load() image probe functions return -EINVAL when
> they do not recognize the image format. A probe function that rejects
> an image should return -ENOEXEC to indicate that the image is not a
> recognized executable format. -EINVAL implies a problem with the
> syscall parameters, not with image recognition.
>
> kexec_image_probe_default() iterates through registered loaders and
> returns the last probe's error code to the caller. That error
> propagates as the kexec_file_load() return value to userspace.
> Returning -EINVAL from a probe when no loader matches is semantically
> incorrect and misleads userspace about the nature of the failure.
>
> Return -ENOEXEC from all probe functions and their helpers when the
> image format is not recognized.
>
> Signed-off-by: Mukesh Pilaniya <mpilaniy@redhat.com>
> ---
> branch: next-20260812
> base commit: 28d012efb4327f9c75d5e042a7c91e9a542efa98
> ---
> arch/arm64/kernel/kexec_image.c | 4 ++--
> arch/loongarch/kernel/kexec_efi.c | 4 ++--
> arch/riscv/kernel/kexec_image.c | 4 ++--
> kernel/kexec_elf.c | 4 ++--
> 4 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kernel/kexec_image.c b/arch/arm64/kernel/kexec_image.c
> index b70f4df15a1a..101259874d44 100644
> --- a/arch/arm64/kernel/kexec_image.c
> +++ b/arch/arm64/kernel/kexec_image.c
> @@ -25,10 +25,10 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len)
> (const struct arm64_image_header *)(kernel_buf);
>
> if (!h || (kernel_len < sizeof(*h)))
> - return -EINVAL;
> + return -ENOEXEC;
>
> if (memcmp(&h->magic, ARM64_IMAGE_MAGIC, sizeof(h->magic)))
> - return -EINVAL;
> + return -ENOEXEC;
>
> return 0;
> }
> diff --git a/arch/loongarch/kernel/kexec_efi.c b/arch/loongarch/kernel/kexec_efi.c
> index 5ee78ebb1546..28a1d0420ba3 100644
> --- a/arch/loongarch/kernel/kexec_efi.c
> +++ b/arch/loongarch/kernel/kexec_efi.c
> @@ -24,12 +24,12 @@ static int efi_kexec_probe(const char *kernel_buf, unsigned long kernel_len)
>
> if (!h || (kernel_len < sizeof(*h))) {
> kexec_dprintk("No LoongArch image header.\n");
> - return -EINVAL;
> + return -ENOEXEC;
> }
>
> if (!loongarch_header_check_dos_sig(h)) {
> kexec_dprintk("No LoongArch PE image header.\n");
> - return -EINVAL;
> + return -ENOEXEC;
> }
>
> return 0;
> diff --git a/arch/riscv/kernel/kexec_image.c b/arch/riscv/kernel/kexec_image.c
> index 51dc89259f16..963a25f5b55b 100644
> --- a/arch/riscv/kernel/kexec_image.c
> +++ b/arch/riscv/kernel/kexec_image.c
> @@ -20,7 +20,7 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len)
> const struct riscv_image_header *h = (const struct riscv_image_header *)kernel_buf;
>
> if (!h || kernel_len < sizeof(*h))
> - return -EINVAL;
> + return -ENOEXEC;
>
> /* According to Documentation/arch/riscv/boot-image-header.rst,
> * use "magic2" field to check when version >= 0.2.
> @@ -28,7 +28,7 @@ static int image_probe(const char *kernel_buf, unsigned long kernel_len)
>
> if (h->version >= RISCV_HEADER_VERSION &&
> memcmp(&h->magic2, RISCV_IMAGE_MAGIC2, sizeof(h->magic2)))
> - return -EINVAL;
> + return -ENOEXEC;
>
> return 0;
> }
> diff --git a/kernel/kexec_elf.c b/kernel/kexec_elf.c
> index 3a5c25b2adc9..89a444a00693 100644
> --- a/kernel/kexec_elf.c
> +++ b/kernel/kexec_elf.c
> @@ -172,7 +172,7 @@ static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
>
> default:
> pr_debug("Unknown ELF class.\n");
> - return -EINVAL;
> + return -ENOEXEC;
> }
>
> return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
> @@ -236,7 +236,7 @@ static int elf_read_phdr(const char *buf, size_t len,
>
> default:
> pr_debug("Unknown ELF class.\n");
> - return -EINVAL;
> + return -ENOEXEC;
> }
>
> return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
>
> ---
> base-commit: 28d012efb4327f9c75d5e042a7c91e9a542efa98
> change-id: 20260813-mpilaniy-ffb0cc92c313
>
> Best regards,
> --
> Mukesh Pilaniya <mpilaniy@redhat.com>
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-08-13 13:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-13 7:06 [PATCH] kexec: return -ENOEXEC from image probe functions on mismatch Mukesh Pilaniya
2026-08-13 13:13 ` Philipp Rudo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox