* [PATCH 0/3] (no cover subject)
@ 2025-06-05 13:42 Bjorn Andersson
2025-06-05 13:43 ` [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header Bjorn Andersson
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Bjorn Andersson @ 2025-06-05 13:42 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, linux-remoteproc, Mukesh Ojha,
Doug Anderson, Bjorn Andersson, stable
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
Bjorn Andersson (3):
soc: qcom: mdt_loader: Ensure we don't read past the ELF header
soc: qcom: mdt_loader: Rename mdt_phdr_valid()
soc: qcom: mdt_loader: Actually use the e_phoff
drivers/soc/qcom/mdt_loader.c | 57 +++++++++++++++++++++++++++++++++++--------
1 file changed, 47 insertions(+), 10 deletions(-)
---
base-commit: a0bea9e39035edc56a994630e6048c8a191a99d8
change-id: 20250604-mdt-loader-validation-and-fixes-5c3267f5b19f
Best regards,
--
Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header
2025-06-05 13:42 [PATCH 0/3] (no cover subject) Bjorn Andersson
@ 2025-06-05 13:43 ` Bjorn Andersson
2025-06-05 15:57 ` Dmitry Baryshkov
2025-06-05 13:43 ` [PATCH 2/3] soc: qcom: mdt_loader: Rename mdt_phdr_valid() Bjorn Andersson
2025-06-05 13:43 ` [PATCH 3/3] soc: qcom: mdt_loader: Actually use the e_phoff Bjorn Andersson
2 siblings, 1 reply; 9+ messages in thread
From: Bjorn Andersson @ 2025-06-05 13:43 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, linux-remoteproc, Mukesh Ojha,
Doug Anderson, Bjorn Andersson, stable
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.
Fixes: 2aad40d911ee ("remoteproc: Move qcom_mdt_loader into drivers/soc/qcom")
Cc: <stable@vger.kernel.org>
Reported-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
drivers/soc/qcom/mdt_loader.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index b2c0fb55d4ae678ee333f0d6b8b586de319f53b1..1da22b23d19d28678ec78cccdf8c328b50d3ffda 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -18,6 +18,31 @@
#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;
+
+ phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff);
+ if (phend > fw->size)
+ 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)
@@ -82,6 +107,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 +162,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 +245,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 +344,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);
--
2.49.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] soc: qcom: mdt_loader: Rename mdt_phdr_valid()
2025-06-05 13:42 [PATCH 0/3] (no cover subject) Bjorn Andersson
2025-06-05 13:43 ` [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header Bjorn Andersson
@ 2025-06-05 13:43 ` Bjorn Andersson
2025-06-05 15:58 ` Dmitry Baryshkov
2025-06-05 13:43 ` [PATCH 3/3] soc: qcom: mdt_loader: Actually use the e_phoff Bjorn Andersson
2 siblings, 1 reply; 9+ messages in thread
From: Bjorn Andersson @ 2025-06-05 13:43 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, linux-remoteproc, Mukesh Ojha,
Doug Anderson, Bjorn Andersson
The function checks if a program header refers to a PT_LOAD segment,
that isn't a hash segment (which should be PT_LOAD in the first place),
andwith non-zero size. That's not the definition of "valid", but rather
if it's "loadable".
Rename the function to reflect what it does.
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
drivers/soc/qcom/mdt_loader.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index 1da22b23d19d28678ec78cccdf8c328b50d3ffda..dd3875dd7ef68d1f135efd8efdf5634f27aadd5e 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -43,7 +43,7 @@ static bool mdt_header_valid(const struct firmware *fw)
return true;
}
-static bool mdt_phdr_valid(const struct elf32_phdr *phdr)
+static bool mdt_phdr_loadable(const struct elf32_phdr *phdr)
{
if (phdr->p_type != PT_LOAD)
return false;
@@ -116,7 +116,7 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
- if (!mdt_phdr_valid(phdr))
+ if (!mdt_phdr_loadable(phdr))
continue;
if (phdr->p_paddr < min_addr)
@@ -254,7 +254,7 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
- if (!mdt_phdr_valid(phdr))
+ if (!mdt_phdr_loadable(phdr))
continue;
if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
@@ -354,7 +354,7 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
- if (!mdt_phdr_valid(phdr))
+ if (!mdt_phdr_loadable(phdr))
continue;
if (phdr->p_flags & QCOM_MDT_RELOCATABLE)
@@ -381,7 +381,7 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
- if (!mdt_phdr_valid(phdr))
+ if (!mdt_phdr_loadable(phdr))
continue;
offset = phdr->p_paddr - mem_reloc;
--
2.49.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/3] soc: qcom: mdt_loader: Actually use the e_phoff
2025-06-05 13:42 [PATCH 0/3] (no cover subject) Bjorn Andersson
2025-06-05 13:43 ` [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header Bjorn Andersson
2025-06-05 13:43 ` [PATCH 2/3] soc: qcom: mdt_loader: Rename mdt_phdr_valid() Bjorn Andersson
@ 2025-06-05 13:43 ` Bjorn Andersson
2025-06-05 15:58 ` Dmitry Baryshkov
2 siblings, 1 reply; 9+ messages in thread
From: Bjorn Andersson @ 2025-06-05 13:43 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, linux-remoteproc, Mukesh Ojha,
Doug Anderson, Bjorn Andersson
Rather than relying/assuming that the tools generating the firmware
places the program headers immediately following the ELF header, use
e_phoff as intended to find the program headers.
Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
---
drivers/soc/qcom/mdt_loader.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
index dd3875dd7ef68d1f135efd8efdf5634f27aadd5e..01fea4c510717197a67a529cfa467c6a9a3ab55d 100644
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -111,7 +111,7 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw)
return -EINVAL;
ehdr = (struct elf32_hdr *)fw->data;
- phdrs = (struct elf32_phdr *)(ehdr + 1);
+ phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
@@ -166,7 +166,7 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len,
return ERR_PTR(-EINVAL);
ehdr = (struct elf32_hdr *)fw->data;
- phdrs = (struct elf32_phdr *)(ehdr + 1);
+ phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
if (ehdr->e_phnum < 2)
return ERR_PTR(-EINVAL);
@@ -249,7 +249,7 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
return -EINVAL;
ehdr = (struct elf32_hdr *)fw->data;
- phdrs = (struct elf32_phdr *)(ehdr + 1);
+ phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
@@ -304,7 +304,7 @@ static bool qcom_mdt_bins_are_split(const struct firmware *fw, const char *fw_na
int i;
ehdr = (struct elf32_hdr *)fw->data;
- phdrs = (struct elf32_phdr *)(ehdr + 1);
+ phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++) {
/*
@@ -349,7 +349,7 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw,
is_split = qcom_mdt_bins_are_split(fw, fw_name);
ehdr = (struct elf32_hdr *)fw->data;
- phdrs = (struct elf32_phdr *)(ehdr + 1);
+ phdrs = (struct elf32_phdr *)(fw->data + ehdr->e_phoff);
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = &phdrs[i];
--
2.49.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header
2025-06-05 13:43 ` [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header Bjorn Andersson
@ 2025-06-05 15:57 ` Dmitry Baryshkov
2025-06-05 19:29 ` Bjorn Andersson
0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-06-05 15:57 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Bjorn Andersson, Konrad Dybcio, linux-arm-msm, linux-kernel,
linux-remoteproc, Mukesh Ojha, Doug Anderson, stable
On Thu, Jun 05, 2025 at 08:43:00AM -0500, Bjorn Andersson wrote:
> 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.
>
> Fixes: 2aad40d911ee ("remoteproc: Move qcom_mdt_loader into drivers/soc/qcom")
> Cc: <stable@vger.kernel.org>
> Reported-by: Doug Anderson <dianders@chromium.org>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> ---
> drivers/soc/qcom/mdt_loader.c | 37 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 37 insertions(+)
>
> diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> index b2c0fb55d4ae678ee333f0d6b8b586de319f53b1..1da22b23d19d28678ec78cccdf8c328b50d3ffda 100644
> --- a/drivers/soc/qcom/mdt_loader.c
> +++ b/drivers/soc/qcom/mdt_loader.c
> @@ -18,6 +18,31 @@
> #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;
> +
> + phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff);
Nit, this should be a max(sizeof() and ehdr->e_phentsize.
> + if (phend > fw->size)
> + return false;
> +
> + shend = size_add(size_mul(sizeof(struct elf32_shdr), ehdr->e_shnum), ehdr->e_shoff);
> + if (shend > fw->size)
Same for e_shentsize
> + return false;
> +
> + return true;
> +}
> +
> static bool mdt_phdr_valid(const struct elf32_phdr *phdr)
> {
> if (phdr->p_type != PT_LOAD)
> @@ -82,6 +107,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 +162,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 +245,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 +344,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);
>
> --
> 2.49.0
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 2/3] soc: qcom: mdt_loader: Rename mdt_phdr_valid()
2025-06-05 13:43 ` [PATCH 2/3] soc: qcom: mdt_loader: Rename mdt_phdr_valid() Bjorn Andersson
@ 2025-06-05 15:58 ` Dmitry Baryshkov
0 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-06-05 15:58 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Bjorn Andersson, Konrad Dybcio, linux-arm-msm, linux-kernel,
linux-remoteproc, Mukesh Ojha, Doug Anderson
On Thu, Jun 05, 2025 at 08:43:01AM -0500, Bjorn Andersson wrote:
> The function checks if a program header refers to a PT_LOAD segment,
> that isn't a hash segment (which should be PT_LOAD in the first place),
> andwith non-zero size. That's not the definition of "valid", but rather
> if it's "loadable".
>
> Rename the function to reflect what it does.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> ---
> drivers/soc/qcom/mdt_loader.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/3] soc: qcom: mdt_loader: Actually use the e_phoff
2025-06-05 13:43 ` [PATCH 3/3] soc: qcom: mdt_loader: Actually use the e_phoff Bjorn Andersson
@ 2025-06-05 15:58 ` Dmitry Baryshkov
0 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-06-05 15:58 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Bjorn Andersson, Konrad Dybcio, linux-arm-msm, linux-kernel,
linux-remoteproc, Mukesh Ojha, Doug Anderson
On Thu, Jun 05, 2025 at 08:43:02AM -0500, Bjorn Andersson wrote:
> Rather than relying/assuming that the tools generating the firmware
> places the program headers immediately following the ELF header, use
> e_phoff as intended to find the program headers.
>
> Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> ---
> drivers/soc/qcom/mdt_loader.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header
2025-06-05 15:57 ` Dmitry Baryshkov
@ 2025-06-05 19:29 ` Bjorn Andersson
2025-06-06 3:18 ` Dmitry Baryshkov
0 siblings, 1 reply; 9+ messages in thread
From: Bjorn Andersson @ 2025-06-05 19:29 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Bjorn Andersson, Konrad Dybcio, linux-arm-msm, linux-kernel,
linux-remoteproc, Mukesh Ojha, Doug Anderson, stable
On Thu, Jun 05, 2025 at 06:57:41PM +0300, Dmitry Baryshkov wrote:
> On Thu, Jun 05, 2025 at 08:43:00AM -0500, Bjorn Andersson wrote:
> > 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.
> >
> > Fixes: 2aad40d911ee ("remoteproc: Move qcom_mdt_loader into drivers/soc/qcom")
> > Cc: <stable@vger.kernel.org>
> > Reported-by: Doug Anderson <dianders@chromium.org>
> > Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> > ---
> > drivers/soc/qcom/mdt_loader.c | 37 +++++++++++++++++++++++++++++++++++++
> > 1 file changed, 37 insertions(+)
> >
> > diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> > index b2c0fb55d4ae678ee333f0d6b8b586de319f53b1..1da22b23d19d28678ec78cccdf8c328b50d3ffda 100644
> > --- a/drivers/soc/qcom/mdt_loader.c
> > +++ b/drivers/soc/qcom/mdt_loader.c
> > @@ -18,6 +18,31 @@
> > #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;
> > +
> > + phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff);
>
> Nit, this should be a max(sizeof() and ehdr->e_phentsize.
>
Hmm, I forgot about e_phentsize.
But the fact is that the check matches what we do below and validates
that we won't reach outside the provided buffer.
If e_phentsize != sizeof(struct elf32_phdr) we're not going to be able
to parse the header.
Not sure if it's worth it, but that would make sense to change
separately. In which case ehdr->e_phentsize * ehdr->e_phnum would be the
correct thing to check (no max()). Or perhaps just a check to ensure
that e_phentsize == sizeof(struct elf32_phdr)?
Regards,
Bjorn
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header
2025-06-05 19:29 ` Bjorn Andersson
@ 2025-06-06 3:18 ` Dmitry Baryshkov
0 siblings, 0 replies; 9+ messages in thread
From: Dmitry Baryshkov @ 2025-06-06 3:18 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Dmitry Baryshkov, Bjorn Andersson, Konrad Dybcio, linux-arm-msm,
linux-kernel, linux-remoteproc, Mukesh Ojha, Doug Anderson,
stable
On Thu, Jun 05, 2025 at 02:29:53PM -0500, Bjorn Andersson wrote:
> On Thu, Jun 05, 2025 at 06:57:41PM +0300, Dmitry Baryshkov wrote:
> > On Thu, Jun 05, 2025 at 08:43:00AM -0500, Bjorn Andersson wrote:
> > > 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.
> > >
> > > Fixes: 2aad40d911ee ("remoteproc: Move qcom_mdt_loader into drivers/soc/qcom")
> > > Cc: <stable@vger.kernel.org>
> > > Reported-by: Doug Anderson <dianders@chromium.org>
> > > Signed-off-by: Bjorn Andersson <bjorn.andersson@oss.qualcomm.com>
> > > ---
> > > drivers/soc/qcom/mdt_loader.c | 37 +++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 37 insertions(+)
> > >
> > > diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c
> > > index b2c0fb55d4ae678ee333f0d6b8b586de319f53b1..1da22b23d19d28678ec78cccdf8c328b50d3ffda 100644
> > > --- a/drivers/soc/qcom/mdt_loader.c
> > > +++ b/drivers/soc/qcom/mdt_loader.c
> > > @@ -18,6 +18,31 @@
> > > #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;
> > > +
> > > + phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff);
> >
> > Nit, this should be a max(sizeof() and ehdr->e_phentsize.
> >
>
> Hmm, I forgot about e_phentsize.
>
> But the fact is that the check matches what we do below and validates
> that we won't reach outside the provided buffer.
> If e_phentsize != sizeof(struct elf32_phdr) we're not going to be able
> to parse the header.
>
> Not sure if it's worth it, but that would make sense to change
> separately. In which case ehdr->e_phentsize * ehdr->e_phnum would be the
> correct thing to check (no max()). Or perhaps just a check to ensure
> that e_phentsize == sizeof(struct elf32_phdr)?
I think it's the best option.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-06-06 3:18 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-05 13:42 [PATCH 0/3] (no cover subject) Bjorn Andersson
2025-06-05 13:43 ` [PATCH 1/3] soc: qcom: mdt_loader: Ensure we don't read past the ELF header Bjorn Andersson
2025-06-05 15:57 ` Dmitry Baryshkov
2025-06-05 19:29 ` Bjorn Andersson
2025-06-06 3:18 ` Dmitry Baryshkov
2025-06-05 13:43 ` [PATCH 2/3] soc: qcom: mdt_loader: Rename mdt_phdr_valid() Bjorn Andersson
2025-06-05 15:58 ` Dmitry Baryshkov
2025-06-05 13:43 ` [PATCH 3/3] soc: qcom: mdt_loader: Actually use the e_phoff Bjorn Andersson
2025-06-05 15:58 ` Dmitry Baryshkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).