Skip to content

Commit 743cfae

Browse files
mukeshojha-linuxandersson
authored andcommitted
remoteproc: qcom: Fix minidump out-of-bounds access on subsystems array
MAX_NUM_OF_SS was hardcoded to 10 in the minidump_global_toc struct, which is a direct overlay on an SMEM item allocated by the firmware. Newer Qualcomm SoC firmware allocates space for more subsystems, while older firmware only allocates space for 10. Bumping the constant would cause Linux to read/write beyond the SMEM item boundary on older platforms. Fix this by converting subsystems[] to a flexible array member and deriving the actual number of subsystems at runtime from the size returned by qcom_smem_get(). Add a bounds check on minidump_id against the derived count before indexing into the array. Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Acked-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> Link: https://lore.kernel.org/r/20260331171243.1962067-1-mukesh.ojha@oss.qualcomm.com Signed-off-by: Bjorn Andersson <andersson@kernel.org>
1 parent 479ba9d commit 743cfae

1 file changed

Lines changed: 14 additions & 3 deletions

File tree

drivers/remoteproc/qcom_common.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
#define to_ssr_subdev(d) container_of(d, struct qcom_rproc_ssr, subdev)
2929
#define to_pdm_subdev(d) container_of(d, struct qcom_rproc_pdm, subdev)
3030

31-
#define MAX_NUM_OF_SS 10
3231
#define MAX_REGION_NAME_LENGTH 16
3332
#define SBL_MINIDUMP_SMEM_ID 602
3433
#define MINIDUMP_REGION_VALID ('V' << 24 | 'A' << 16 | 'L' << 8 | 'I' << 0)
@@ -80,7 +79,7 @@ struct minidump_global_toc {
8079
__le32 status;
8180
__le32 md_revision;
8281
__le32 enabled;
83-
struct minidump_subsystem subsystems[MAX_NUM_OF_SS];
82+
struct minidump_subsystem subsystems[];
8483
};
8584

8685
struct qcom_ssr_subsystem {
@@ -151,16 +150,28 @@ void qcom_minidump(struct rproc *rproc, unsigned int minidump_id,
151150
int ret;
152151
struct minidump_subsystem *subsystem;
153152
struct minidump_global_toc *toc;
153+
unsigned int num_ss;
154+
size_t toc_size;
154155

155156
/* Get Global minidump ToC*/
156-
toc = qcom_smem_get(QCOM_SMEM_HOST_ANY, SBL_MINIDUMP_SMEM_ID, NULL);
157+
toc = qcom_smem_get(QCOM_SMEM_HOST_ANY, SBL_MINIDUMP_SMEM_ID, &toc_size);
157158

158159
/* check if global table pointer exists and init is set */
159160
if (IS_ERR(toc) || !toc->status) {
160161
dev_err(&rproc->dev, "Minidump TOC not found in SMEM\n");
161162
return;
162163
}
163164

165+
/* Derive the number of subsystems from the actual SMEM item size */
166+
num_ss = (toc_size - offsetof(struct minidump_global_toc, subsystems)) /
167+
sizeof(struct minidump_subsystem);
168+
169+
if (minidump_id >= num_ss) {
170+
dev_err(&rproc->dev, "Minidump id %d is out of range: %d\n",
171+
minidump_id, num_ss);
172+
return;
173+
}
174+
164175
/* Get subsystem table of contents using the minidump id */
165176
subsystem = &toc->subsystems[minidump_id];
166177

0 commit comments

Comments
 (0)