diff --git a/kexec-tools-2.0.23-03-_PATCH_v2_3_3_use_cycle_detection_when_parsing_the_prink_log_buf.patch b/kexec-tools-2.0.23-03-_PATCH_v2_3_3_use_cycle_detection_when_parsing_the_prink_log_buf.patch new file mode 100644 index 0000000..fc70613 --- /dev/null +++ b/kexec-tools-2.0.23-03-_PATCH_v2_3_3_use_cycle_detection_when_parsing_the_prink_log_buf.patch @@ -0,0 +1,118 @@ + commit 68d120b30af5e930afafed81e79712af3c1a278c + Author: Philipp Rudo + Date: Mon Mar 14 17:04:31 2022 +0100 + + [PATCH v2 3/3] use cycle detection when parsing the prink log_buf + + The old printk mechanism (> v3.5.0 and < v5.10.0) had a fixed size + buffer (log_buf) that contains all messages. The location for the next + message is stored in log_next_idx. In case the log_buf runs full + log_next_idx wraps around and starts overwriting old messages at the + beginning of the buffer. The wraparound is denoted by a message with + msg->len == 0. + + Following the behavior described above blindly in makedumpfile is + dangerous as e.g. a memory corruption could overwrite (parts of) the + log_buf. If the corruption adds a message with msg->len == 0 this leads + to an endless loop when dumping the dmesg with makedumpfile appending + the messages up to the corruption over and over again to the output file + until file system is full. Fix this by using cycle detection and aboard + once one is detected. + + While at it also verify that the index is within the log_buf and thus + guard against corruptions with msg->len != 0. + + Reported-by: Audra Mitchell + Suggested-by: Dave Wysochanski + Signed-off-by: Philipp Rudo + Reviewed-and-tested-by: Dave Wysochanski + + diff --git a/makedumpfile-1.7.0/makedumpfile.c b/makedumpfile-1.7.0/makedumpfile.c + index e72dba219eec198ec865045562f39a14b5a092eb..2b94446b8f2ad513da060e15821544ae32e1a2c6 100644 + --- a/makedumpfile-1.7.0/makedumpfile.c + +++ b/makedumpfile-1.7.0/makedumpfile.c + @@ -15,6 +15,7 @@ + */ + #include "makedumpfile.h" + #include "print_info.h" + +#include "detect_cycle.h" + #include "dwarf_info.h" + #include "elf_info.h" + #include "erase_info.h" + @@ -5526,10 +5527,11 @@ dump_dmesg() + unsigned long index, log_buf, log_end; + unsigned int log_first_idx, log_next_idx; + unsigned long long first_idx_sym; + + struct detect_cycle *dc = NULL; + unsigned long log_end_2_6_24; + unsigned log_end_2_6_25; + char *log_buffer = NULL, *log_ptr = NULL; + - char *ptr; + + char *ptr, *next_ptr; + + /* + * log_end has been changed to "unsigned" since linux-2.6.25. + @@ -5677,12 +5679,55 @@ dump_dmesg() + goto out; + } + ptr = log_buffer + log_first_idx; + + dc = dc_init(ptr, log_buffer, log_next); + while (ptr != log_buffer + log_next_idx) { + log_ptr = log_from_ptr(ptr, log_buffer); + if (!dump_log_entry(log_ptr, info->fd_dumpfile, + info->name_dumpfile)) + goto out; + ptr = log_next(ptr, log_buffer); + + if (dc_next(dc, (void **) &next_ptr)) { + + unsigned long len; + + int in_cycle; + + char *first; + + + + /* Clear everything we have already written... */ + + ftruncate(info->fd_dumpfile, 0); + + lseek(info->fd_dumpfile, 0, SEEK_SET); + + + + /* ...and only write up to the corruption. */ + + dc_find_start(dc, (void **) &first, &len); + + ptr = log_buffer + log_first_idx; + + in_cycle = FALSE; + + while (len) { + + log_ptr = log_from_ptr(ptr, log_buffer); + + if (!dump_log_entry(log_ptr, + + info->fd_dumpfile, + + info->name_dumpfile)) + + goto out; + + ptr = log_next(ptr, log_buffer); + + + + if (log_ptr == first) + + in_cycle = TRUE; + + + + if (in_cycle) + + len--; + + } + + ERRMSG("Cycle when parsing dmesg detected.\n"); + + ERRMSG("The printk log_buf is most likely corrupted.\n"); + + ERRMSG("log_buf = 0x%lx, idx = 0x%lx\n", log_buf, ptr - log_buffer); + + close_files_for_creating_dumpfile(); + + goto out; + + } + + if (next_ptr < log_buffer || + + next_ptr > log_buffer + log_buf_len - SIZE(printk_log)) { + + ERRMSG("Index outside log_buf detected.\n"); + + ERRMSG("The printk log_buf is most likely corrupted.\n"); + + ERRMSG("log_buf = 0x%lx, idx = 0x%lx\n", log_buf, ptr - log_buffer); + + close_files_for_creating_dumpfile(); + + goto out; + + } + + ptr = next_ptr; + } + if (!close_files_for_creating_dumpfile()) + goto out; + @@ -5692,6 +5737,7 @@ dump_dmesg() + out: + if (log_buffer) + free(log_buffer); + + free(dc); + + return ret; + } diff --git a/kexec-tools.spec b/kexec-tools.spec index 4ffc73d..de18616 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -115,6 +115,7 @@ Patch601: ./kexec-tools-2.0.22-01-s390_handle_R_390_PLT32DBL_reloc_entries_in_ma Patch602: ./kexec-tools-2.0.23-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr_.patch Patch603: ./kexec-tools-2.0.23-01-_PATCH_v2_1_3_add_generic_cycle_detection.patch Patch604: ./kexec-tools-2.0.23-02-_PATCH_v2_2_3_use_pointer_arithmetics_for_dump_dmesg.patch +Patch605: ./kexec-tools-2.0.23-03-_PATCH_v2_3_3_use_cycle_detection_when_parsing_the_prink_log_buf.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -134,6 +135,7 @@ tar -z -x -v -f %{SOURCE19} %patch602 -p1 %patch603 -p1 %patch604 -p1 +%patch605 -p1 %ifarch ppc %define archdef ARCH=ppc