FAILED: patch "[PATCH] soc: qcom: mdt_loader: Ensure we don't read past the ELF" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025082136-finalist-ravage-eaf5@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef Mon Sep 17 00:00:00 2001
From: Bjorn Andersson <[email protected]>
Date: Tue, 10 Jun 2025 21:58:28 -0500
Subject: [PATCH] soc: qcom: mdt_loader: Ensure we don't read past the ELF
header
When the MDT loader is used in remoteproc, the ELF header is sanitized beforehand, but that's not necessary the case for other clients.
Validate the size of the firmware buffer to ensure that we don't read past the end as we iterate over the header. e_phentsize and e_shentsize are validated as well, to ensure that the assumptions about step size in the traversal are valid.
drivers/soc/qcom/mdt_loader.c +43 -0
@@ -18,6 +18,37 @@#include <linux/slab.h> #include <linux/soc/qcom/mdt_loader.h> +static bool mdt_header_valid (const struct firmware *fw) +{ +const struct elf32_hdr *ehdr; +size_t phend; +size_t shend; + +if (fw->size <sizeof (*ehdr)) +return false; + + ehdr = (struct elf32_hdr *)fw->data; + +if (memcmp (ehdr->e_ident,ELFMAG ,SELFMAG )) +return false; + +if (ehdr->e_phentsize !=sizeof (struct elf32_phdr )) +return -EINVAL ; + + phend =size_add (size_mul (sizeof (struct elf32_phdr ), ehdr->e_phnum), ehdr->e_phoff); +if (phend > fw->size) +return false; + +if (ehdr->e_shentsize !=sizeof (struct elf32_shdr )) +return -EINVAL ; + + shend =size_add (size_mul (sizeof (struct elf32_shdr ), ehdr->e_shnum), ehdr->e_shoff); +if (shend > fw->size) +return false; + +return true; +} +static bool mdt_phdr_valid (const struct elf32_phdr *phdr) {if (phdr->p_type !=PT_LOAD )
@@ -82,6 +113,9 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)phys_addr_t max_addr =0 ;int i; +if (!mdt_header_valid (fw)) +return -EINVAL ; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -134,6 +168,9 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,ssize_t ret;void *data; +if (!mdt_header_valid (fw)) +return ERR_PTR (-EINVAL ); + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -214,6 +251,9 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,int ret;int i; +if (!mdt_header_valid (fw)) +return -EINVAL ; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -310,6 +350,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,if (!fw || !mem_region || !mem_phys || !mem_size)return -EINVAL ; +if (!mdt_header_valid (fw)) +return -EINVAL ; + is_split =qcom_mdt_bins_are_split (fw, fw_name); ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
Sasha Levin
maintainerPATCH 1/1 soc: qcom: mdt_loader: Ensure we don't read past the ELF header
From: Bjorn Andersson <[email protected]>
[ Upstream commit 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef ]
When the MDT loader is used in remoteproc, the ELF header is sanitized beforehand, but that's not necessary the case for other clients.
Validate the size of the firmware buffer to ensure that we don't read past the end as we iterate over the header. e_phentsize and e_shentsize are validated as well, to ensure that the assumptions about step size in the traversal are valid.
--- drivers/soc/qcom/mdt_loader.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
drivers/soc/qcom/mdt_loader.c +41 -0
@@ -12,11 +12,43 @@#include <linux/firmware.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/overflow.h> #include <linux/qcom_scm.h> #include <linux/sizes.h> #include <linux/slab.h> #include <linux/soc/qcom/mdt_loader.h> +static bool mdt_header_valid (const struct firmware *fw) +{ +const struct elf32_hdr *ehdr; +size_t phend; +size_t shend; + +if (fw->size <sizeof (*ehdr)) +return false; + + ehdr = (struct elf32_hdr *)fw->data; + +if (memcmp (ehdr->e_ident,ELFMAG ,SELFMAG )) +return false; + +if (ehdr->e_phentsize !=sizeof (struct elf32_phdr )) +return false; + + phend =size_add (size_mul (sizeof (struct elf32_phdr ), ehdr->e_phnum), ehdr->e_phoff); +if (phend > fw->size) +return false; + +if (ehdr->e_shentsize !=sizeof (struct elf32_shdr )) +return false; + + shend =size_add (size_mul (sizeof (struct elf32_shdr ), ehdr->e_shnum), ehdr->e_shoff); +if (shend > fw->size) +return false; + +return true; +} +static bool mdt_phdr_valid (const struct elf32_phdr *phdr) {if (phdr->p_type !=PT_LOAD )
@@ -46,6 +78,9 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)phys_addr_t max_addr =0 ;int i; +if (!mdt_header_valid (fw)) +return -EINVAL ; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -92,6 +127,9 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len)size_t ehdr_size;void *data; +if (!mdt_header_valid (fw)) +return ERR_PTR (-EINVAL ); + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
@@ -151,6 +189,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,if (!fw || !mem_region || !mem_phys || !mem_size)return -EINVAL ; +if (!mdt_header_valid (fw)) +return -EINVAL ; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr +1 );
Signature · 1 line
2.50.1