Fix con_puts buffer overread
ASan reports a 2K read from a small string literal. Also, fix silly double copy in con_add_buffer_line and delete too-short memset in con_add_buffer_line.
This commit is contained in:
parent
779d1b95db
commit
a40c19f770
|
@ -3,6 +3,8 @@
|
|||
#ifndef _CONSOLE_H_
|
||||
#define _CONSOLE_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include "pstypes.h"
|
||||
#include "dxxsconf.h"
|
||||
#include "fmtcheck.h"
|
||||
|
@ -20,7 +22,7 @@
|
|||
#define CON_LINES_ONSCREEN 18
|
||||
#define CON_SCROLL_OFFSET (CON_LINES_ONSCREEN - 3)
|
||||
#define CON_LINES_MAX 128
|
||||
#define CON_LINE_LENGTH 2048
|
||||
static const size_t CON_LINE_LENGTH = 2048;
|
||||
|
||||
#define CON_STATE_OPEN 2
|
||||
#define CON_STATE_OPENING 1
|
||||
|
@ -34,7 +36,16 @@ typedef struct console_buffer
|
|||
} __pack__ console_buffer;
|
||||
|
||||
void con_init(void);
|
||||
void con_puts(int level, const char *str) __attribute_nonnull();
|
||||
void con_puts(int level, const char *str, size_t len) __attribute_nonnull();
|
||||
static inline void con_puts(int level, const char *str)
|
||||
{
|
||||
con_puts(level, str, strlen(str));
|
||||
}
|
||||
template <size_t len>
|
||||
static inline void con_puts(int level, const char (&str)[len])
|
||||
{
|
||||
con_puts(level, str, len - 1);
|
||||
}
|
||||
void con_printf(int level, const char *fmt, ...) __attribute_format_printf(2, 3);
|
||||
#define con_printf(A1,F,...) dxx_call_printf_checked(con_printf,con_puts,(A1),(F),##__VA_ARGS__)
|
||||
void con_showup(void);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -25,7 +26,7 @@ static PHYSFS_file *gamelog_fp=NULL;
|
|||
static struct console_buffer con_buffer[CON_LINES_MAX];
|
||||
static int con_state = CON_STATE_CLOSED, con_scroll_offset = 0, con_size = 0;
|
||||
|
||||
static void con_add_buffer_line(int priority, const char *buffer)
|
||||
static void con_add_buffer_line(int priority, const char *buffer, size_t len)
|
||||
{
|
||||
int i=0;
|
||||
|
||||
|
@ -35,14 +36,11 @@ static void con_add_buffer_line(int priority, const char *buffer)
|
|||
con_buffer[i-1].priority=con_buffer[i].priority;
|
||||
memcpy(&con_buffer[i-1].line,&con_buffer[i].line,CON_LINE_LENGTH);
|
||||
}
|
||||
memset(con_buffer[CON_LINES_MAX-1].line,'\0',sizeof(CON_LINE_LENGTH));
|
||||
con_buffer[CON_LINES_MAX-1].priority=priority;
|
||||
|
||||
memcpy(&con_buffer[CON_LINES_MAX-1].line,buffer,CON_LINE_LENGTH);
|
||||
for (i=0; i<CON_LINE_LENGTH; i++)
|
||||
{
|
||||
con_buffer[CON_LINES_MAX-1].line[i]=buffer[i];
|
||||
}
|
||||
size_t copy = std::min(len, CON_LINE_LENGTH - 1);
|
||||
memcpy(&con_buffer[CON_LINES_MAX-1].line,buffer, copy);
|
||||
con_buffer[CON_LINES_MAX-1].line[copy] = 0;
|
||||
}
|
||||
|
||||
void (con_printf)(int priority, const char *fmt, ...)
|
||||
|
@ -50,8 +48,6 @@ void (con_printf)(int priority, const char *fmt, ...)
|
|||
va_list arglist;
|
||||
char buffer[CON_LINE_LENGTH];
|
||||
|
||||
memset(buffer,'\0',CON_LINE_LENGTH);
|
||||
|
||||
if (priority <= ((int)GameArg.DbgVerbose))
|
||||
{
|
||||
char *p1, *p2;
|
||||
|
@ -76,16 +72,16 @@ void (con_printf)(int priority, const char *fmt, ...)
|
|||
}
|
||||
while (*p1);
|
||||
*p2 = 0;
|
||||
con_puts(priority, buffer);
|
||||
con_puts(priority, buffer, p2 - buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void con_puts(int priority, const char *buffer)
|
||||
void con_puts(int priority, const char *buffer, size_t len)
|
||||
{
|
||||
if (priority <= ((int)GameArg.DbgVerbose))
|
||||
{
|
||||
/* add given string to con_buffer */
|
||||
con_add_buffer_line(priority, buffer);
|
||||
con_add_buffer_line(priority, buffer, len);
|
||||
|
||||
/* Print output to stdout */
|
||||
puts(buffer);
|
||||
|
|
Loading…
Reference in a new issue