From 174c107f6a511f27fe6508da177244d2d467806e Mon Sep 17 00:00:00 2001 From: Amine Najahi Date: Tue, 16 Aug 2022 23:11:57 -0400 Subject: [PATCH] disp: msm: sde: bound event log traversal to allocated memory in coredump Currently, driver is determining the amount of memory to allocate based on the event log object indexes (first, last). The last index can change if there is additional logging done during the coredump phase and potentially cause an out-of-bound memory access during buffer traversal. This change restrict the event log object traversal to a maximum of the output buffer size. Change-Id: I91e5734362d2d7a796129fce85e27611bab2245f Signed-off-by: Amine Najahi --- msm/sde_dbg.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/msm/sde_dbg.c b/msm/sde_dbg.c index 2eacf1f8..7aef13e9 100644 --- a/msm/sde_dbg.c +++ b/msm/sde_dbg.c @@ -1191,7 +1191,6 @@ void sde_evtlog_dump_all(struct sde_dbg_evtlog *evtlog) char buf[SDE_EVTLOG_BUF_MAX]; bool update_last_entry = true; u32 in_log, in_mem, in_dump; - u32 log_size = 0; char *dump_addr = NULL; int i; @@ -1202,21 +1201,22 @@ void sde_evtlog_dump_all(struct sde_dbg_evtlog *evtlog) in_mem = evtlog->dump_mode & SDE_DBG_DUMP_IN_MEM; in_dump = evtlog->dump_mode & SDE_DBG_DUMP_IN_COREDUMP; - log_size = sde_evtlog_count(evtlog); - if (!log_size) - return; - if (!evtlog->dumped_evtlog) { - if (in_mem) - log_size = SDE_EVTLOG_ENTRY; - evtlog->dumped_evtlog = kvzalloc((log_size * SDE_EVTLOG_BUF_MAX), GFP_KERNEL); - evtlog->log_size = log_size; + evtlog->dumped_evtlog = kvzalloc((SDE_EVTLOG_ENTRY * SDE_EVTLOG_BUF_MAX), + GFP_KERNEL); + if (!evtlog->dumped_evtlog) + return; + + evtlog->log_size = SDE_EVTLOG_ENTRY; } dump_addr = evtlog->dumped_evtlog; if ((in_mem || in_dump) && dump_addr && (!sde_dbg_base.coredump_reading)) { - while (sde_evtlog_dump_to_buffer(evtlog, dump_addr, SDE_EVTLOG_BUF_MAX, - update_last_entry, true)) { + for (i = 0; i < evtlog->log_size; i++) { + if (!sde_evtlog_dump_to_buffer(evtlog, dump_addr, SDE_EVTLOG_BUF_MAX, + update_last_entry, true)) + break; + dump_addr += SDE_EVTLOG_BUF_MAX; update_last_entry = false; } @@ -1232,8 +1232,11 @@ void sde_evtlog_dump_all(struct sde_dbg_evtlog *evtlog) } if (in_log) { - while (sde_evtlog_dump_to_buffer(evtlog, buf, sizeof(buf), - update_last_entry, false)) { + for (i = 0; i < evtlog->log_size; i++) { + if (!sde_evtlog_dump_to_buffer(evtlog, buf, SDE_EVTLOG_BUF_MAX, + update_last_entry, false)) + break; + pr_info("%s\n", buf); update_last_entry = false; }