aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-07-16 21:35:29 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 21:35:29 -0400
commit70498253186586e5dca7bc3ebd3415203b059fbc (patch)
tree7039fd24627aff100b3fc5ddf97e9b27dae9b8b5 /kernel
parent28a78e46f04ac5c4952533f2938a18699f207004 (diff)
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>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/printk.c33
1 files changed, 19 insertions, 14 deletions
diff --git a/kernel/printk.c b/kernel/printk.c
index 177fa49357a5..d87ca5c6a989 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -235,7 +235,8 @@ static u32 log_next_idx;
235static u64 clear_seq; 235static u64 clear_seq;
236static u32 clear_idx; 236static u32 clear_idx;
237 237
238#define LOG_LINE_MAX 1024 238#define PREFIX_MAX 32
239#define LOG_LINE_MAX 1024 - PREFIX_MAX
239 240
240/* record buffer */ 241/* record buffer */
241#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) 242#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,
876 877
877 if (buf) { 878 if (buf) {
878 if (print_prefix(msg, syslog, NULL) + 879 if (print_prefix(msg, syslog, NULL) +
879 text_len + 1>= size - len) 880 text_len + 1 >= size - len)
880 break; 881 break;
881 882
882 if (prefix) 883 if (prefix)
@@ -907,7 +908,7 @@ static int syslog_print(char __user *buf, int size)
907 struct log *msg; 908 struct log *msg;
908 int len = 0; 909 int len = 0;
909 910
910 text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); 911 text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
911 if (!text) 912 if (!text)
912 return -ENOMEM; 913 return -ENOMEM;
913 914
@@ -930,7 +931,8 @@ static int syslog_print(char __user *buf, int size)
930 931
931 skip = syslog_partial; 932 skip = syslog_partial;
932 msg = log_from_idx(syslog_idx); 933 msg = log_from_idx(syslog_idx);
933 n = msg_print_text(msg, syslog_prev, true, text, LOG_LINE_MAX); 934 n = msg_print_text(msg, syslog_prev, true, text,
935 LOG_LINE_MAX + PREFIX_MAX);
934 if (n - syslog_partial <= size) { 936 if (n - syslog_partial <= size) {
935 /* message fits into buffer, move forward */ 937 /* message fits into buffer, move forward */
936 syslog_idx = log_next(syslog_idx); 938 syslog_idx = log_next(syslog_idx);
@@ -969,7 +971,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
969 char *text; 971 char *text;
970 int len = 0; 972 int len = 0;
971 973
972 text = kmalloc(LOG_LINE_MAX, GFP_KERNEL); 974 text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
973 if (!text) 975 if (!text)
974 return -ENOMEM; 976 return -ENOMEM;
975 977
@@ -1022,7 +1024,8 @@ static int syslog_print_all(char __user *buf, int size, bool clear)
1022 struct log *msg = log_from_idx(idx); 1024 struct log *msg = log_from_idx(idx);
1023 int textlen; 1025 int textlen;
1024 1026
1025 textlen = msg_print_text(msg, prev, true, text, LOG_LINE_MAX); 1027 textlen = msg_print_text(msg, prev, true, text,
1028 LOG_LINE_MAX + PREFIX_MAX);
1026 if (textlen < 0) { 1029 if (textlen < 0) {
1027 len = textlen; 1030 len = textlen;
1028 break; 1031 break;
@@ -1367,15 +1370,15 @@ static struct cont {
1367 bool flushed:1; /* buffer sealed and committed */ 1370 bool flushed:1; /* buffer sealed and committed */
1368} cont; 1371} cont;
1369 1372
1370static void cont_flush(void) 1373static void cont_flush(enum log_flags flags)
1371{ 1374{
1372 if (cont.flushed) 1375 if (cont.flushed)
1373 return; 1376 return;
1374 if (cont.len == 0) 1377 if (cont.len == 0)
1375 return; 1378 return;
1376 1379
1377 log_store(cont.facility, cont.level, LOG_NOCONS, cont.ts_nsec, 1380 log_store(cont.facility, cont.level, LOG_NOCONS | flags,
1378 NULL, 0, cont.buf, cont.len); 1381 cont.ts_nsec, NULL, 0, cont.buf, cont.len);
1379 1382
1380 cont.flushed = true; 1383 cont.flushed = true;
1381} 1384}
@@ -1386,7 +1389,8 @@ static bool cont_add(int facility, int level, const char *text, size_t len)
1386 return false; 1389 return false;
1387 1390
1388 if (cont.len + len > sizeof(cont.buf)) { 1391 if (cont.len + len > sizeof(cont.buf)) {
1389 cont_flush(); 1392 /* the line gets too long, split it up in separate records */
1393 cont_flush(LOG_CONT);
1390 return false; 1394 return false;
1391 } 1395 }
1392 1396
@@ -1522,7 +1526,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1522 * or another task also prints continuation lines. 1526 * or another task also prints continuation lines.
1523 */ 1527 */
1524 if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) 1528 if (cont.len && (lflags & LOG_PREFIX || cont.owner != current))
1525 cont_flush(); 1529 cont_flush(0);
1526 1530
1527 /* buffer line if possible, otherwise store it right away */ 1531 /* buffer line if possible, otherwise store it right away */
1528 if (!cont_add(facility, level, text, text_len)) 1532 if (!cont_add(facility, level, text, text_len))
@@ -1540,7 +1544,7 @@ asmlinkage int vprintk_emit(int facility, int level,
1540 if (cont.len && cont.owner == current) { 1544 if (cont.len && cont.owner == current) {
1541 if (!(lflags & LOG_PREFIX)) 1545 if (!(lflags & LOG_PREFIX))
1542 stored = cont_add(facility, level, text, text_len); 1546 stored = cont_add(facility, level, text, text_len);
1543 cont_flush(); 1547 cont_flush(0);
1544 } 1548 }
1545 1549
1546 if (!stored) 1550 if (!stored)
@@ -1633,7 +1637,8 @@ EXPORT_SYMBOL(printk);
1633 1637
1634#else 1638#else
1635 1639
1636#define LOG_LINE_MAX 0 1640#define LOG_LINE_MAX 0
1641#define PREFIX_MAX 0
1637static struct cont { 1642static struct cont {
1638 size_t len; 1643 size_t len;
1639 size_t cons; 1644 size_t cons;
@@ -1938,7 +1943,7 @@ static enum log_flags console_prev;
1938 */ 1943 */
1939void console_unlock(void) 1944void console_unlock(void)
1940{ 1945{
1941 static char text[LOG_LINE_MAX]; 1946 static char text[LOG_LINE_MAX + PREFIX_MAX];
1942 static u64 seen_seq; 1947 static u64 seen_seq;
1943 unsigned long flags; 1948 unsigned long flags;
1944 bool wake_klogd = false; 1949 bool wake_klogd = false;