diff --git a/kexec-tools-2.0.23-01-_PATCH_v2_1_3_add_generic_cycle_detection.patch b/kexec-tools-2.0.23-01-_PATCH_v2_1_3_add_generic_cycle_detection.patch new file mode 100644 index 0000000..4ecbc58 --- /dev/null +++ b/kexec-tools-2.0.23-01-_PATCH_v2_1_3_add_generic_cycle_detection.patch @@ -0,0 +1,191 @@ + commit feae3d1754d2b0788ce1f18b0cd4b40098ff52ff + Author: Philipp Rudo + Date: Mon Mar 14 17:04:29 2022 +0100 + + [PATCH v2 1/3] add generic cycle detection + + In order to work makedumpfile needs to interpret data read from the + dump. This can cause problems as the data from the dump cannot be + trusted (otherwise the kernel wouldn't have panicked in the first + place). This also means that every loop which stop condition depend on + data read from the dump has a chance to loop forever. Thus add a generic + cycle detection mechanism that allows to detect and handle such + situations appropriately. + + For cycle detection use Brent's algorithm [1] as it has constant memory + usage. With this it can also be used in the kdump kernel without the + danger that it runs oom when iterating large data structures. + Furthermore it only depends on some pointer arithmetic. Thus the + performance impact (as long as no cycle was detected) should be + comparatively small. + + [1] https://en.wikipedia.org/wiki/Cycle_detection#Brent's_algorithm + + Suggested-by: Dave Wysochanski + Signed-off-by: Philipp Rudo + Reviewed-and-tested-by: Dave Wysochanski + + diff --git a/makedumpfile-1.7.0/Makefile b/makedumpfile-1.7.0/Makefile + index f118b31e45989d9590ae075fb9b8ed2f27353a92..3441364cb6c7103a20072bd50ec58f1eed01ab69 100644 + --- a/makedumpfile-1.7.0/Makefile + +++ b/makedumpfile-1.7.0/Makefile + @@ -45,7 +45,7 @@ CFLAGS_ARCH += -m32 + endif + + SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h + -SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c + +SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c detect_cycle.c + OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART)) + SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c arch/mips64.c + OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) + diff --git a/makedumpfile-1.7.0/detect_cycle.c b/makedumpfile-1.7.0/detect_cycle.c + new file mode 100644 + index 0000000000000000000000000000000000000000..6b551a75d1c83d64fba2c078be8133efbc791fbe + --- /dev/null + +++ b/makedumpfile-1.7.0/detect_cycle.c + @@ -0,0 +1,99 @@ + +/* + + * detect_cycle.c -- Generic cycle detection using Brent's algorithm + + * + + * Created by: Philipp Rudo + + * + + * Copyright (c) 2022 Red Hat, Inc. All rights reserved. + + * + + * This program is free software; you can redistribute it and/or modify + + * it under the terms of the GNU General Public License as published by + + * the Free Software Foundation; either version 2 of the License, or + + * (at your option) any later version. + + * + + * This program is distributed in the hope that it will be useful, + + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + * GNU General Public License for more details. + + */ + + + +#include + + + +#include "detect_cycle.h" + + + +struct detect_cycle { + + /* First entry of the list */ + + void *head; + + + + /* Variables required by Brent's algorithm */ + + void *fast_p; + + void *slow_p; + + unsigned long length; + + unsigned long power; + + + + /* Function to get the next entry in the list */ + + dc_next_t next; + + + + /* Private data passed to next */ + + void *data; + +}; + + + +struct detect_cycle *dc_init(void *head, void *data, dc_next_t next) + +{ + + struct detect_cycle *new; + + + + new = malloc(sizeof(*new)); + + if (!new) + + return NULL; + + + + new->next = next; + + new->data = data; + + + + new->head = head; + + new->slow_p = head; + + new->fast_p = head; + + new->length = 0; + + new->power = 2; + + + + return new; + +} + + + +int dc_next(struct detect_cycle *dc, void **next) + +{ + + + + if (dc->length == dc->power) { + + dc->length = 0; + + dc->power *= 2; + + dc->slow_p = dc->fast_p; + + } + + + + dc->fast_p = dc->next(dc->fast_p, dc->data); + + dc->length++; + + + + if (dc->slow_p == dc->fast_p) + + return 1; + + + + *next = dc->fast_p; + + return 0; + +} + + + +void dc_find_start(struct detect_cycle *dc, void **first, unsigned long *len) + +{ + + void *slow_p, *fast_p; + + unsigned long tmp; + + + + slow_p = fast_p = dc->head; + + tmp = dc->length; + + + + while (tmp) { + + fast_p = dc->next(fast_p, dc->data); + + tmp--; + + } + + + + while (slow_p != fast_p) { + + slow_p = dc->next(slow_p, dc->data); + + fast_p = dc->next(fast_p, dc->data); + + } + + + + *first = slow_p; + + *len = dc->length; + +} + diff --git a/makedumpfile-1.7.0/detect_cycle.h b/makedumpfile-1.7.0/detect_cycle.h + new file mode 100644 + index 0000000000000000000000000000000000000000..2ca75c78b59a98274fc5a98666b1be74f7bbfc2c + --- /dev/null + +++ b/makedumpfile-1.7.0/detect_cycle.h + @@ -0,0 +1,40 @@ + +/* + + * detect_cycle.h -- Generic cycle detection using Brent's algorithm + + * + + * Created by: Philipp Rudo + + * + + * Copyright (c) 2022 Red Hat, Inc. All rights reserved. + + * + + * This program is free software; you can redistribute it and/or modify + + * it under the terms of the GNU General Public License as published by + + * the Free Software Foundation; either version 2 of the License, or + + * (at your option) any later version. + + * + + * This program is distributed in the hope that it will be useful, + + * but WITHOUT ANY WARRANTY; without even the implied warranty of + + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + * GNU General Public License for more details. + + */ + + + +struct detect_cycle; + + + +typedef void *(*dc_next_t)(void *prev, void *data); + + + +/* + + * Initialize cycle detection. + + * Returns a pointer to allocated struct detect_cycle. The caller is + + * responsible to free the memory after use. + + */ + +struct detect_cycle *dc_init(void *head, void *data, dc_next_t next); + + + +/* + + * Get next entry in the list using dc->next. + + * Returns 1 when cycle was detected, 0 otherwise. + + */ + +int dc_next(struct detect_cycle *dc, void **next); + + + +/* + + * Get the start and length of the cycle. Must only be called after cycle was + + * detected by dc_next. + + */ + +void dc_find_start(struct detect_cycle *dc, void **first, unsigned long *len); diff --git a/kexec-tools.spec b/kexec-tools.spec index 8486a4d..75c52b7 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -113,6 +113,7 @@ Requires: systemd-udev%{?_isa} # Patch601: ./kexec-tools-2.0.22-01-s390_handle_R_390_PLT32DBL_reloc_entries_in_machine_apply_elf_rel_.patch 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 %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -130,6 +131,7 @@ tar -z -x -v -f %{SOURCE19} %patch601 -p1 %patch602 -p1 +%patch603 -p1 %ifarch ppc %define archdef ARCH=ppc