forked from luck/tmp_suning_uos_patched
kmsg - properly print over-long continuation lines
Reserve PREFIX_MAX bytes in the LOG_LINE_MAX line when buffering a continuation line, to be able to properly prefix the LOG_LINE_MAX line with the syslog prefix and timestamp when printing it. Reported-By: Dave Jones <davej@redhat.com> Signed-off-by: Kay Sievers <kay@vrfy.org> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
28a78e46f0
commit
7049825318
|
@ -235,7 +235,8 @@ static u32 log_next_idx;
|
||||||
static u64 clear_seq;
|
static u64 clear_seq;
|
||||||
static u32 clear_idx;
|
static u32 clear_idx;
|
||||||
|
|
||||||
#define LOG_LINE_MAX 1024
|
#define PREFIX_MAX 32
|
||||||
|
#define LOG_LINE_MAX 1024 - PREFIX_MAX
|
||||||
|
|
||||||
/* record buffer */
|
/* record buffer */
|
||||||
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
|
||||||
|
@ -876,7 +877,7 @@ static size_t msg_print_text(const struct log *msg, enum log_flags prev,
|
||||||
|
|
||||||
if (buf) {
|
if (buf) {
|
||||||
if (print_prefix(msg, syslog, NULL) +
|
if (print_prefix(msg, syslog, NULL) +
|
||||||
text_len + 1>= size - len)
|
text_len + 1 >= size - len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (prefix)
|
if (prefix)
|
||||||
|
@ -907,7 +908,7 @@ static int syslog_print(char __user *buf, int size)
|
||||||
struct log *msg;
|
struct log *msg;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
|
text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
|
||||||
if (!text)
|
if (!text)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -930,7 +931,8 @@ static int syslog_print(char __user *buf, int size)
|
||||||
|
|
||||||
skip = syslog_partial;
|
skip = syslog_partial;
|
||||||
msg = log_from_idx(syslog_idx);
|
msg = log_from_idx(syslog_idx);
|
||||||
n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX);
|
n = msg_print_text(msg, syslog_prev, true, text,
|
||||||
|
LOG_LINE_MAX + PREFIX_MAX);
|
||||||
if (n - syslog_partial <= size) {
|
if (n - syslog_partial <= size) {
|
||||||
/* message fits into buffer, move forward */
|
/* message fits into buffer, move forward */
|
||||||
syslog_idx = log_next(syslog_idx);
|
syslog_idx = log_next(syslog_idx);
|
||||||
|
@ -969,7 +971,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
|
||||||
char *text;
|
char *text;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
text = kmalloc(LOG_LINE_MAX, GFP_KERNEL);
|
text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
|
||||||
if (!text)
|
if (!text)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1022,7 +1024,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
|
||||||
struct log *msg = log_from_idx(idx);
|
struct log *msg = log_from_idx(idx);
|
||||||
int textlen;
|
int textlen;
|
||||||
|
|
||||||
textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX);
|
textlen = msg_print_text(msg, prev, true, text,
|
||||||
|
LOG_LINE_MAX + PREFIX_MAX);
|
||||||
if (textlen < 0) {
|
if (textlen < 0) {
|
||||||
len = textlen;
|
len = textlen;
|
||||||
break;
|
break;
|
||||||
|
@ -1367,15 +1370,15 @@ static struct cont {
|
||||||
bool flushed:1; /* buffer sealed and committed */
|
bool flushed:1; /* buffer sealed and committed */
|
||||||
} cont;
|
} cont;
|
||||||
|
|
||||||
static void cont_flush(void)
|
static void cont_flush(enum log_flags flags)
|
||||||
{
|
{
|
||||||
if (cont.flushed)
|
if (cont.flushed)
|
||||||
return;
|
return;
|
||||||
if (cont.len == 0)
|
if (cont.len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec,
|
log_store(cont.facility, cont.level, LOG_NOCONS | flags,
|
||||||
NULL, 0, cont.buf, cont.len);
|
cont.ts_nsec, NULL, 0, cont.buf, cont.len);
|
||||||
|
|
||||||
cont.flushed = true;
|
cont.flushed = true;
|
||||||
}
|
}
|
||||||
|
@ -1386,7 +1389,8 @@ static bool cont_add(int facility, int level, const char *text, size_t len)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (cont.len + len > sizeof(cont.buf)) {
|
if (cont.len + len > sizeof(cont.buf)) {
|
||||||
cont_flush();
|
/* the line gets too long, split it up in separate records */
|
||||||
|
cont_flush(LOG_CONT);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1522,7 +1526,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
||||||
* or another task also prints continuation lines.
|
* or another task also prints continuation lines.
|
||||||
*/
|
*/
|
||||||
if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
|
if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
|
||||||
cont_flush();
|
cont_flush(0);
|
||||||
|
|
||||||
/* buffer line if possible, otherwise store it right away */
|
/* buffer line if possible, otherwise store it right away */
|
||||||
if (!cont_add(facility, level, text, text_len))
|
if (!cont_add(facility, level, text, text_len))
|
||||||
|
@ -1540,7 +1544,7 @@ asmlinkage int vprintk_emit(int facility, int level,
|
||||||
if (cont.len && cont.owner == current) {
|
if (cont.len && cont.owner == current) {
|
||||||
if (!(lflags & LOG_PREFIX))
|
if (!(lflags & LOG_PREFIX))
|
||||||
stored = cont_add(facility, level, text, text_len);
|
stored = cont_add(facility, level, text, text_len);
|
||||||
cont_flush();
|
cont_flush(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stored)
|
if (!stored)
|
||||||
|
@ -1633,7 +1637,8 @@ EXPORT_SYMBOL(printk);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define LOG_LINE_MAX 0
|
#define LOG_LINE_MAX 0
|
||||||
|
#define PREFIX_MAX 0
|
||||||
static struct cont {
|
static struct cont {
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t cons;
|
size_t cons;
|
||||||
|
@ -1938,7 +1943,7 @@ static enum log_flags console_prev;
|
||||||
*/
|
*/
|
||||||
void console_unlock(void)
|
void console_unlock(void)
|
||||||
{
|
{
|
||||||
static char text[LOG_LINE_MAX];
|
static char text[LOG_LINE_MAX + PREFIX_MAX];
|
||||||
static u64 seen_seq;
|
static u64 seen_seq;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
bool wake_klogd = false;
|
bool wake_klogd = false;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user