summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2013-11-27 17:51:31 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2013-11-30 20:46:52 +0100
commita3c5ba3ca71c6c6a72a4ab1ef244d3b4acfb83a9 (patch)
tree98eaf91f134b3a2f7b7d7319a53f42efb2125d21 /src/lib
parent1fefa84405090ef659e561809a043febbef997a9 (diff)
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>
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/cbmem_console.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/lib/cbmem_console.c b/src/lib/cbmem_console.c
index dd883008bf..ac1d8bbd7e 100644
--- a/src/lib/cbmem_console.c
+++ b/src/lib/cbmem_console.c
@@ -113,27 +113,39 @@ void cbmemc_tx_byte(unsigned char data)
*/
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;
struct cbmem_console *old_cons_p;
- int overflow;
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 ?
- old_cons_p->buffer_size : old_cons_p->buffer_cursor;
+ if (cursor > new_cons_p->buffer_size)
+ 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,
copy_size);
cursor += copy_size;
- if (overflow) {
+ if (dropped_chars) {
const char loss_str1[] = "\n\n*** Log truncated, ";
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