trace.c: don't split mbox events over the buffer's end and lose them

Don't try to pack the ring buffer to the very last byte so we don't
split (and lose!) trace events across the end and start of the
buffer. The logger on the receive side does not support such
re-assembly.

Note this was never noticed because the logger tends to silently (!)
discard garbage like this, addressed in other commit(s).

Also switch to memset() and memcpy_s()

Fixes commit 271c75aa71 ("debugability: Fix potential buffer overflow
in mbox traces")

Signed-off-by: Marc Herbert <marc.herbert@intel.com>
This commit is contained in:
Marc Herbert 2021-04-17 05:50:17 +00:00 committed by Liam Girdwood
parent d54a9281f8
commit 73378e269f
1 changed files with 13 additions and 21 deletions

View File

@ -42,8 +42,9 @@ struct recent_trace_context {
};
#endif /* CONFIG_TRACE_FILTERING_ADAPTIVE */
/** MAILBOX_TRACE_BASE ring buffer */
struct trace {
uintptr_t pos ; /* trace position */
uintptr_t pos ; /**< offset of the next byte to write */
uint32_t enable;
#if CONFIG_TRACE_FILTERING_ADAPTIVE
bool user_filter_override; /* whether filtering was overridden by user or not */
@ -89,32 +90,23 @@ static void put_header(uint32_t *dst, const struct sof_uuid_entry *uid,
}
/** Ring buffer for the mailbox trace */
static inline void mtrace_event(const char *data, uint32_t length)
{
struct trace *trace = trace_get();
volatile char *t;
uint32_t i, available;
char *t = (char *)MAILBOX_TRACE_BASE;
const int32_t available = MAILBOX_TRACE_SIZE - trace->pos;
available = MAILBOX_TRACE_SIZE - trace->pos;
t = (volatile char *)(MAILBOX_TRACE_BASE);
/* write until we run out of space */
for (i = 0; i < available && i < length; i++)
t[trace->pos + i] = data[i];
dcache_writeback_region((void *)&t[trace->pos], i);
trace->pos += length;
/* if there was more data than space available, wrap back */
if (length > available) {
for (i = 0; i < length - available; i++)
t[i] = data[available + i];
dcache_writeback_region((void *)t, i);
trace->pos = i;
if (available < length) { /* wrap */
memset(t + trace->pos, 0xff, available);
dcache_writeback_region(t + trace->pos, available);
trace->pos = 0;
}
memcpy_s(t + trace->pos, MAILBOX_TRACE_SIZE,
data, length);
dcache_writeback_region(t + trace->pos, length);
trace->pos += length;
}
#if CONFIG_TRACE_FILTERING_VERBOSITY