util_lib/elf_info: harden parsing of printk buffer
Resolves: bz2069200 Upstream: git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git Conflicts: None commit f4c59879b830c7d574a953e6ce970ddaf20910d7 Author: Philipp Rudo <prudo@redhat.com> Date: Wed Mar 23 16:35:36 2022 +0100 util_lib/elf_info: harden parsing of printk buffer 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 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. Fix this by verifying that not wrapped around before when it encounters a message with msg->len == 0. While at it also verify that the index is within the log_buf and thus guard against corruptions with msg->len != 0. The same bug has been reported and fixed in makedumpfile [1]. [1] http://lists.infradead.org/pipermail/kexec/2022-March/024272.html Signed-off-by: Philipp Rudo <prudo@redhat.com> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Philipp Rudo <prudo@redhat.com>
This commit is contained in:
parent
7620d676de
commit
574a202f62
@ -0,0 +1,86 @@
|
|||||||
|
commit f4c59879b830c7d574a953e6ce970ddaf20910d7
|
||||||
|
Author: Philipp Rudo <prudo@redhat.com>
|
||||||
|
Date: Wed Mar 23 16:35:36 2022 +0100
|
||||||
|
|
||||||
|
util_lib/elf_info: harden parsing of printk buffer
|
||||||
|
|
||||||
|
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 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. Fix this by verifying that not wrapped
|
||||||
|
around before when it encounters a message with msg->len == 0.
|
||||||
|
|
||||||
|
While at it also verify that the index is within the log_buf and thus
|
||||||
|
guard against corruptions with msg->len != 0.
|
||||||
|
|
||||||
|
The same bug has been reported and fixed in makedumpfile [1].
|
||||||
|
|
||||||
|
[1] http://lists.infradead.org/pipermail/kexec/2022-March/024272.html
|
||||||
|
|
||||||
|
Signed-off-by: Philipp Rudo <prudo@redhat.com>
|
||||||
|
Signed-off-by: Simon Horman <horms@verge.net.au>
|
||||||
|
|
||||||
|
diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c
|
||||||
|
index d252eff5bd582837595a22aa387f53675c402121..ce71c6055c3a6ce8698d35960a8448be1dc8adc1 100644
|
||||||
|
--- a/util_lib/elf_info.c
|
||||||
|
+++ b/util_lib/elf_info.c
|
||||||
|
@@ -763,8 +763,9 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
|
||||||
|
{
|
||||||
|
#define OUT_BUF_SIZE 4096
|
||||||
|
uint64_t log_buf, log_buf_offset, ts_nsec;
|
||||||
|
- uint32_t log_first_idx, log_next_idx, current_idx, len = 0, i;
|
||||||
|
+ uint32_t log_buf_len, log_first_idx, log_next_idx, current_idx, len = 0, i;
|
||||||
|
char *buf, out_buf[OUT_BUF_SIZE];
|
||||||
|
+ bool has_wrapped_around = false;
|
||||||
|
ssize_t ret;
|
||||||
|
char *msg;
|
||||||
|
uint16_t text_len;
|
||||||
|
@@ -811,6 +812,7 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
|
||||||
|
}
|
||||||
|
|
||||||
|
log_buf = read_file_pointer(fd, vaddr_to_offset(log_buf_vaddr));
|
||||||
|
+ log_buf_len = read_file_s32(fd, vaddr_to_offset(log_buf_len_vaddr));
|
||||||
|
|
||||||
|
log_first_idx = read_file_u32(fd, vaddr_to_offset(log_first_idx_vaddr));
|
||||||
|
log_next_idx = read_file_u32(fd, vaddr_to_offset(log_next_idx_vaddr));
|
||||||
|
@@ -882,11 +884,31 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int))
|
||||||
|
* and read the message at the start of the buffer.
|
||||||
|
*/
|
||||||
|
loglen = struct_val_u16(buf, log_offset_len);
|
||||||
|
- if (!loglen)
|
||||||
|
+ if (!loglen) {
|
||||||
|
+ if (has_wrapped_around) {
|
||||||
|
+ if (len && handler)
|
||||||
|
+ handler(out_buf, len);
|
||||||
|
+ fprintf(stderr, "Cycle when parsing dmesg detected.\n");
|
||||||
|
+ fprintf(stderr, "The prink log_buf is most likely corrupted.\n");
|
||||||
|
+ fprintf(stderr, "log_buf = 0x%lx, idx = 0x%x\n",
|
||||||
|
+ log_buf, current_idx);
|
||||||
|
+ exit(68);
|
||||||
|
+ }
|
||||||
|
current_idx = 0;
|
||||||
|
- else
|
||||||
|
+ has_wrapped_around = true;
|
||||||
|
+ } else {
|
||||||
|
/* Move to next record */
|
||||||
|
current_idx += loglen;
|
||||||
|
+ if(current_idx > log_buf_len - log_sz) {
|
||||||
|
+ if (len && handler)
|
||||||
|
+ handler(out_buf, len);
|
||||||
|
+ fprintf(stderr, "Index outside log_buf detected.\n");
|
||||||
|
+ fprintf(stderr, "The prink log_buf is most likely corrupted.\n");
|
||||||
|
+ fprintf(stderr, "log_buf = 0x%lx, idx = 0x%x\n",
|
||||||
|
+ log_buf, current_idx);
|
||||||
|
+ exit(69);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
if (len && handler)
|
@ -117,6 +117,7 @@ Patch603: ./kexec-tools-2.0.23-01-_PATCH_v2_1_3_add_generic_cycle_detection.patc
|
|||||||
Patch604: ./kexec-tools-2.0.23-02-_PATCH_v2_2_3_use_pointer_arithmetics_for_dump_dmesg.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
|
Patch605: ./kexec-tools-2.0.23-03-_PATCH_v2_3_3_use_cycle_detection_when_parsing_the_prink_log_buf.patch
|
||||||
Patch606: ./kexec-tools-2.0.23-04-_PATCH_print_error_when_reading_with_unsupported_compression.patch
|
Patch606: ./kexec-tools-2.0.23-04-_PATCH_print_error_when_reading_with_unsupported_compression.patch
|
||||||
|
Patch607: ./kexec-tools-2.0.23-05-util_lib_elf_info_harden_parsing_of_printk_buffer.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
kexec-tools provides /sbin/kexec binary that facilitates a new
|
kexec-tools provides /sbin/kexec binary that facilitates a new
|
||||||
@ -138,6 +139,7 @@ tar -z -x -v -f %{SOURCE19}
|
|||||||
%patch604 -p1
|
%patch604 -p1
|
||||||
%patch605 -p1
|
%patch605 -p1
|
||||||
%patch606 -p1
|
%patch606 -p1
|
||||||
|
%patch607 -p1
|
||||||
|
|
||||||
%ifarch ppc
|
%ifarch ppc
|
||||||
%define archdef ARCH=ppc
|
%define archdef ARCH=ppc
|
||||||
|
Loading…
Reference in New Issue
Block a user