CBMEM console: Prevent buffer overrun

Make sure memcpy target and a possible message telling log was truncated
stay within the allocated region for CBMEM console.

This fixes observed CBMEM corruption on platforms that do not use CBMEM
console during romstage. Those platforms will need an additional fix to
reset cursor position to zero on s3 resume.

Change-Id: I76501ca3afc716545ca76ebca1119995126a43f8
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: http://review.coreboot.org/4292
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Idwer Vollering <vidwer@gmail.com>
Reviewed-by: Martin Roth <martin.roth@se-eng.com>
This commit is contained in:
Kyösti Mälkki 2013-11-27 17:51:31 +02:00
parent 1fefa84405
commit a3c5ba3ca7
1 changed files with 19 additions and 7 deletions

View File

@ -113,27 +113,39 @@ void cbmemc_tx_byte(unsigned char data)
*/ */
static void copy_console_buffer(struct cbmem_console *new_cons_p) static void copy_console_buffer(struct cbmem_console *new_cons_p)
{ {
u32 copy_size; u32 copy_size, dropped_chars;
u32 cursor = new_cons_p->buffer_cursor; u32 cursor = new_cons_p->buffer_cursor;
struct cbmem_console *old_cons_p; struct cbmem_console *old_cons_p;
int overflow;
old_cons_p = current_console(); old_cons_p = current_console();
overflow = old_cons_p->buffer_cursor > old_cons_p->buffer_size; if (old_cons_p->buffer_cursor < old_cons_p->buffer_size)
copy_size = old_cons_p->buffer_cursor;
else
copy_size = old_cons_p->buffer_size;
copy_size = overflow ? if (cursor > new_cons_p->buffer_size)
old_cons_p->buffer_size : old_cons_p->buffer_cursor; copy_size = 0;
else if (cursor + copy_size > new_cons_p->buffer_size)
copy_size = new_cons_p->buffer_size - cursor;
dropped_chars = old_cons_p->buffer_cursor - copy_size;
if (dropped_chars) {
/* Reserve 80 chars to report overflow, if possible. */
if (copy_size < 80)
return;
copy_size -= 80;
dropped_chars += 80;
}
memcpy(new_cons_p->buffer_body + cursor, old_cons_p->buffer_body, memcpy(new_cons_p->buffer_body + cursor, old_cons_p->buffer_body,
copy_size); copy_size);
cursor += copy_size; cursor += copy_size;
if (overflow) { if (dropped_chars) {
const char loss_str1[] = "\n\n*** Log truncated, "; const char loss_str1[] = "\n\n*** Log truncated, ";
const char loss_str2[] = " characters dropped. ***\n\n"; const char loss_str2[] = " characters dropped. ***\n\n";
u32 dropped_chars = old_cons_p->buffer_cursor - copy_size;
/* /*
* When running from ROM sprintf is not available, a simple * When running from ROM sprintf is not available, a simple