* [PATCH v3 1/4] soc: qcom: smem: add IN_PARTITION_RANGE helper
2026-09-24 13:10 [PATCH v3 0/4] Add automotive SMEM hardening for Qualcomm platforms Albert Esteve
@ 2026-09-24 13:10 ` Albert Esteve
2026-10-21 12:23 ` Konrad Dybcio
2026-09-24 13:10 ` [PATCH v3 2/4] soc: qcom: smem: validate private entry list walks Albert Esteve
` (2 subsequent siblings)
3 siblings, 1 reply; 10+ messages in thread
From: Albert Esteve @ 2026-09-24 13:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, Albert Esteve, Sarannya S,
Pranav Mahesh Phansalkar, Sudeepgoud Patil
From: Sarannya S <quic_sarannya@oss.qualcomm.com>
Add IN_PARTITION_RANGE() to test that a pointer lies in [start, end]
and that pointer + size does not wrap.
Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
drivers/soc/qcom/smem.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index b5e7bd8c1512..6783a3c533f0 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -2,6 +2,7 @@
/*
* Copyright (c) 2015, Sony Mobile Communications AB.
* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/debugfs.h>
@@ -88,6 +89,17 @@
/* Processor/host identifier for the global partition */
#define SMEM_GLOBAL_HOST 0xfffe
+/* Entry range check
+ * ptr >= start : Checks if ptr is greater than the start of access region
+ * ptr + size >= ptr: Check for integer overflow (On 32bit system where ptr
+ * and size are 32bits, ptr + size can wrap around to be a small integer)
+ * ptr + size <= end: Checks if ptr+size is less than the end of access region
+ */
+#define IN_PARTITION_RANGE(ptr, size, start, end) \
+ (((void *)(ptr) >= (void *)(start)) && \
+ (((void *)(ptr) + (size)) >= (void *)(ptr)) && \
+ (((void *)(ptr) + (size)) <= (void *)(end)))
+
/**
* struct smem_proc_comm - proc_comm communication struct (legacy)
* @command: current command to be executed
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 1/4] soc: qcom: smem: add IN_PARTITION_RANGE helper
2026-09-24 13:10 ` [PATCH v3 1/4] soc: qcom: smem: add IN_PARTITION_RANGE helper Albert Esteve
@ 2026-10-21 12:23 ` Konrad Dybcio
2026-10-22 7:33 ` Albert Esteve
0 siblings, 1 reply; 10+ messages in thread
From: Konrad Dybcio @ 2026-10-21 12:23 UTC (permalink / raw)
To: Albert Esteve, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, Sarannya S,
Pranav Mahesh Phansalkar, Sudeepgoud Patil
On 9/24/26 3:10 PM, Albert Esteve wrote:
> From: Sarannya S <quic_sarannya@oss.qualcomm.com>
>
> Add IN_PARTITION_RANGE() to test that a pointer lies in [start, end]
> and that pointer + size does not wrap.
>
> Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
> Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
> Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
> drivers/soc/qcom/smem.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> index b5e7bd8c1512..6783a3c533f0 100644
> --- a/drivers/soc/qcom/smem.c
> +++ b/drivers/soc/qcom/smem.c
> @@ -2,6 +2,7 @@
> /*
> * Copyright (c) 2015, Sony Mobile Communications AB.
> * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> */
>
> #include <linux/debugfs.h>
> @@ -88,6 +89,17 @@
> /* Processor/host identifier for the global partition */
> #define SMEM_GLOBAL_HOST 0xfffe
>
> +/* Entry range check
> + * ptr >= start : Checks if ptr is greater than the start of access region
> + * ptr + size >= ptr: Check for integer overflow (On 32bit system where ptr
> + * and size are 32bits, ptr + size can wrap around to be a small integer)
> + * ptr + size <= end: Checks if ptr+size is less than the end of access region
> + */
> +#define IN_PARTITION_RANGE(ptr, size, start, end) \
> + (((void *)(ptr) >= (void *)(start)) && \
> + (((void *)(ptr) + (size)) >= (void *)(ptr)) && \
> + (((void *)(ptr) + (size)) <= (void *)(end)))
LLM is unhappy about the 32-bit base and suggests this instead:
#define IN_PARTITION_RANGE(ptr, size, start, end) \
((void *)(ptr) >= (void *)(start) && \
(void *)(ptr) <= (void *)(end) && \
(size) <= (uintptr_t)(end) - (uintptr_t)(ptr))
Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 1/4] soc: qcom: smem: add IN_PARTITION_RANGE helper
2026-10-21 12:23 ` Konrad Dybcio
@ 2026-10-22 7:33 ` Albert Esteve
0 siblings, 0 replies; 10+ messages in thread
From: Albert Esteve @ 2026-10-22 7:33 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Konrad Dybcio, linux-arm-msm, linux-kernel,
Sarannya S, Pranav Mahesh Phansalkar, Sudeepgoud Patil
On Wed, Oct 21, 2026 at 2:23 PM Konrad Dybcio
<konrad.dybcio@oss.qualcomm.com> wrote:
>
> On 9/24/26 3:10 PM, Albert Esteve wrote:
> > From: Sarannya S <quic_sarannya@oss.qualcomm.com>
> >
> > Add IN_PARTITION_RANGE() to test that a pointer lies in [start, end]
> > and that pointer + size does not wrap.
> >
> > Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
> > Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
> > Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > ---
> > drivers/soc/qcom/smem.c | 12 ++++++++++++
> > 1 file changed, 12 insertions(+)
> >
> > diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
> > index b5e7bd8c1512..6783a3c533f0 100644
> > --- a/drivers/soc/qcom/smem.c
> > +++ b/drivers/soc/qcom/smem.c
> > @@ -2,6 +2,7 @@
> > /*
> > * Copyright (c) 2015, Sony Mobile Communications AB.
> > * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
> > + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> > */
> >
> > #include <linux/debugfs.h>
> > @@ -88,6 +89,17 @@
> > /* Processor/host identifier for the global partition */
> > #define SMEM_GLOBAL_HOST 0xfffe
> >
> > +/* Entry range check
> > + * ptr >= start : Checks if ptr is greater than the start of access region
> > + * ptr + size >= ptr: Check for integer overflow (On 32bit system where ptr
> > + * and size are 32bits, ptr + size can wrap around to be a small integer)
> > + * ptr + size <= end: Checks if ptr+size is less than the end of access region
> > + */
> > +#define IN_PARTITION_RANGE(ptr, size, start, end) \
> > + (((void *)(ptr) >= (void *)(start)) && \
> > + (((void *)(ptr) + (size)) >= (void *)(ptr)) && \
> > + (((void *)(ptr) + (size)) <= (void *)(end)))
>
> LLM is unhappy about the 32-bit base and suggests this instead:
>
> #define IN_PARTITION_RANGE(ptr, size, start, end) \
> ((void *)(ptr) >= (void *)(start) && \
> (void *)(ptr) <= (void *)(end) && \
> (size) <= (uintptr_t)(end) - (uintptr_t)(ptr))
>
I see. I will update it in the next version. Thanks.
> Konrad
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 2/4] soc: qcom: smem: validate private entry list walks
2026-09-24 13:10 [PATCH v3 0/4] Add automotive SMEM hardening for Qualcomm platforms Albert Esteve
2026-09-24 13:10 ` [PATCH v3 1/4] soc: qcom: smem: add IN_PARTITION_RANGE helper Albert Esteve
@ 2026-09-24 13:10 ` Albert Esteve
2026-10-21 12:39 ` Konrad Dybcio
2026-09-24 13:10 ` [PATCH v3 3/4] soc: qcom: smem: validate private item payloads Albert Esteve
2026-09-24 13:10 ` [PATCH v3 4/4] soc: qcom: smem: ignore multi remote host partitions Albert Esteve
3 siblings, 1 reply; 10+ messages in thread
From: Albert Esteve @ 2026-09-24 13:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, Albert Esteve, Sarannya S,
Pranav Mahesh Phansalkar, Sudeepgoud Patil
From: Sarannya S <quic_sarannya@oss.qualcomm.com>
When walking private entries, use the uncached/cached free offsets as
the list bounds, require room for a header before dereferencing, and
reject a next pointer that does not advance.
Skip the cached list when the cached free offset is at the partition
end.
Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
drivers/soc/qcom/smem.c | 50 ++++++++++++++++++++++++++++++++++++-------------
1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 6783a3c533f0..9bf0ec32c9f1 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -421,6 +421,7 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
size_t size)
{
struct smem_private_entry *hdr, *end;
+ struct smem_private_entry *next_hdr;
struct smem_partition_header *phdr;
size_t alloc_size;
void *cached;
@@ -433,19 +434,25 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
end = phdr_to_last_uncached_entry(phdr);
cached = phdr_to_last_cached_entry(phdr);
- if (WARN_ON((void *)end > p_end || cached > p_end))
+ if (WARN_ON(!IN_PARTITION_RANGE(end, 0, phdr, cached) ||
+ cached > p_end))
return -EINVAL;
- while (hdr < end) {
+ while ((hdr + 1) < end) {
if (hdr->canary != SMEM_PRIVATE_CANARY)
goto bad_canary;
if (le16_to_cpu(hdr->item) == item)
return -EEXIST;
- hdr = uncached_entry_next(hdr);
+ next_hdr = uncached_entry_next(hdr);
+
+ if (WARN_ON(next_hdr <= hdr))
+ return -EINVAL;
+
+ hdr = next_hdr;
}
- if (WARN_ON((void *)hdr > p_end))
+ if (WARN_ON((void *)hdr > (void *)end))
return -EINVAL;
/* Check that we don't grow into the cached region */
@@ -604,7 +611,8 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
unsigned int item,
size_t *size)
{
- struct smem_private_entry *e, *end;
+ struct smem_private_entry *e, *uncached_end, *cached_end;
+ struct smem_private_entry *next_e;
struct smem_partition_header *phdr;
void *item_ptr, *p_end;
u32 padding_data;
@@ -614,9 +622,14 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
p_end = (void *)phdr + part->size;
e = phdr_to_first_uncached_entry(phdr);
- end = phdr_to_last_uncached_entry(phdr);
+ uncached_end = phdr_to_last_uncached_entry(phdr);
+ cached_end = phdr_to_last_cached_entry(phdr);
+
+ if (WARN_ON(!IN_PARTITION_RANGE(uncached_end, 0, phdr, cached_end) ||
+ (void *)cached_end > p_end))
+ return ERR_PTR(-EINVAL);
- while (e < end) {
+ while ((e + 1) < uncached_end) {
if (e->canary != SMEM_PRIVATE_CANARY)
goto invalid_canary;
@@ -638,21 +651,28 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
return item_ptr;
}
- e = uncached_entry_next(e);
+ next_e = uncached_entry_next(e);
+ if (WARN_ON(next_e <= e))
+ return ERR_PTR(-EINVAL);
+
+ e = next_e;
}
- if (WARN_ON((void *)e > p_end))
+ if (WARN_ON((void *)e > (void *)uncached_end))
return ERR_PTR(-EINVAL);
/* Item was not found in the uncached list, search the cached list */
+ if (cached_end == p_end)
+ return ERR_PTR(-ENOENT);
+
e = phdr_to_first_cached_entry(phdr, part->cacheline);
- end = phdr_to_last_cached_entry(phdr);
- if (WARN_ON((void *)e < (void *)phdr || (void *)end > p_end))
+ if (WARN_ON(!IN_PARTITION_RANGE(cached_end, 0, uncached_end, p_end) ||
+ !IN_PARTITION_RANGE(e, sizeof(*e), cached_end, p_end)))
return ERR_PTR(-EINVAL);
- while (e > end) {
+ while (e > cached_end) {
if (e->canary != SMEM_PRIVATE_CANARY)
goto invalid_canary;
@@ -674,7 +694,11 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
return item_ptr;
}
- e = cached_entry_next(e, part->cacheline);
+ next_e = cached_entry_next(e, part->cacheline);
+ if (WARN_ON(next_e >= e))
+ return ERR_PTR(-EINVAL);
+
+ e = next_e;
}
if (WARN_ON((void *)e < (void *)phdr))
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 2/4] soc: qcom: smem: validate private entry list walks
2026-09-24 13:10 ` [PATCH v3 2/4] soc: qcom: smem: validate private entry list walks Albert Esteve
@ 2026-10-21 12:39 ` Konrad Dybcio
2026-10-22 8:20 ` Albert Esteve
0 siblings, 1 reply; 10+ messages in thread
From: Konrad Dybcio @ 2026-10-21 12:39 UTC (permalink / raw)
To: Albert Esteve, Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, Sarannya S,
Pranav Mahesh Phansalkar, Sudeepgoud Patil
On 9/24/26 3:10 PM, Albert Esteve wrote:
> From: Sarannya S <quic_sarannya@oss.qualcomm.com>
>
> When walking private entries, use the uncached/cached free offsets as
> the list bounds, require room for a header before dereferencing, and
> reject a next pointer that does not advance.
>
> Skip the cached list when the cached free offset is at the partition
> end.
>
> Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
> Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
> Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
[...]
> - while (hdr < end) {
> + while ((hdr + 1) < end) {
This will reject a header that's at the tail of the buffer, need
to make this <= instead
[...]
> - while (e < end) {
> + while ((e + 1) < uncached_end) {
Likewise
[...]
> - e = cached_entry_next(e, part->cacheline);
> + next_e = cached_entry_next(e, part->cacheline);
> + if (WARN_ON(next_e >= e))
> + return ERR_PTR(-EINVAL);
> +
> + e = next_e;
> }
>
> if (WARN_ON((void *)e < (void *)phdr))
And LLM thinks should compare against cached_end
Konrad
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 2/4] soc: qcom: smem: validate private entry list walks
2026-10-21 12:39 ` Konrad Dybcio
@ 2026-10-22 8:20 ` Albert Esteve
2026-10-22 15:05 ` Albert Esteve
0 siblings, 1 reply; 10+ messages in thread
From: Albert Esteve @ 2026-10-22 8:20 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Konrad Dybcio, linux-arm-msm, linux-kernel,
Sarannya S, Pranav Mahesh Phansalkar, Sudeepgoud Patil
On Wed, Oct 21, 2026 at 2:39 PM Konrad Dybcio
<konrad.dybcio@oss.qualcomm.com> wrote:
>
> On 9/24/26 3:10 PM, Albert Esteve wrote:
> > From: Sarannya S <quic_sarannya@oss.qualcomm.com>
> >
> > When walking private entries, use the uncached/cached free offsets as
> > the list bounds, require room for a header before dereferencing, and
> > reject a next pointer that does not advance.
> >
> > Skip the cached list when the cached free offset is at the partition
> > end.
> >
> > Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
> > Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
> > Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
> > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > ---
>
> [...]
>
> > - while (hdr < end) {
> > + while ((hdr + 1) < end) {
>
> This will reject a header that's at the tail of the buffer, need
> to make this <= instead
Roger. This is a bit hard to read as intuitively I would have thought
end is the first free byte after the last header, so `(hdr + 1) < end`
should include it? End uses `offset_free_uncached` which should be
bigger than `hdr + 1` and it would not miss the tail. But being
defensive about its value seems like the right call. I will change it.
>
> [...]
>
> > - while (e < end) {
> > + while ((e + 1) < uncached_end) {
>
> Likewise
>
> [...]
>
> > - e = cached_entry_next(e, part->cacheline);
> > + next_e = cached_entry_next(e, part->cacheline);
> > + if (WARN_ON(next_e >= e))
> > + return ERR_PTR(-EINVAL);
> > +
> > + e = next_e;
> > }
> >
> > if (WARN_ON((void *)e < (void *)phdr))
>
> And LLM thinks should compare against cached_end
This is preexisting but I think the LLM is right, and it matches the
theme of the patch. I will change it.
>
> Konrad
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH v3 2/4] soc: qcom: smem: validate private entry list walks
2026-10-22 8:20 ` Albert Esteve
@ 2026-10-22 15:05 ` Albert Esteve
0 siblings, 0 replies; 10+ messages in thread
From: Albert Esteve @ 2026-10-22 15:05 UTC (permalink / raw)
To: Konrad Dybcio
Cc: Bjorn Andersson, Konrad Dybcio, linux-arm-msm, linux-kernel,
Sarannya S, Pranav Mahesh Phansalkar, Sudeepgoud Patil
On Thu, Oct 22, 2026 at 10:20:05AM +0200, Albert Esteve wrote:
> On Wed, Oct 21, 2026 at 2:39 PM Konrad Dybcio
> <konrad.dybcio@oss.qualcomm.com> wrote:
> >
> > On 9/24/26 3:10 PM, Albert Esteve wrote:
> > > From: Sarannya S <quic_sarannya@oss.qualcomm.com>
> > >
> > > When walking private entries, use the uncached/cached free offsets as
> > > the list bounds, require room for a header before dereferencing, and
> > > reject a next pointer that does not advance.
> > >
> > > Skip the cached list when the cached free offset is at the partition
> > > end.
> > >
> > > Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
> > > Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
> > > Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
> > > Signed-off-by: Albert Esteve <aesteve@redhat.com>
> > > ---
> >
> > [...]
> >
> > > - while (hdr < end) {
> > > + while ((hdr + 1) < end) {
> >
> > This will reject a header that's at the tail of the buffer, need
> > to make this <= instead
>
> Roger. This is a bit hard to read as intuitively I would have thought
> end is the first free byte after the last header, so `(hdr + 1) < end`
> should include it? End uses `offset_free_uncached` which should be
> bigger than `hdr + 1` and it would not miss the tail. But being
> defensive about its value seems like the right call. I will change it.
>
> >
> > [...]
> >
> > > - while (e < end) {
> > > + while ((e + 1) < uncached_end) {
> >
> > Likewise
> >
> > [...]
> >
> > > - e = cached_entry_next(e, part->cacheline);
> > > + next_e = cached_entry_next(e, part->cacheline);
> > > + if (WARN_ON(next_e >= e))
> > > + return ERR_PTR(-EINVAL);
> > > +
> > > + e = next_e;
> > > }
> > >
> > > if (WARN_ON((void *)e < (void *)phdr))
> >
> > And LLM thinks should compare against cached_end
>
> This is preexisting but I think the LLM is right, and it matches the
> theme of the patch. I will change it.
I've sent a new version and Sashiko still complains. Maybe we can just drop the check?
We can continue the conversation in the new version of the series. I wrote here because it had the context.
BR,
Albert
>
> >
> > Konrad
> >
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v3 3/4] soc: qcom: smem: validate private item payloads
2026-09-24 13:10 [PATCH v3 0/4] Add automotive SMEM hardening for Qualcomm platforms Albert Esteve
2026-09-24 13:10 ` [PATCH v3 1/4] soc: qcom: smem: add IN_PARTITION_RANGE helper Albert Esteve
2026-09-24 13:10 ` [PATCH v3 2/4] soc: qcom: smem: validate private entry list walks Albert Esteve
@ 2026-09-24 13:10 ` Albert Esteve
2026-09-24 13:10 ` [PATCH v3 4/4] soc: qcom: smem: ignore multi remote host partitions Albert Esteve
3 siblings, 0 replies; 10+ messages in thread
From: Albert Esteve @ 2026-09-24 13:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, Albert Esteve, Sarannya S,
Pranav Mahesh Phansalkar, Sudeepgoud Patil
From: Sarannya S <quic_sarannya@oss.qualcomm.com>
Validate a matching entry's size and padding even when the caller does
not request the length, and check that the payload stays inside the
same region as the header.
Signed-off-by: Sarannya S <quic_sarannya@oss.qualcomm.com>
Signed-off-by: Pranav Mahesh Phansalkar <quic_pphansal@oss.qualcomm.com>
Signed-off-by: Sudeepgoud Patil <quic_sudeepgo@oss.qualcomm.com>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
drivers/soc/qcom/smem.c | 39 +++++++++++++++++++++------------------
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 9bf0ec32c9f1..393257cbe5e1 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -615,6 +615,7 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
struct smem_private_entry *next_e;
struct smem_partition_header *phdr;
void *item_ptr, *p_end;
+ size_t entry_size = 0;
u32 padding_data;
u32 e_size;
@@ -634,20 +635,21 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
goto invalid_canary;
if (le16_to_cpu(e->item) == item) {
- if (size != NULL) {
- e_size = le32_to_cpu(e->size);
- padding_data = le16_to_cpu(e->padding_data);
+ e_size = le32_to_cpu(e->size);
+ padding_data = le16_to_cpu(e->padding_data);
- if (WARN_ON(e_size > part->size || padding_data > e_size))
- return ERR_PTR(-EINVAL);
-
- *size = e_size - padding_data;
- }
+ if (e_size < part->size && padding_data < e_size)
+ entry_size = e_size - padding_data;
+ else
+ return ERR_PTR(-EINVAL);
item_ptr = uncached_entry_to_item(e);
- if (WARN_ON(item_ptr > p_end))
+ if (WARN_ON(!IN_PARTITION_RANGE(item_ptr, entry_size, e, uncached_end)))
return ERR_PTR(-EINVAL);
+ if (size != NULL)
+ *size = entry_size;
+
return item_ptr;
}
@@ -677,20 +679,21 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
goto invalid_canary;
if (le16_to_cpu(e->item) == item) {
- if (size != NULL) {
- e_size = le32_to_cpu(e->size);
- padding_data = le16_to_cpu(e->padding_data);
+ e_size = le32_to_cpu(e->size);
+ padding_data = le16_to_cpu(e->padding_data);
- if (WARN_ON(e_size > part->size || padding_data > e_size))
- return ERR_PTR(-EINVAL);
-
- *size = e_size - padding_data;
- }
+ if (e_size < part->size && padding_data < e_size)
+ entry_size = e_size - padding_data;
+ else
+ return ERR_PTR(-EINVAL);
item_ptr = cached_entry_to_item(e);
- if (WARN_ON(item_ptr < (void *)phdr))
+ if (WARN_ON(!IN_PARTITION_RANGE(item_ptr, entry_size, cached_end, e)))
return ERR_PTR(-EINVAL);
+ if (size != NULL)
+ *size = entry_size;
+
return item_ptr;
}
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread* [PATCH v3 4/4] soc: qcom: smem: ignore multi remote host partitions
2026-09-24 13:10 [PATCH v3 0/4] Add automotive SMEM hardening for Qualcomm platforms Albert Esteve
` (2 preceding siblings ...)
2026-09-24 13:10 ` [PATCH v3 3/4] soc: qcom: smem: validate private item payloads Albert Esteve
@ 2026-09-24 13:10 ` Albert Esteve
3 siblings, 0 replies; 10+ messages in thread
From: Albert Esteve @ 2026-09-24 13:10 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio
Cc: linux-arm-msm, linux-kernel, Albert Esteve, Tony Truong, Konrad Dybcio
From: Tony Truong <quic_truong@oss.qualcomm.com>
SMEM now supports more than just 1-to-1 partitions. It is possible for
a partition to have multiple remote host and the logic to handle that
does not exist. For now, skip all partitions which has multiple remote
hosts.
Signed-off-by: Tony Truong <quic_truong@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Albert Esteve <aesteve@redhat.com>
---
drivers/soc/qcom/smem.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 393257cbe5e1..a7a1840b7ff7 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -89,6 +89,9 @@
/* Processor/host identifier for the global partition */
#define SMEM_GLOBAL_HOST 0xfffe
+/* Processor/host identifier for multi host partition */
+#define SMEM_MULTI_HOST 0xfffc
+
/* Entry range check
* ptr >= start : Checks if ptr is greater than the start of access region
* ptr + size >= ptr: Check for integer overflow (On 32bit system where ptr
@@ -1091,6 +1094,9 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host)
else
continue;
+ if (remote_host == SMEM_MULTI_HOST)
+ continue;
+
if (xa_load(&smem->partitions, remote_host)) {
dev_err(smem->dev, "duplicate host %u\n", remote_host);
return -EINVAL;
--
2.55.0
^ permalink raw reply [flat|nested] 10+ messages in thread