| From 36f2dbfe6ad33a96299580d6a5dd1176a398fd6f Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 11 Jul 2019 16:29:37 +0200 |
| Subject: printk: Do not lose last line in kmsg buffer dump |
| |
| From: Vincent Whitchurch <vincent.whitchurch@axis.com> |
| |
| [ Upstream commit b46eff55ad5bd98e746c0a7022fe7ee071de5fee ] |
| |
| kmsg_dump_get_buffer() is supposed to select all the youngest log |
| messages which fit into the provided buffer. It determines the correct |
| start index by using msg_print_text() with a NULL buffer to calculate |
| the size of each entry. However, when performing the actual writes, |
| msg_print_text() only writes the entry to the buffer if the written len |
| is lesser than the size of the buffer. So if the lengths of the |
| selected youngest log messages happen to precisely fill up the provided |
| buffer, the last log message is not included. |
| |
| We don't want to modify msg_print_text() to fill up the buffer and start |
| returning a length which is equal to the size of the buffer, since |
| callers of its other users, such as kmsg_dump_get_line(), depend upon |
| the current behaviour. |
| |
| Instead, fix kmsg_dump_get_buffer() to compensate for this. |
| |
| For example, with the following two final prints: |
| |
| [ 6.427502] AAAAAAAAAAAAA |
| [ 6.427769] BBBBBBBB12345 |
| |
| A dump of a 64-byte buffer filled by kmsg_dump_get_buffer(), before this |
| patch: |
| |
| 00000000: 3c 30 3e 5b 20 20 20 20 36 2e 35 32 32 31 39 37 <0>[ 6.522197 |
| 00000010: 5d 20 41 41 41 41 41 41 41 41 41 41 41 41 41 0a ] AAAAAAAAAAAAA. |
| 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
| 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
| |
| After this patch: |
| |
| 00000000: 3c 30 3e 5b 20 20 20 20 36 2e 34 35 36 36 37 38 <0>[ 6.456678 |
| 00000010: 5d 20 42 42 42 42 42 42 42 42 31 32 33 34 35 0a ] BBBBBBBB12345. |
| 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
| 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
| |
| Link: http://lkml.kernel.org/r/20190711142937.4083-1-vincent.whitchurch@axis.com |
| Fixes: e2ae715d66bf4bec ("kmsg - kmsg_dump() use iterator to receive log buffer content") |
| To: rostedt@goodmis.org |
| Cc: linux-kernel@vger.kernel.org |
| Cc: <stable@vger.kernel.org> # v3.5+ |
| Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com> |
| Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> |
| Signed-off-by: Petr Mladek <pmladek@suse.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| kernel/printk/printk.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c |
| index df348d4eeb265..6607d77afe55a 100644 |
| --- a/kernel/printk/printk.c |
| +++ b/kernel/printk/printk.c |
| @@ -3131,7 +3131,7 @@ bool kmsg_dump_get_buffer(struct kmsg_dumper *dumper, bool syslog, |
| /* move first record forward until length fits into the buffer */ |
| seq = dumper->cur_seq; |
| idx = dumper->cur_idx; |
| - while (l > size && seq < dumper->next_seq) { |
| + while (l >= size && seq < dumper->next_seq) { |
| struct printk_log *msg = log_from_idx(idx); |
| |
| l -= msg_print_text(msg, true, NULL, 0); |
| -- |
| 2.20.1 |
| |