Fix supermin crash with truncated vmlinuz file (RHBZ#1477758).

- Include all upstream patches since 5.1.18.
This commit is contained in:
Richard W.M. Jones 2017-08-03 17:30:13 +01:00
parent 2e7b101d9a
commit 36f5331e31
11 changed files with 799 additions and 1 deletions

View File

@ -0,0 +1,38 @@
From 8518865218063cb2db1e7a7ab7dfc3fc0a80561c Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 29 Jul 2017 10:39:43 +0100
Subject: [PATCH 01/10] prepare: Add some debugging of config files / creating
base.tar.gz.
---
src/mode_prepare.ml | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/mode_prepare.ml b/src/mode_prepare.ml
index e8cf058..7c8221e 100644
--- a/src/mode_prepare.ml
+++ b/src/mode_prepare.ml
@@ -146,6 +146,10 @@ let prepare debug (copy_kernel, format, host_cpu,
with Sys_error _ -> false
) config_files in
+ if debug >= 1 then
+ printf "supermin: there are %d config files\n"
+ (List.length config_files);
+
(* Put the list of config files into a file, for tar to read. *)
let files_from = tmpdir // "files-from.txt" in
let chan = open_out files_from in
@@ -158,6 +162,7 @@ let prepare debug (copy_kernel, format, host_cpu,
let base = outputdir // "base.tar.gz" in
if debug >= 1 then printf "supermin: writing %s\n%!" base;
let cmd =
- sprintf "tar -C %s -zcf %s -T %s"
- (quote dir) (quote base) (quote files_from) in
+ sprintf "tar%s -C %s -zcf %s -T %s"
+ (if debug >=1 then " -v" else "")
+ (quote dir) (quote base) (quote files_from) in
run_command cmd;
--
2.13.1

View File

@ -0,0 +1,178 @@
From 137dc8b5a0b7427cd80d774604f2f048259b7926 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 12:19:35 +0100
Subject: [PATCH 02/10] kernel: Refactor code for locating the kernel.
Refactor the code for locating the kernel into separate functions,
making clear the purpose of each part of the code.
This is pure refactoring and doesn't change the meaning of the code.
---
src/format_ext2_kernel.ml | 126 ++++++++++++++++++++++++++--------------------
1 file changed, 72 insertions(+), 54 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index 5d1ae66..a12fbd2 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -40,49 +40,21 @@ let patt_of_cpu host_cpu =
List.map (fun model -> sprintf "vmlinu?-*-%s" model) models
let rec build_kernel debug host_cpu copy_kernel kernel =
- (* Locate the kernel. *)
+ (* Locate the kernel.
+ * SUPERMIN_* environment variables override everything. If those
+ * are not present then we look in /lib/modules and /boot.
+ *)
let kernel_file, kernel_name, kernel_version, modpath =
- try
- let kernel_env = getenv "SUPERMIN_KERNEL" in
- if debug >= 1 then
- printf "supermin: kernel: SUPERMIN_KERNEL environment variable %s\n%!"
- kernel_env;
- let kernel_version =
- try
- let v = getenv "SUPERMIN_KERNEL_VERSION" in
- if debug >= 1 then
- printf "supermin: kernel: SUPERMIN_KERNEL_VERSION environment variable %s\n%!" v;
- v
- with Not_found -> get_kernel_version_from_file kernel_env in
- if debug >= 1 then
- printf "supermin: kernel: SUPERMIN_KERNEL version %s\n%!"
- kernel_version;
- let kernel_name = Filename.basename kernel_env in
- let modpath = find_modpath debug kernel_version in
- kernel_env, kernel_name, kernel_version, modpath
- with Not_found ->
- let kernels =
- let files = glob "/lib/modules/*/vmlinuz" [GLOB_NOSORT; GLOB_NOESCAPE] in
- let files = Array.to_list files in
- let kernels =
- List.map (
- fun f ->
- let modpath = Filename.dirname f in
- f, Filename.basename f, Filename.basename modpath, modpath
- ) files in
- List.sort (
- fun (_, _, a, _) (_, _, b, _) -> compare_version b a
- ) kernels in
-
- if kernels <> [] then (
- let kernel = List.hd kernels in
- if debug >= 1 then (
- let kernel_file, _, _, _ = kernel in
- printf "supermin: kernel: picked vmlinuz %s\n%!" kernel_file;
- );
- kernel
- ) else
- find_kernel debug host_cpu kernel in
+ match find_kernel_from_env_vars debug with
+ | Some k -> k
+ | None ->
+ match find_kernel_from_lib_modules debug with
+ | Some k -> k
+ | None ->
+ match find_kernel_from_boot debug host_cpu with
+ | Some k -> k
+ | None ->
+ error_no_kernels host_cpu in
if debug >= 1 then (
printf "supermin: kernel: kernel_version %s\n" kernel_version;
@@ -93,7 +65,52 @@ let rec build_kernel debug host_cpu copy_kernel kernel =
(kernel_version, modpath)
-and find_kernel debug host_cpu kernel =
+and find_kernel_from_env_vars debug =
+ try
+ let kernel_env = getenv "SUPERMIN_KERNEL" in
+ if debug >= 1 then
+ printf "supermin: kernel: SUPERMIN_KERNEL environment variable %s\n%!"
+ kernel_env;
+ let kernel_version =
+ try
+ let v = getenv "SUPERMIN_KERNEL_VERSION" in
+ if debug >= 1 then
+ printf "supermin: kernel: SUPERMIN_KERNEL_VERSION environment variable %s\n%!" v;
+ v
+ with Not_found -> get_kernel_version_from_file kernel_env in
+ if debug >= 1 then
+ printf "supermin: kernel: SUPERMIN_KERNEL version %s\n%!"
+ kernel_version;
+ let kernel_name = Filename.basename kernel_env in
+ let modpath = find_modpath debug kernel_version in
+ Some (kernel_env, kernel_name, kernel_version, modpath)
+ with Not_found -> None
+
+and find_kernel_from_lib_modules debug =
+ let kernels =
+ let files = glob "/lib/modules/*/vmlinuz" [GLOB_NOSORT; GLOB_NOESCAPE] in
+ let files = Array.to_list files in
+ let kernels =
+ List.map (
+ fun f ->
+ let modpath = Filename.dirname f in
+ f, Filename.basename f, Filename.basename modpath, modpath
+ ) files in
+ List.sort (
+ fun (_, _, a, _) (_, _, b, _) -> compare_version b a
+ ) kernels in
+
+ if kernels <> [] then (
+ let kernel = List.hd kernels in
+ if debug >= 1 then (
+ let kernel_file, _, _, _ = kernel in
+ printf "supermin: kernel: picked vmlinuz %s\n%!" kernel_file;
+ );
+ Some kernel
+ ) else
+ None
+
+and find_kernel_from_boot debug host_cpu =
let is_arm =
String.length host_cpu >= 3 &&
host_cpu.[0] = 'a' && host_cpu.[1] = 'r' && host_cpu.[2] = 'm' in
@@ -111,19 +128,20 @@ and find_kernel debug host_cpu kernel =
(* In original: ls -1dvr /boot/vmlinuz-* 2>/dev/null | grep -v xen *)
kernel_filter ["vmlinu?-*"] is_arm all_files in
- if files = [] then no_kernels host_cpu;
-
- let files = List.sort (fun a b -> compare_version b a) files in
- let kernel_name = List.hd files in
- let kernel_version = get_kernel_version kernel_name in
+ if files = [] then None
+ else (
+ let files = List.sort (fun a b -> compare_version b a) files in
+ let kernel_name = List.hd files in
+ let kernel_version = get_kernel_version kernel_name in
- if debug >= 1 then
- printf "supermin: kernel: picked kernel %s\n%!" kernel_name;
+ if debug >= 1 then
+ printf "supermin: kernel: picked kernel %s\n%!" kernel_name;
- (* Get the kernel modules. *)
- let modpath = find_modpath debug kernel_version in
+ (* Get the kernel modules. *)
+ let modpath = find_modpath debug kernel_version in
- ("/boot" // kernel_name), kernel_name, kernel_version, modpath
+ Some (("/boot" // kernel_name), kernel_name, kernel_version, modpath)
+ )
and kernel_filter patterns is_arm all_files =
let files =
@@ -143,7 +161,7 @@ and kernel_filter patterns is_arm all_files =
) in
List.filter (fun filename -> has_modpath filename) files
-and no_kernels host_cpu =
+and error_no_kernels host_cpu =
error "\
failed to find a suitable kernel (host_cpu=%s).
--
2.13.1

View File

@ -0,0 +1,110 @@
From 44d0d1d9cd57feb4f6bd31c0530e90f6d7ede2f5 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 12:27:09 +0100
Subject: [PATCH 03/10] kernel: Tweak debug messages.
Rework the debug messages so it's clearer in debugging messages how
the kernel was located. Also removes duplicated debugging
information.
This is cleanup, there is no functional change.
---
src/format_ext2_kernel.ml | 35 ++++++++++++++---------------------
1 file changed, 14 insertions(+), 21 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index a12fbd2..90fa56f 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -45,20 +45,27 @@ let rec build_kernel debug host_cpu copy_kernel kernel =
* are not present then we look in /lib/modules and /boot.
*)
let kernel_file, kernel_name, kernel_version, modpath =
+ if debug >= 1 then
+ printf "supermin: kernel: looking for kernel using environment variables ...\n%!";
match find_kernel_from_env_vars debug with
| Some k -> k
| None ->
+ if debug >= 1 then
+ printf "supermin: kernel: looking for kernels in /lib/modules/*/vmlinuz ...\n%!";
match find_kernel_from_lib_modules debug with
| Some k -> k
| None ->
+ if debug >= 1 then
+ printf "supermin: kernel: looking for kernels in /boot ...\n%!";
match find_kernel_from_boot debug host_cpu with
| Some k -> k
| None ->
error_no_kernels host_cpu in
if debug >= 1 then (
+ printf "supermin: kernel: picked vmlinuz %s\n%!" kernel_file;
printf "supermin: kernel: kernel_version %s\n" kernel_version;
- printf "supermin: kernel: modules %s\n%!" modpath;
+ printf "supermin: kernel: modpath %s\n%!" modpath;
);
copy_or_symlink_file copy_kernel kernel_file kernel;
@@ -69,18 +76,14 @@ and find_kernel_from_env_vars debug =
try
let kernel_env = getenv "SUPERMIN_KERNEL" in
if debug >= 1 then
- printf "supermin: kernel: SUPERMIN_KERNEL environment variable %s\n%!"
- kernel_env;
+ printf "supermin: kernel: SUPERMIN_KERNEL=%s\n%!" kernel_env;
let kernel_version =
try
let v = getenv "SUPERMIN_KERNEL_VERSION" in
if debug >= 1 then
- printf "supermin: kernel: SUPERMIN_KERNEL_VERSION environment variable %s\n%!" v;
+ printf "supermin: kernel: SUPERMIN_KERNEL_VERSION=%s\n%!" v;
v
with Not_found -> get_kernel_version_from_file kernel_env in
- if debug >= 1 then
- printf "supermin: kernel: SUPERMIN_KERNEL version %s\n%!"
- kernel_version;
let kernel_name = Filename.basename kernel_env in
let modpath = find_modpath debug kernel_version in
Some (kernel_env, kernel_name, kernel_version, modpath)
@@ -100,15 +103,9 @@ and find_kernel_from_lib_modules debug =
fun (_, _, a, _) (_, _, b, _) -> compare_version b a
) kernels in
- if kernels <> [] then (
- let kernel = List.hd kernels in
- if debug >= 1 then (
- let kernel_file, _, _, _ = kernel in
- printf "supermin: kernel: picked vmlinuz %s\n%!" kernel_file;
- );
- Some kernel
- ) else
- None
+ match kernels with
+ | kernel :: _ -> Some kernel
+ | [] -> None
and find_kernel_from_boot debug host_cpu =
let is_arm =
@@ -134,9 +131,6 @@ and find_kernel_from_boot debug host_cpu =
let kernel_name = List.hd files in
let kernel_version = get_kernel_version kernel_name in
- if debug >= 1 then
- printf "supermin: kernel: picked kernel %s\n%!" kernel_name;
-
(* Get the kernel modules. *)
let modpath = find_modpath debug kernel_version in
@@ -176,8 +170,7 @@ and find_modpath debug kernel_version =
try
let modpath = getenv "SUPERMIN_MODULES" in
if debug >= 1 then
- printf "supermin: kernel: SUPERMIN_MODULES environment variable = %s\n%!"
- modpath;
+ printf "supermin: kernel: SUPERMIN_MODULES=%s\n%!" modpath;
modpath
with Not_found ->
let modpath = "/lib/modules/" ^ kernel_version in
--
2.13.1

View File

@ -0,0 +1,90 @@
From cb080ba09e0e2b78cf33d88acd510641118c07ca Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 12:34:47 +0100
Subject: [PATCH 04/10] kernel: Rearrange the order of functions.
Rearrange the order of functions more logically.
Just code motion, no functional change.
---
src/format_ext2_kernel.ml | 50 +++++++++++++++++++++++------------------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index 90fa56f..e2f8e4b 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -24,21 +24,6 @@ open Ext2fs
open Fnmatch
open Glob
-let patt_of_cpu host_cpu =
- let models =
- match host_cpu with
- | "mips" | "mips64" -> [host_cpu; "*-malta"]
- | "ppc" | "powerpc" | "powerpc64" -> ["ppc"; "powerpc"; "powerpc64"]
- | "sparc" | "sparc64" -> ["sparc"; "sparc64"]
- | "amd64" | "x86_64" -> ["amd64"; "x86_64"]
- | "parisc" | "parisc64" -> ["hppa"; "hppa64"]
- | "ppc64el" -> ["powerpc64le"]
- | _ when host_cpu.[0] = 'i' && host_cpu.[2] = '8' && host_cpu.[3] = '6' -> ["?86"]
- | _ when String.length host_cpu >= 5 && String.sub host_cpu 0 5 = "armv7" -> ["armmp"]
- | _ -> [host_cpu]
- in
- List.map (fun model -> sprintf "vmlinu?-*-%s" model) models
-
let rec build_kernel debug host_cpu copy_kernel kernel =
(* Locate the kernel.
* SUPERMIN_* environment variables override everything. If those
@@ -72,6 +57,17 @@ let rec build_kernel debug host_cpu copy_kernel kernel =
(kernel_version, modpath)
+and error_no_kernels host_cpu =
+ error "\
+failed to find a suitable kernel (host_cpu=%s).
+
+I looked for kernels in /boot and modules in /lib/modules.
+
+If this is a Xen guest, and you only have Xen domU kernels
+installed, try installing a fullvirt kernel (only for
+supermin use, you shouldn't boot the Xen guest with it)."
+ host_cpu
+
and find_kernel_from_env_vars debug =
try
let kernel_env = getenv "SUPERMIN_KERNEL" in
@@ -155,16 +151,20 @@ and kernel_filter patterns is_arm all_files =
) in
List.filter (fun filename -> has_modpath filename) files
-and error_no_kernels host_cpu =
- error "\
-failed to find a suitable kernel (host_cpu=%s).
-
-I looked for kernels in /boot and modules in /lib/modules.
-
-If this is a Xen guest, and you only have Xen domU kernels
-installed, try installing a fullvirt kernel (only for
-supermin use, you shouldn't boot the Xen guest with it)."
- host_cpu
+and patt_of_cpu host_cpu =
+ let models =
+ match host_cpu with
+ | "mips" | "mips64" -> [host_cpu; "*-malta"]
+ | "ppc" | "powerpc" | "powerpc64" -> ["ppc"; "powerpc"; "powerpc64"]
+ | "sparc" | "sparc64" -> ["sparc"; "sparc64"]
+ | "amd64" | "x86_64" -> ["amd64"; "x86_64"]
+ | "parisc" | "parisc64" -> ["hppa"; "hppa64"]
+ | "ppc64el" -> ["powerpc64le"]
+ | _ when host_cpu.[0] = 'i' && host_cpu.[2] = '8' && host_cpu.[3] = '6' -> ["?86"]
+ | _ when String.length host_cpu >= 5 && String.sub host_cpu 0 5 = "armv7" -> ["armmp"]
+ | _ -> [host_cpu]
+ in
+ List.map (fun model -> sprintf "vmlinu?-*-%s" model) models
and find_modpath debug kernel_version =
try
--
2.13.1

View File

@ -0,0 +1,60 @@
From fb7164c23b4e5161d22eaf266abd3e0bf55e7b1e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 12:47:49 +0100
Subject: [PATCH 05/10] kernel: Filter /boot kernels using has_modpath later.
/boot kernels are filtered using the has_modpath function.
This change just moves the test later, which has no effect
here but makes subsequent cleanups simpler.
---
src/format_ext2_kernel.ml | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index e2f8e4b..c44ae23 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -121,17 +121,22 @@ and find_kernel_from_boot debug host_cpu =
(* In original: ls -1dvr /boot/vmlinuz-* 2>/dev/null | grep -v xen *)
kernel_filter ["vmlinu?-*"] is_arm all_files in
- if files = [] then None
- else (
- let files = List.sort (fun a b -> compare_version b a) files in
- let kernel_name = List.hd files in
- let kernel_version = get_kernel_version kernel_name in
+ let files = List.sort (fun a b -> compare_version b a) files in
+ let kernels =
+ List.map (
+ fun kernel_name ->
+ let kernel_version = get_kernel_version kernel_name in
+ let kernel_file = "/boot" // kernel_name in
+ let modpath = find_modpath debug kernel_version in
+ (kernel_file, kernel_name, kernel_version, modpath)
+ ) files in
- (* Get the kernel modules. *)
- let modpath = find_modpath debug kernel_version in
+ let kernels =
+ List.filter (fun (_, kernel_name, _, _) -> has_modpath kernel_name) kernels in
- Some (("/boot" // kernel_name), kernel_name, kernel_version, modpath)
- )
+ match kernels with
+ | kernel :: _ -> Some kernel
+ | [] -> None
and kernel_filter patterns is_arm all_files =
let files =
@@ -149,7 +154,7 @@ and kernel_filter patterns is_arm all_files =
find filename "tegra" = -1
) files
) in
- List.filter (fun filename -> has_modpath filename) files
+ files
and patt_of_cpu host_cpu =
let models =
--
2.13.1

View File

@ -0,0 +1,42 @@
From 407bf152a24399c78eae114589100ba0923ef70a Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 12:53:54 +0100
Subject: [PATCH 06/10] kernel: Change has_modpath function so it checks for
modpath // modules.dep.
---
src/format_ext2_kernel.ml | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index c44ae23..0bb67fe 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -132,7 +132,7 @@ and find_kernel_from_boot debug host_cpu =
) files in
let kernels =
- List.filter (fun (_, kernel_name, _, _) -> has_modpath kernel_name) kernels in
+ List.filter (fun (_, _, _, modpath) -> has_modpath modpath) kernels in
match kernels with
| kernel :: _ -> Some kernel
@@ -183,12 +183,9 @@ and find_modpath debug kernel_version =
printf "supermin: kernel: picked modules path %s\n%!" modpath;
modpath
-and has_modpath kernel_name =
- try
- let kv = get_kernel_version kernel_name in
- modules_dep_exists kv
- with
- | Not_found -> false
+and has_modpath modpath =
+ try (stat (modpath // "modules.dep")).st_kind = S_REG
+ with Unix_error _ -> false
and get_kernel_version kernel_name =
if (string_prefix "vmlinuz-" kernel_name) ||
--
2.13.1

View File

@ -0,0 +1,150 @@
From c859939113b939b5ad4237e8f4835cd33290357f Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 13:06:41 +0100
Subject: [PATCH 07/10] kernel: Replace how kernel version information is
found.
The old code was fairly bogus. In the new code there is one "public"
function:
val get_kernel_version : bool -> string -> string option
which takes a full vmlinuz path and returns the kernel version from it
if possible (or None if not). This function first looks at the file
content to see if the version can be extracted, and if that fails
looks at the filename.
As a side effect of making this change, we also filter out kernels
from /boot where we cannot read the kernel version.
---
src/format_ext2_kernel.ml | 78 +++++++++++++++++++++++++++++++----------------
1 file changed, 51 insertions(+), 27 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index 0bb67fe..55c5af9 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -79,7 +79,10 @@ and find_kernel_from_env_vars debug =
if debug >= 1 then
printf "supermin: kernel: SUPERMIN_KERNEL_VERSION=%s\n%!" v;
v
- with Not_found -> get_kernel_version_from_file kernel_env in
+ with Not_found ->
+ match get_kernel_version debug kernel_env with
+ | Some v -> v
+ | None -> raise Not_found in
let kernel_name = Filename.basename kernel_env in
let modpath = find_modpath debug kernel_version in
Some (kernel_env, kernel_name, kernel_version, modpath)
@@ -123,17 +126,17 @@ and find_kernel_from_boot debug host_cpu =
let files = List.sort (fun a b -> compare_version b a) files in
let kernels =
- List.map (
+ filter_map (
fun kernel_name ->
- let kernel_version = get_kernel_version kernel_name in
let kernel_file = "/boot" // kernel_name in
- let modpath = find_modpath debug kernel_version in
- (kernel_file, kernel_name, kernel_version, modpath)
+ match get_kernel_version debug kernel_file with
+ | None -> None
+ | Some kernel_version ->
+ let modpath = find_modpath debug kernel_version in
+ if not (has_modpath modpath) then None
+ else Some (kernel_file, kernel_name, kernel_version, modpath)
) files in
- let kernels =
- List.filter (fun (_, _, _, modpath) -> has_modpath modpath) kernels in
-
match kernels with
| kernel :: _ -> Some kernel
| [] -> None
@@ -187,24 +190,43 @@ and has_modpath modpath =
try (stat (modpath // "modules.dep")).st_kind = S_REG
with Unix_error _ -> false
-and get_kernel_version kernel_name =
- if (string_prefix "vmlinuz-" kernel_name) ||
- (string_prefix "vmlinux-" kernel_name) then (
- let kv = String.sub kernel_name 8 (String.length kernel_name - 8) in
- if modules_dep_exists kv then kv
- else get_kernel_version_from_name kernel_name
- ) else get_kernel_version_from_name kernel_name
-
-and modules_dep_exists kv =
- try (lstat ("/lib/modules/" ^ kv ^ "/modules.dep")).st_kind = S_REG
- with Unix_error _ -> false
-
-and get_kernel_version_from_name kernel_name =
- get_kernel_version_from_file ("/boot" // kernel_name)
+(* Extract the kernel version from a Linux kernel file.
+ *
+ * This first sees if we can get the information from the file
+ * content (see below) and if that fails tries to parse the
+ * filename.
+ *)
+and get_kernel_version debug kernel_file =
+ if debug >= 1 then
+ printf "supermin: kernel: kernel version of %s%!" kernel_file;
+ match get_kernel_version_from_file_content kernel_file with
+ | Some version ->
+ if debug >= 1 then printf " = %s (from content)\n%!" version;
+ Some version
+ | None ->
+ (* Try to work it out from the filename instead. *)
+ let basename = Filename.basename kernel_file in
+ if string_prefix "vmlinuz-" basename || string_prefix "vmlinux-" basename
+ then (
+ let version = String.sub basename 8 (String.length basename - 8) in
+ (* Does the version look reasonable? *)
+ let modpath = "/lib/modules" // version in
+ if has_modpath modpath then (
+ if debug >= 1 then printf " = %s (from filename)\n%!" version;
+ Some version
+ ) else (
+ if debug >= 1 then printf " = error, no modpath\n%!";
+ None
+ )
+ )
+ else (
+ if debug >= 1 then printf " = error, cannot parse filename\n%!";
+ None
+ )
(* Extract the kernel version from a Linux kernel file.
*
- * Returns a string containing the version or [Not_found] if the
+ * Returns a string containing the version or [None] if the
* file can't be read, is not a Linux kernel, or the version can't
* be found.
*
@@ -217,7 +239,7 @@ and get_kernel_version_from_name kernel_name =
*
* Bugs: probably limited to x86 kernels.
*)
-and get_kernel_version_from_file file =
+and get_kernel_version_from_file_content file =
try
let chan = open_in file in
let buf = read_string chan 514 4 in
@@ -247,10 +269,12 @@ and get_kernel_version_from_file file =
)
else raise Not_found
in
- loop 0
+ let version = loop 0 in
+ Some version
with
- | Sys_error _ -> raise Not_found
- | Invalid_argument _ -> raise Not_found
+ | Not_found
+ | Sys_error _
+ | Invalid_argument _ -> None
(* Read an unsigned little endian short at a specified offset in a file. *)
and read_leshort chan offset =
--
2.13.1

View File

@ -0,0 +1,35 @@
From 1cb54ab90e813e148e218cb274c97b08b610e3b9 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 13:09:06 +0100
Subject: [PATCH 08/10] kernel: Don't allow End_of_file exception to escape if
kernel is bogus (RHBZ#1477758).
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If the kernel file is truncated (zero length or too short) then
functions such as really_input raise End_of_file. Unfortunately
this exception could escape and kill the program. What we want to do
instead is to ignore such kernels. The combination of this commit and
the last commit ignores such kernels if they are found in /boot.
Reported by Charlie Martinez.
---
src/format_ext2_kernel.ml | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index 55c5af9..e329adb 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -273,6 +273,7 @@ and get_kernel_version_from_file_content file =
Some version
with
| Not_found
+ | End_of_file
| Sys_error _
| Invalid_argument _ -> None
--
2.13.1

View File

@ -0,0 +1,33 @@
From bc33663a38bc401a5b5883e253cc93b0d3e67ef2 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 13:48:37 +0100
Subject: [PATCH 09/10] kernel: Simple renaming to make find_kernel_from_*
functions consistent.
No functional change, just renaming variables.
---
src/format_ext2_kernel.ml | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index e329adb..44ba035 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -94,9 +94,11 @@ and find_kernel_from_lib_modules debug =
let files = Array.to_list files in
let kernels =
List.map (
- fun f ->
- let modpath = Filename.dirname f in
- f, Filename.basename f, Filename.basename modpath, modpath
+ fun kernel_file ->
+ let kernel_name = Filename.basename kernel_file in
+ let modpath = Filename.dirname kernel_file in
+ let kernel_version = Filename.basename modpath in
+ kernel_file, kernel_name, kernel_version, modpath
) files in
List.sort (
fun (_, _, a, _) (_, _, b, _) -> compare_version b a
--
2.13.1

View File

@ -0,0 +1,45 @@
From ea3b3dce6bb77dbe57f91044c30ab49693e88e2b Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 3 Aug 2017 13:09:06 +0100
Subject: [PATCH 10/10] kernel: Reject implausibly small kernels in
/lib/modules (RHBZ#1477758).
Previous changes will reject truncated / implausibly small kernel
files found under /boot, but because the code that looks for kernels
in /lib/modules works slightly differently it would not work there.
This uses a simple stat check to reject kernels there too.
Reported by Charlie Martinez.
---
src/format_ext2_kernel.ml | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/format_ext2_kernel.ml b/src/format_ext2_kernel.ml
index 44ba035..d5d529d 100644
--- a/src/format_ext2_kernel.ml
+++ b/src/format_ext2_kernel.ml
@@ -93,12 +93,16 @@ and find_kernel_from_lib_modules debug =
let files = glob "/lib/modules/*/vmlinuz" [GLOB_NOSORT; GLOB_NOESCAPE] in
let files = Array.to_list files in
let kernels =
- List.map (
+ filter_map (
fun kernel_file ->
- let kernel_name = Filename.basename kernel_file in
- let modpath = Filename.dirname kernel_file in
- let kernel_version = Filename.basename modpath in
- kernel_file, kernel_name, kernel_version, modpath
+ let size = try (stat kernel_file).st_size with Unix_error _ -> 0 in
+ if size < 10000 then None
+ else (
+ let kernel_name = Filename.basename kernel_file in
+ let modpath = Filename.dirname kernel_file in
+ let kernel_version = Filename.basename modpath in
+ Some (kernel_file, kernel_name, kernel_version, modpath)
+ )
) files in
List.sort (
fun (_, _, a, _) (_, _, b, _) -> compare_version b a
--
2.13.1

View File

@ -31,7 +31,7 @@
Summary: Tool for creating supermin appliances
Name: supermin
Version: 5.1.18
Release: 3%{?dist}
Release: 4%{?dist}
License: GPLv2+
%if 0%{?rhel} >= 7
@ -49,6 +49,19 @@ Source1: http://libguestfs.org/download/supermin/%{name}-%{version}.tar.gz
Source2: libguestfs.keyring
%endif
# All upstream patches since 5.1.18.
Patch0001: 0001-prepare-Add-some-debugging-of-config-files-creating-.patch
# Fix supermin crash with truncated vmlinuz file (RHBZ#1477758).
Patch0002: 0002-kernel-Refactor-code-for-locating-the-kernel.patch
Patch0003: 0003-kernel-Tweak-debug-messages.patch
Patch0004: 0004-kernel-Rearrange-the-order-of-functions.patch
Patch0005: 0005-kernel-Filter-boot-kernels-using-has_modpath-later.patch
Patch0006: 0006-kernel-Change-has_modpath-function-so-it-checks-for-.patch
Patch0007: 0007-kernel-Replace-how-kernel-version-information-is-fou.patch
Patch0008: 0008-kernel-Don-t-allow-End_of_file-exception-to-escape-i.patch
Patch0009: 0009-kernel-Simple-renaming-to-make-find_kernel_from_-fun.patch
Patch0010: 0010-kernel-Reject-implausibly-small-kernels-in-lib-modul.patch
BuildRequires: /usr/bin/pod2man
BuildRequires: /usr/bin/pod2html
BuildRequires: rpm
@ -170,6 +183,10 @@ make check || {
%changelog
* Thu Aug 03 2017 Richard W.M. Jones <rjones@redhat.com> - 5.1.18-4
- Fix supermin crash with truncated vmlinuz file (RHBZ#1477758).
- Include all upstream patches since 5.1.18.
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 5.1.18-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild