summaryrefslogtreecommitdiff
path: root/drivers/soc/qcom/smem.c
diff options
context:
space:
mode:
authorSarannya S <quic_sarannya@quicinc.com>2024-03-21 02:59:56 -0700
committerSarannya S <quic_sarannya@quicinc.com>2024-03-22 11:52:03 +0530
commit7462e3e61f80c615bca0b5d690273318e0504687 (patch)
tree881b3183d3f5269d314cf459db19485657f4432a /drivers/soc/qcom/smem.c
parent71dc69707730a693c883a94f2d390299b49ea144 (diff)
Revert "soc: qcom: smem: Add boundary checks for partitions"
This reverts commit 71dc69707730a693c883a94f2d390299b49ea144. Reason for revert: Few boundary checks are missing Change-Id: Ib6783b43ad447fe5ebaed20a6e7908b96fb87fdf Signed-off-by: Sarannya S <quic_sarannya@quicinc.com>
Diffstat (limited to 'drivers/soc/qcom/smem.c')
-rw-r--r--drivers/soc/qcom/smem.c62
1 files changed, 24 insertions, 38 deletions
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 817e2dfae12d..4958b65ec935 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -86,17 +86,6 @@
/* Max number of processors/hosts in a system */
#define SMEM_HOST_COUNT 9
-/* 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
@@ -326,8 +315,7 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem,
end = phdr_to_last_private_entry(phdr);
cached = phdr_to_first_cached_entry(phdr);
- if (WARN_ON(!IN_PARTITION_RANGE(end, 0, phdr, cached) ||
- cached > p_end))
+ if (WARN_ON((void *)end > p_end || (void *)cached > p_end))
return -EINVAL;
while (hdr < end) {
@@ -496,9 +484,8 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
unsigned item,
size_t *size)
{
-
struct smem_partition_header *phdr;
- struct smem_private_entry *e, *uncached_end, *cached_end;
+ struct smem_private_entry *e, *end;
void *item_ptr, *p_end;
u32 partition_size;
u32 padding_data;
@@ -509,36 +496,35 @@ static void *qcom_smem_get_private(struct qcom_smem *smem,
p_end = (void *)phdr + partition_size;
e = phdr_to_first_private_entry(phdr);
- uncached_end = phdr_to_last_private_entry(phdr);
- cached_end = phdr_to_first_cached_entry(phdr);
+ end = phdr_to_last_private_entry(phdr);
- if (WARN_ON(!IN_PARTITION_RANGE(uncached_end, 0, phdr, uncached_end)
- || (void *)cached_end > p_end))
+ if (WARN_ON((void *)end > p_end))
return ERR_PTR(-EINVAL);
-
- while ((e < uncached_end) && ((e + 1) < uncached_end)) {
- if (e->canary != SMEM_PRIVATE_CANARY)
- goto invalid_canary;
+ while (e < end) {
+ if (e->canary != SMEM_PRIVATE_CANARY) {
+ dev_err(smem->dev,
+ "Found invalid canary in host %d:%d partition\n",
+ phdr->host0, phdr->host1);
+ return ERR_PTR(-EINVAL);
+ }
if (le16_to_cpu(e->item) == item) {
- e_size = le32_to_cpu(e->size);
- padding_data = le16_to_cpu(e->padding_data);
-
- if (e_size < partition_size && padding_data < e_size)
- entry_size = e_size - padding_data;
- else
+ if (size != NULL) {
+ e_size = le32_to_cpu(e->size);
+ padding_data = le16_to_cpu(e->padding_data);
+
+ if (e_size < partition_size
+ && padding_data < e_size)
+ *size = e_size - padding_data;
+ else
+ return ERR_PTR(-EINVAL);
+ }
+
+ item_ptr = entry_to_item(e);
+ if (WARN_ON(item_ptr > p_end))
return ERR_PTR(-EINVAL);
- item_ptr = entry_to_item(e);
-
- 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;
}