Accepting request 784674 from Kernel:kdump
- kexec-tools-reset-getopt-before-falling-back-to-legacy.patch: Reset getopt before falling back to legacy syscall (bsc#1166105). - kexec-tools-fix-kexec_file_load-error-handling.patch: Fix the error handling if kexec_file_load() fails (bsc#1166105). OBS-URL: https://build.opensuse.org/request/show/784674 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/kexec-tools?expand=0&rev=134
This commit is contained in:
commit
a40f6346d2
230
kexec-tools-fix-kexec_file_load-error-handling.patch
Normal file
230
kexec-tools-fix-kexec_file_load-error-handling.patch
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
From 0ec1fd23847ba103f967e3377e2a1b13712cff6e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Tesarik <ptesarik@suse.com>
|
||||||
|
Date: Thu, 12 Mar 2020 20:12:12 +0100
|
||||||
|
Upstream: not yet, patch sent 2020-03-12
|
||||||
|
Subject: Fix kexec_file_load(2) error handling
|
||||||
|
References: bsc#1166105
|
||||||
|
|
||||||
|
The handling of kexec_file_load() error conditions needs some
|
||||||
|
improvement.
|
||||||
|
|
||||||
|
First, on failure, the system call itself returns -1 and sets
|
||||||
|
errno. It is wrong to check the return value itself.
|
||||||
|
|
||||||
|
Second, do_kexec_file_load() mixes different types of error
|
||||||
|
codes (-1, return value of a load method, negative kernel error
|
||||||
|
number). Let it always return one of the reason codes defined in
|
||||||
|
kexec/kexec.h.
|
||||||
|
|
||||||
|
Third, the caller of do_kexec_file_load() cannot know what exactly
|
||||||
|
failed inside that function, so it should not check errno directly.
|
||||||
|
All it needs to know is whether it makes sense to fall back to the
|
||||||
|
other syscall. Add an error code for that purpose (EFALLBACK), and
|
||||||
|
let do_kexec_file_load() decide.
|
||||||
|
|
||||||
|
Fourth, do_kexec_file_load() should not print any error message if
|
||||||
|
it returns EFALLBACK, because the fallback syscall may succeed
|
||||||
|
later, and the user is confused whether the command failed, or not.
|
||||||
|
Move the error message towards the end of main().
|
||||||
|
|
||||||
|
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
||||||
|
---
|
||||||
|
kexec/kexec.c | 114 ++++++++++++++++++++++++++++++----------------------------
|
||||||
|
kexec/kexec.h | 1 +
|
||||||
|
2 files changed, 61 insertions(+), 54 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/kexec/kexec.c b/kexec/kexec.c
|
||||||
|
index bc6ab3d..33c1b4b 100644
|
||||||
|
--- a/kexec/kexec.c
|
||||||
|
+++ b/kexec/kexec.c
|
||||||
|
@@ -836,11 +836,21 @@ static int kexec_file_unload(unsigned long kexec_file_flags)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
+ if (!is_kexec_file_load_implemented())
|
||||||
|
+ return EFALLBACK;
|
||||||
|
+
|
||||||
|
ret = kexec_file_load(-1, -1, 0, NULL, kexec_file_flags);
|
||||||
|
if (ret != 0) {
|
||||||
|
- /* The unload failed, print some debugging information */
|
||||||
|
- fprintf(stderr, "kexec_file_load(unload) failed\n: %s\n",
|
||||||
|
- strerror(errno));
|
||||||
|
+ if (errno == ENOSYS) {
|
||||||
|
+ ret = EFALLBACK;
|
||||||
|
+ } else {
|
||||||
|
+ /*
|
||||||
|
+ * The unload failed, print some debugging
|
||||||
|
+ * information */
|
||||||
|
+ fprintf(stderr, "kexec_file_load(unload) failed: %s\n",
|
||||||
|
+ strerror(errno));
|
||||||
|
+ ret = EFAILED;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -1182,15 +1192,13 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||||
|
info.file_mode = 1;
|
||||||
|
info.initrd_fd = -1;
|
||||||
|
|
||||||
|
- if (!is_kexec_file_load_implemented()) {
|
||||||
|
- fprintf(stderr, "syscall kexec_file_load not available.\n");
|
||||||
|
- return -ENOSYS;
|
||||||
|
- }
|
||||||
|
+ if (!is_kexec_file_load_implemented())
|
||||||
|
+ return EFALLBACK;
|
||||||
|
|
||||||
|
if (argc - fileind <= 0) {
|
||||||
|
fprintf(stderr, "No kernel specified\n");
|
||||||
|
usage();
|
||||||
|
- return -1;
|
||||||
|
+ return EFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
kernel = argv[fileind];
|
||||||
|
@@ -1199,7 +1207,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||||
|
if (kernel_fd == -1) {
|
||||||
|
fprintf(stderr, "Failed to open file %s:%s\n", kernel,
|
||||||
|
strerror(errno));
|
||||||
|
- return -1;
|
||||||
|
+ return EFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* slurp in the input kernel */
|
||||||
|
@@ -1225,7 +1233,7 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||||
|
if (i == file_types) {
|
||||||
|
fprintf(stderr, "Cannot determine the file type " "of %s\n",
|
||||||
|
kernel);
|
||||||
|
- return -1;
|
||||||
|
+ return EFAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = file_type[i].load(argc, argv, kernel_buf, kernel_size, &info);
|
||||||
|
@@ -1243,9 +1251,43 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
|
||||||
|
|
||||||
|
ret = kexec_file_load(kernel_fd, info.initrd_fd, info.command_line_len,
|
||||||
|
info.command_line, info.kexec_flags);
|
||||||
|
- if (ret != 0)
|
||||||
|
- fprintf(stderr, "kexec_file_load failed: %s\n",
|
||||||
|
- strerror(errno));
|
||||||
|
+ if (ret != 0) {
|
||||||
|
+ switch (errno) {
|
||||||
|
+ /*
|
||||||
|
+ * Something failed with signature verification.
|
||||||
|
+ * Reject the image.
|
||||||
|
+ */
|
||||||
|
+ case ELIBBAD:
|
||||||
|
+ case EKEYREJECTED:
|
||||||
|
+ case ENOPKG:
|
||||||
|
+ case ENOKEY:
|
||||||
|
+ case EBADMSG:
|
||||||
|
+ case EMSGSIZE:
|
||||||
|
+ /* Reject by default. */
|
||||||
|
+ default:
|
||||||
|
+ ret = EFAILED;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ /* Not implemented. */
|
||||||
|
+ case ENOSYS:
|
||||||
|
+ /*
|
||||||
|
+ * Parsing image or other options failed
|
||||||
|
+ * The image may be invalid or image
|
||||||
|
+ * type may not supported by kernel so
|
||||||
|
+ * retry parsing in kexec-tools.
|
||||||
|
+ */
|
||||||
|
+ case EINVAL:
|
||||||
|
+ case ENOEXEC:
|
||||||
|
+ /*
|
||||||
|
+ * ENOTSUP can be unsupported image
|
||||||
|
+ * type or unsupported PE signature
|
||||||
|
+ * wrapper type, duh.
|
||||||
|
+ */
|
||||||
|
+ case ENOTSUP:
|
||||||
|
+ ret = EFALLBACK;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
|
||||||
|
close(kernel_fd);
|
||||||
|
return ret;
|
||||||
|
@@ -1496,7 +1538,7 @@ int main(int argc, char *argv[])
|
||||||
|
if (do_unload) {
|
||||||
|
if (do_kexec_file_syscall) {
|
||||||
|
result = kexec_file_unload(kexec_file_flags);
|
||||||
|
- if ((result == -ENOSYS) && do_kexec_fallback)
|
||||||
|
+ if (result == EFALLBACK && do_kexec_fallback)
|
||||||
|
do_kexec_file_syscall = 0;
|
||||||
|
}
|
||||||
|
if (!do_kexec_file_syscall)
|
||||||
|
@@ -1506,46 +1548,8 @@ int main(int argc, char *argv[])
|
||||||
|
if (do_kexec_file_syscall) {
|
||||||
|
result = do_kexec_file_load(fileind, argc, argv,
|
||||||
|
kexec_file_flags);
|
||||||
|
- if (do_kexec_fallback) switch (result) {
|
||||||
|
- /*
|
||||||
|
- * Something failed with signature verification.
|
||||||
|
- * Reject the image.
|
||||||
|
- */
|
||||||
|
- case -ELIBBAD:
|
||||||
|
- case -EKEYREJECTED:
|
||||||
|
- case -ENOPKG:
|
||||||
|
- case -ENOKEY:
|
||||||
|
- case -EBADMSG:
|
||||||
|
- case -EMSGSIZE:
|
||||||
|
- /*
|
||||||
|
- * By default reject or do nothing if
|
||||||
|
- * succeded
|
||||||
|
- */
|
||||||
|
- default: break;
|
||||||
|
- case -ENOSYS: /* not implemented */
|
||||||
|
- /*
|
||||||
|
- * Parsing image or other options failed
|
||||||
|
- * The image may be invalid or image
|
||||||
|
- * type may not supported by kernel so
|
||||||
|
- * retry parsing in kexec-tools.
|
||||||
|
- */
|
||||||
|
- case -EINVAL:
|
||||||
|
- case -ENOEXEC:
|
||||||
|
- /*
|
||||||
|
- * ENOTSUP can be unsupported image
|
||||||
|
- * type or unsupported PE signature
|
||||||
|
- * wrapper type, duh
|
||||||
|
- *
|
||||||
|
- * The kernel sometimes wrongly
|
||||||
|
- * returns ENOTSUPP (524) - ignore
|
||||||
|
- * that. It is not supposed to be seen
|
||||||
|
- * by userspace so seeing it is a
|
||||||
|
- * kernel bug
|
||||||
|
- */
|
||||||
|
- case -ENOTSUP:
|
||||||
|
- do_kexec_file_syscall = 0;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ if (result == EFALLBACK && do_kexec_fallback)
|
||||||
|
+ do_kexec_file_syscall = 0;
|
||||||
|
}
|
||||||
|
if (!do_kexec_file_syscall)
|
||||||
|
result = my_load(type, fileind, argc, argv,
|
||||||
|
@@ -1570,6 +1574,8 @@ int main(int argc, char *argv[])
|
||||||
|
if ((result == 0) && do_load_jump_back_helper) {
|
||||||
|
result = my_load_jump_back_helper(kexec_flags, entry);
|
||||||
|
}
|
||||||
|
+ if (result == EFALLBACK)
|
||||||
|
+ fputs("syscall kexec_file_load not available.\n", stderr);
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
fflush(stderr);
|
||||||
|
diff --git a/kexec/kexec.h b/kexec/kexec.h
|
||||||
|
index a97b9ce..28fd129 100644
|
||||||
|
--- a/kexec/kexec.h
|
||||||
|
+++ b/kexec/kexec.h
|
||||||
|
@@ -63,6 +63,7 @@
|
||||||
|
*/
|
||||||
|
#define EFAILED -1 /* default error code */
|
||||||
|
#define ENOCRASHKERNEL -2 /* no memory reserved for crashkernel */
|
||||||
|
+#define EFALLBACK -3 /* fallback to kexec_load(2) may work */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function doesn't actually exist. The idea is that when someone
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
54
kexec-tools-reset-getopt-before-falling-back-to-legacy.patch
Normal file
54
kexec-tools-reset-getopt-before-falling-back-to-legacy.patch
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
From dadafc4664c7b78ea1561ccca33986c9639106ec Mon Sep 17 00:00:00 2001
|
||||||
|
From: Petr Tesarik <ptesarik@suse.com>
|
||||||
|
Date: Fri, 13 Mar 2020 14:54:00 +0100
|
||||||
|
Upstream: not yet, patch sent 2020-03-13
|
||||||
|
Subject: Reset getopt before falling back to legacy syscall
|
||||||
|
References: bsc#1166105
|
||||||
|
|
||||||
|
The modules may need to parse the arguments again after
|
||||||
|
kexec_file_load(2) failed, but getopt is not reset.
|
||||||
|
|
||||||
|
This change fixes the --initrd option on s390x. Without this patch,
|
||||||
|
it will fail to load the initrd on kernels that do not implement
|
||||||
|
kexec_file_load(2).
|
||||||
|
|
||||||
|
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
|
||||||
|
---
|
||||||
|
kexec/kexec.c | 12 ++++++++++--
|
||||||
|
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/kexec/kexec.c b/kexec/kexec.c
|
||||||
|
index 33c1b4b..6601f1f 100644
|
||||||
|
--- a/kexec/kexec.c
|
||||||
|
+++ b/kexec/kexec.c
|
||||||
|
@@ -1538,8 +1538,12 @@ int main(int argc, char *argv[])
|
||||||
|
if (do_unload) {
|
||||||
|
if (do_kexec_file_syscall) {
|
||||||
|
result = kexec_file_unload(kexec_file_flags);
|
||||||
|
- if (result == EFALLBACK && do_kexec_fallback)
|
||||||
|
+ if (result == EFALLBACK && do_kexec_fallback) {
|
||||||
|
+ /* Reset getopt for fallback */
|
||||||
|
+ opterr = 1;
|
||||||
|
+ optind = 1;
|
||||||
|
do_kexec_file_syscall = 0;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (!do_kexec_file_syscall)
|
||||||
|
result = k_unload(kexec_flags);
|
||||||
|
@@ -1548,8 +1552,12 @@ int main(int argc, char *argv[])
|
||||||
|
if (do_kexec_file_syscall) {
|
||||||
|
result = do_kexec_file_load(fileind, argc, argv,
|
||||||
|
kexec_file_flags);
|
||||||
|
- if (result == EFALLBACK && do_kexec_fallback)
|
||||||
|
+ if (result == EFALLBACK && do_kexec_fallback) {
|
||||||
|
+ /* Reset getopt for fallback */
|
||||||
|
+ opterr = 1;
|
||||||
|
+ optind = 1;
|
||||||
|
do_kexec_file_syscall = 0;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (!do_kexec_file_syscall)
|
||||||
|
result = my_load(type, fileind, argc, argv,
|
||||||
|
--
|
||||||
|
2.16.4
|
||||||
|
|
@ -1,3 +1,15 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Mar 13 14:11:55 UTC 2020 - Petr Tesařík <ptesarik@suse.com>
|
||||||
|
|
||||||
|
- kexec-tools-reset-getopt-before-falling-back-to-legacy.patch:
|
||||||
|
Reset getopt before falling back to legacy syscall (bsc#1166105).
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Mar 13 08:37:58 UTC 2020 - Petr Tesařík <ptesarik@suse.com>
|
||||||
|
|
||||||
|
- kexec-tools-fix-kexec_file_load-error-handling.patch: Fix the
|
||||||
|
error handling if kexec_file_load() fails (bsc#1166105).
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Jan 29 07:35:18 UTC 2020 - Petr Tesařík <ptesarik@suse.com>
|
Wed Jan 29 07:35:18 UTC 2020 - Petr Tesařík <ptesarik@suse.com>
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ Patch7: %{name}-arm64-kdump-deal-with-resource-entries-in-proc-iomem.pat
|
|||||||
Patch8: %{name}-build-multiboot2-for-i386.patch
|
Patch8: %{name}-build-multiboot2-for-i386.patch
|
||||||
Patch9: %{name}-video-capability.patch
|
Patch9: %{name}-video-capability.patch
|
||||||
Patch10: %{name}-SYS_getrandom.patch
|
Patch10: %{name}-SYS_getrandom.patch
|
||||||
|
Patch11: %{name}-fix-kexec_file_load-error-handling.patch
|
||||||
|
Patch12: %{name}-reset-getopt-before-falling-back-to-legacy.patch
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
BuildRequires: systemd-rpm-macros
|
BuildRequires: systemd-rpm-macros
|
||||||
@ -68,6 +70,8 @@ the loaded kernel after it panics.
|
|||||||
%patch8 -p1
|
%patch8 -p1
|
||||||
%patch9 -p1
|
%patch9 -p1
|
||||||
%patch10 -p1
|
%patch10 -p1
|
||||||
|
%patch11 -p1
|
||||||
|
%patch12 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
autoreconf -fvi
|
autoreconf -fvi
|
||||||
|
Loading…
Reference in New Issue
Block a user