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>
|
||||
|
||||
|
@ -36,6 +36,8 @@ Patch7: %{name}-arm64-kdump-deal-with-resource-entries-in-proc-iomem.pat
|
||||
Patch8: %{name}-build-multiboot2-for-i386.patch
|
||||
Patch9: %{name}-video-capability.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: automake
|
||||
BuildRequires: systemd-rpm-macros
|
||||
@ -68,6 +70,8 @@ the loaded kernel after it panics.
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch12 -p1
|
||||
|
||||
%build
|
||||
autoreconf -fvi
|
||||
|
Loading…
Reference in New Issue
Block a user