From 57bd50bb336c299f0904abd0bb11377be29a7a79 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 5 Apr 2022 06:47:50 -0400 Subject: [PATCH] import virt-v2v-1.45.99-2.el9_0 --- .../0010-lib-Remove-Utils.metaversion.patch | 55 +++ ...mon-code-for-creating-v2v-directory-.patch | 169 +++++++++ ...n-of-v2v-directory-until-after-optio.patch | 44 +++ ...-Correct-copy-paste-error-in-comment.patch | 26 ++ ...rity-of-in-out-sockets-when-running-.patch | 151 ++++++++ ...un_unix-formally-require-externally-.patch | 343 ++++++++++++++++++ SPECS/virt-v2v.spec | 12 +- 7 files changed, 799 insertions(+), 1 deletion(-) create mode 100644 SOURCES/0010-lib-Remove-Utils.metaversion.patch create mode 100644 SOURCES/0011-lib-v2v-Move-common-code-for-creating-v2v-directory-.patch create mode 100644 SOURCES/0012-v2v-Move-creation-of-v2v-directory-until-after-optio.patch create mode 100644 SOURCES/0013-lib-nbdkit.ml-Correct-copy-paste-error-in-comment.patch create mode 100644 SOURCES/0014-lib-Improve-security-of-in-out-sockets-when-running-.patch create mode 100644 SOURCES/0015-nbdkit-qemuNBD-run_unix-formally-require-externally-.patch diff --git a/SOURCES/0010-lib-Remove-Utils.metaversion.patch b/SOURCES/0010-lib-Remove-Utils.metaversion.patch new file mode 100644 index 0000000..da97e31 --- /dev/null +++ b/SOURCES/0010-lib-Remove-Utils.metaversion.patch @@ -0,0 +1,55 @@ +From 67ebe6585e7db9cfc1f01de9777f780db42868f2 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 22 Mar 2022 13:39:57 +0000 +Subject: [PATCH] lib: Remove Utils.metaversion + +This was used before we turned the helpers into OCaml modules but is +now dead code, remove it. + +Fixes: commit 4de22686fe74e1711efd9bfed3f663b67e7ad69e +Fixes: commit 724ecb5e887e5b71db836143ec0c0d8a20b05903 +Fixes: commit 5609c73c615a8f12c5c6d50908bb4761bdc16173 +(cherry picked from commit c208bc97d863aa43857c72608a1fc57ab50047ed) +--- + lib/utils.ml | 2 -- + lib/utils.mli | 11 ----------- + 2 files changed, 13 deletions(-) + +diff --git a/lib/utils.ml b/lib/utils.ml +index 7b16dd8b..4f0ff67a 100644 +--- a/lib/utils.ml ++++ b/lib/utils.ml +@@ -164,8 +164,6 @@ let rec wait_for_file filename timeout = + wait_for_file filename (timeout-1) + ) + +-let metaversion = Digest.to_hex (Digest.string Config.package_version_full) +- + let with_nbd_connect_unix ?(meta_contexts = []) ~socket f = + let nbd = NBD.create () in + protect +diff --git a/lib/utils.mli b/lib/utils.mli +index 76a2ec8c..3f8e4b3c 100644 +--- a/lib/utils.mli ++++ b/lib/utils.mli +@@ -67,17 +67,6 @@ val wait_for_file : string -> int -> bool + (** [wait_for_file filename timeout] waits up to [timeout] seconds for + [filename] to appear. It returns [true] if the file appeared. *) + +-val metaversion : string +-(** When writing the metadata files between versions we serialize this +- string first to ensure the binary metadata blob is compatible. +- +- This prevents mixing and matching helpers between incompatible +- versions of virt-v2v (which could cause a crash) and discourages +- people from trying to write their own metadata. +- +- Eventually we may switch to using an "open metadata" format instead +- (eg. XML). *) +- + val with_nbd_connect_unix : ?meta_contexts:string list -> + socket:string -> + (NBD.t -> 'a) -> +-- +2.31.1 + diff --git a/SOURCES/0011-lib-v2v-Move-common-code-for-creating-v2v-directory-.patch b/SOURCES/0011-lib-v2v-Move-common-code-for-creating-v2v-directory-.patch new file mode 100644 index 0000000..e1776e1 --- /dev/null +++ b/SOURCES/0011-lib-v2v-Move-common-code-for-creating-v2v-directory-.patch @@ -0,0 +1,169 @@ +From d604830d0da31280c347346343dc880e14965cf8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 22 Mar 2022 13:49:20 +0000 +Subject: [PATCH] lib, v2v: Move common code for creating v2v directory to + Utils + +I have also renamed the directory in the code from "tmpdir" to +"v2vdir" since tmpdir was a bit generic and didn't accurately describe +what this directory is for. + +This is simple refactoring. + +(cherry picked from commit 5a60e9a4f6e68d50c6b22eb0c8608aef563bf516) +--- + lib/utils.ml | 9 +++++++++ + lib/utils.mli | 3 +++ + v2v/v2v.ml | 37 ++++++++++++++----------------------- + v2v/v2v_unit_tests.ml | 1 + + 4 files changed, 27 insertions(+), 23 deletions(-) + +diff --git a/lib/utils.ml b/lib/utils.ml +index 4f0ff67a..876a44c6 100644 +--- a/lib/utils.ml ++++ b/lib/utils.ml +@@ -22,6 +22,7 @@ open Printf + + open Std_utils + open Tools_utils ++open Unix_utils + open Common_gettext.Gettext + + let large_tmpdir = +@@ -155,6 +156,14 @@ let error_if_no_ssh_agent () = + with Not_found -> + error (f_"ssh-agent authentication has not been set up ($SSH_AUTH_SOCK is not set). This is required by qemu to do passwordless ssh access. See the virt-v2v(1) man page for more information.") + ++(* Create the directory containing inX and outX sockets. *) ++let create_v2v_directory () = ++ let d = Mkdtemp.temp_dir "v2v." in ++ let running_as_root = Unix.geteuid () = 0 in ++ if running_as_root then Unix.chmod d 0o711; ++ On_exit.rmdir d; ++ d ++ + (* Wait for a file to appear until a timeout. *) + let rec wait_for_file filename timeout = + if Sys.file_exists filename then true +diff --git a/lib/utils.mli b/lib/utils.mli +index 3f8e4b3c..c571cca5 100644 +--- a/lib/utils.mli ++++ b/lib/utils.mli +@@ -63,6 +63,9 @@ val backend_is_libvirt : unit -> bool + + val error_if_no_ssh_agent : unit -> unit + ++val create_v2v_directory : unit -> string ++(** Create the directory containing inX and outX sockets. *) ++ + val wait_for_file : string -> int -> bool + (** [wait_for_file filename timeout] waits up to [timeout] seconds for + [filename] to appear. It returns [true] if the file appeared. *) +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index 6859a02c..71dd1c4d 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -37,17 +37,8 @@ open Utils + let mac_re = PCRE.compile ~anchored:true "([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)" + let mac_ip_re = PCRE.compile ~anchored:true "([[:xdigit:]]|:|\\.)+" + +-(* Create the temporary directory to control conversion. +- * +- * Because it contains sockets, if we're running as root then +- * we must make it executable by world. +- *) +-let tmpdir = +- let tmpdir = Mkdtemp.temp_dir "v2v." in +- let running_as_root = geteuid () = 0 in +- if running_as_root then chmod tmpdir 0o711; +- On_exit.rmdir tmpdir; +- tmpdir ++(* Create the temporary directory to control conversion. *) ++let v2vdir = create_v2v_directory () + + let rec main () = + let set_string_option_once optname optref arg = +@@ -523,7 +514,7 @@ read the man page virt-v2v(1). + (* Start the input module (runs an NBD server in the background). *) + message (f_"Setting up the source: %s") + (Input_module.to_string input_options args); +- let source = Input_module.setup tmpdir input_options args in ++ let source = Input_module.setup v2vdir input_options args in + + (* If --print-source then print the source metadata and exit. *) + if print_source then ( +@@ -540,28 +531,28 @@ read the man page virt-v2v(1). + let output_poptions = Output_module.parse_options output_options source in + + (* Do the conversion. *) +- with_open_out (tmpdir // "convert") (fun _ -> ()); +- let inspect, target_meta = Convert.convert tmpdir conv_options source in +- unlink (tmpdir // "convert"); ++ with_open_out (v2vdir // "convert") (fun _ -> ()); ++ let inspect, target_meta = Convert.convert v2vdir conv_options source in ++ unlink (v2vdir // "convert"); + + (* Start the output module (runs an NBD server in the background). *) + message (f_"Setting up the destination: %s") + (Output_module.to_string output_options); +- let output_t = Output_module.setup tmpdir output_poptions source in ++ let output_t = Output_module.setup v2vdir output_poptions source in + + (* Debug the v2vdir. *) + if verbose () then ( +- let cmd = sprintf "ls -alZ %s 1>&2" (quote tmpdir) in ++ let cmd = sprintf "ls -alZ %s 1>&2" (quote v2vdir) in + ignore (Sys.command cmd) + ); + + (* Do the copy. *) +- with_open_out (tmpdir // "copy") (fun _ -> ()); ++ with_open_out (v2vdir // "copy") (fun _ -> ()); + + (* Get the list of disks and corresponding sockets. *) + let rec loop acc i = +- let input_socket = sprintf "%s/in%d" tmpdir i +- and output_socket = sprintf "%s/out%d" tmpdir i in ++ let input_socket = sprintf "%s/in%d" v2vdir i ++ and output_socket = sprintf "%s/out%d" v2vdir i in + if Sys.file_exists input_socket && Sys.file_exists output_socket then + loop ((i, input_socket, output_socket) :: acc) (i+1) + else +@@ -591,11 +582,11 @@ read the man page virt-v2v(1). + ) disks; + + (* End of copying phase. *) +- unlink (tmpdir // "copy"); ++ unlink (v2vdir // "copy"); + + (* Do the finalization step. *) + message (f_"Creating output metadata"); +- Output_module.finalize tmpdir output_poptions output_t ++ Output_module.finalize v2vdir output_poptions output_t + source inspect target_meta; + + message (f_"Finishing off"); +@@ -604,7 +595,7 @@ read the man page virt-v2v(1). + * use the presence or absence of the file to determine if + * on-success or on-fail cleanup is required. + *) +- with_open_out (tmpdir // "done") (fun _ -> ()) ++ with_open_out (v2vdir // "done") (fun _ -> ()) + + (* Conversion can fail or hang if there is insufficient free space in + * the large temporary directory. Some input modules use large_tmpdir +diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml +index 889f7998..bf5306c4 100644 +--- a/v2v/v2v_unit_tests.ml ++++ b/v2v/v2v_unit_tests.ml +@@ -26,6 +26,7 @@ open Std_utils + open Tools_utils + + open Types ++open Utils + + let inspect_defaults = { + i_type = ""; i_distro = ""; i_osinfo = ""; i_arch = ""; +-- +2.31.1 + diff --git a/SOURCES/0012-v2v-Move-creation-of-v2v-directory-until-after-optio.patch b/SOURCES/0012-v2v-Move-creation-of-v2v-directory-until-after-optio.patch new file mode 100644 index 0000000..602b56c --- /dev/null +++ b/SOURCES/0012-v2v-Move-creation-of-v2v-directory-until-after-optio.patch @@ -0,0 +1,44 @@ +From e001191c79e3e890d433fa237deda2332773ab97 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 22 Mar 2022 15:36:00 +0000 +Subject: [PATCH] v2v: Move creation of v2v directory until after option + parsing + +Only after option parsing does the -v (verbose) option take effect, +and so any debug messages emitted before this point are not seen. In +particular, debug messages emitted when creating the v2v directory +were lost. In any case there's no point creating this directory until +nearer the point when we might actually need it. + +(cherry picked from commit 88aaf8263ae89a40e72197ba58f08bc777dc59c3) +--- + v2v/v2v.ml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/v2v/v2v.ml b/v2v/v2v.ml +index 71dd1c4d..661f2dec 100644 +--- a/v2v/v2v.ml ++++ b/v2v/v2v.ml +@@ -37,9 +37,6 @@ open Utils + let mac_re = PCRE.compile ~anchored:true "([[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}):(network|bridge|ip):(.*)" + let mac_ip_re = PCRE.compile ~anchored:true "([[:xdigit:]]|:|\\.)+" + +-(* Create the temporary directory to control conversion. *) +-let v2vdir = create_v2v_directory () +- + let rec main () = + let set_string_option_once optname optref arg = + match !optref with +@@ -333,6 +330,9 @@ read the man page virt-v2v(1). + debug "libvirt version: %d.%d.%d" major minor release + ); + ++ (* Create the temporary directory to control conversion. *) ++ let v2vdir = create_v2v_directory () in ++ + (* Dereference the arguments. *) + let args = List.rev !args in + let input_conn = !input_conn in +-- +2.31.1 + diff --git a/SOURCES/0013-lib-nbdkit.ml-Correct-copy-paste-error-in-comment.patch b/SOURCES/0013-lib-nbdkit.ml-Correct-copy-paste-error-in-comment.patch new file mode 100644 index 0000000..38684fe --- /dev/null +++ b/SOURCES/0013-lib-nbdkit.ml-Correct-copy-paste-error-in-comment.patch @@ -0,0 +1,26 @@ +From 3d20ba06ab98388c3f08e2430eef53e1e912ef62 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Wed, 23 Mar 2022 10:37:24 +0000 +Subject: [PATCH] lib/nbdkit.ml: Correct copy/paste error in comment + +(cherry picked from commit f44c8d2e819a38ea670b0577fafc8f88265ceacf) +--- + lib/nbdkit.ml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/nbdkit.ml b/lib/nbdkit.ml +index 6787fbb0..85621775 100644 +--- a/lib/nbdkit.ml ++++ b/lib/nbdkit.ml +@@ -202,7 +202,7 @@ If the messages above are not sufficient to diagnose the problem then add the + socket]); + ); + +- (* Set the regular Unix permissions, in case qemu is ++ (* Set the regular Unix permissions, in case nbdkit is + * running as another user. + *) + chmod socket 0o777; +-- +2.31.1 + diff --git a/SOURCES/0014-lib-Improve-security-of-in-out-sockets-when-running-.patch b/SOURCES/0014-lib-Improve-security-of-in-out-sockets-when-running-.patch new file mode 100644 index 0000000..0855b9b --- /dev/null +++ b/SOURCES/0014-lib-Improve-security-of-in-out-sockets-when-running-.patch @@ -0,0 +1,151 @@ +From 6ca02e37d72a81e7e32d4d3eef24d8a0abe3deb2 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 22 Mar 2022 13:53:41 +0000 +Subject: [PATCH] lib: Improve security of in/out sockets when running virt-v2v + as root +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When using the libvirt backend and running as root, libvirt will run +qemu as a non-root user (eg. qemu:qemu). The v2v directory stores NBD +endpoints that qemu must be able to open and so we set the directory +to mode 0711. Unfortunately this permits any non-root user to open +the sockets (since, by design, they have predictable names within the +directory). + +Additionally we were setting the sockets themselves to 0777 mode. + +Instead of using directory permissions, change the owner of the +directory and sockets to precisely give access to the qemu user and no +one else. + +Reported-by: Xiaodai Wang +Thanks: Dr David Gilbert, Daniel Berrangé, Laszlo Ersek +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2066773 +Reviewed-by: Laszlo Ersek +(cherry picked from commit 4e7f206843735ba24e2034f694a214ef057ee139) +--- + lib/nbdkit.ml | 3 ++- + lib/qemuNBD.ml | 3 ++- + lib/utils.ml | 47 +++++++++++++++++++++++++++++++++++++++++++++-- + lib/utils.mli | 11 +++++++++++ + 4 files changed, 60 insertions(+), 4 deletions(-) + +diff --git a/lib/nbdkit.ml b/lib/nbdkit.ml +index 85621775..9ee6f39c 100644 +--- a/lib/nbdkit.ml ++++ b/lib/nbdkit.ml +@@ -205,6 +205,7 @@ If the messages above are not sufficient to diagnose the problem then add the + (* Set the regular Unix permissions, in case nbdkit is + * running as another user. + *) +- chmod socket 0o777; ++ chown_for_libvirt_rhbz_1045069 socket; ++ chmod socket 0o700; + + socket, pid +diff --git a/lib/qemuNBD.ml b/lib/qemuNBD.ml +index 54139ce0..2c999b9f 100644 +--- a/lib/qemuNBD.ml ++++ b/lib/qemuNBD.ml +@@ -150,7 +150,8 @@ If the messages above are not sufficient to diagnose the problem then add the + (* Set the regular Unix permissions, in case qemu is + * running as another user. + *) +- chmod socket 0o777; ++ chown_for_libvirt_rhbz_1045069 socket; ++ chmod socket 0o700; + + (* We don't need the PID file any longer. *) + unlink pidfile; +diff --git a/lib/utils.ml b/lib/utils.ml +index 876a44c6..7116a4f9 100644 +--- a/lib/utils.ml ++++ b/lib/utils.ml +@@ -147,6 +147,50 @@ let backend_is_libvirt () = + let backend = fst (String.split ":" backend) in + backend = "libvirt" + ++let rec chown_for_libvirt_rhbz_1045069 file = ++ let running_as_root = Unix.geteuid () = 0 in ++ if running_as_root && backend_is_libvirt () then ( ++ try ++ let user = Option.default "qemu" (libvirt_qemu_user ()) in ++ let uid = ++ if String.is_prefix user "+" then ++ int_of_string (String.sub user 1 (String.length user - 1)) ++ else ++ (Unix.getpwnam user).pw_uid in ++ debug "setting owner of %s to %d:root" file uid; ++ Unix.chown file uid 0 ++ with ++ | exn -> (* Print exception, but continue. *) ++ debug "could not set owner of %s: %s" ++ file (Printexc.to_string exn) ++ ) ++ ++(* Get the local user that libvirt uses to run qemu when we are ++ * running as root. This is returned as an optional string ++ * containing the username. The username might be "+NNN" ++ * meaning a numeric UID. ++ * https://listman.redhat.com/archives/libguestfs/2022-March/028450.html ++ *) ++and libvirt_qemu_user = ++ let user = ++ lazy ( ++ let conn = Libvirt.Connect.connect_readonly () in ++ let xml = Libvirt.Connect.get_capabilities conn in ++ let doc = Xml.parse_memory xml in ++ let xpathctx = Xml.xpath_new_context doc in ++ let expr = ++ "//secmodel[./model=\"dac\"]/baselabel[@type=\"kvm\"]/text()" in ++ let uid_gid = Xpath_helpers.xpath_string xpathctx expr in ++ match uid_gid with ++ | None -> None ++ | Some uid_gid -> ++ (* The string will be something like "+107:+107", return the ++ * UID part. ++ *) ++ Some (fst (String.split ":" uid_gid)) ++ ) in ++ fun () -> Lazy.force user ++ + (* When using the SSH driver in qemu (currently) this requires + * ssh-agent authentication. Give a clear error if this hasn't been + * set up (RHBZ#1139973). This might improve if we switch to libssh1. +@@ -159,8 +203,7 @@ let error_if_no_ssh_agent () = + (* Create the directory containing inX and outX sockets. *) + let create_v2v_directory () = + let d = Mkdtemp.temp_dir "v2v." in +- let running_as_root = Unix.geteuid () = 0 in +- if running_as_root then Unix.chmod d 0o711; ++ chown_for_libvirt_rhbz_1045069 d; + On_exit.rmdir d; + d + +diff --git a/lib/utils.mli b/lib/utils.mli +index c571cca5..d431e21f 100644 +--- a/lib/utils.mli ++++ b/lib/utils.mli +@@ -61,6 +61,17 @@ val qemu_img_supports_offset_and_size : unit -> bool + val backend_is_libvirt : unit -> bool + (** Return true iff the current backend is libvirt. *) + ++val chown_for_libvirt_rhbz_1045069 : string -> unit ++(** If running and root, and if the backend is libvirt, libvirt ++ will run qemu as a non-root user. This prevents access ++ to root-owned files and directories. To fix this, provide ++ a function to chown things we might need to qemu:root so ++ qemu can access them. Note that root normally ignores ++ permissions so can still access the resource. ++ ++ This is best-effort. If something fails then we carry ++ on and hope for the best. *) ++ + val error_if_no_ssh_agent : unit -> unit + + val create_v2v_directory : unit -> string +-- +2.31.1 + diff --git a/SOURCES/0015-nbdkit-qemuNBD-run_unix-formally-require-externally-.patch b/SOURCES/0015-nbdkit-qemuNBD-run_unix-formally-require-externally-.patch new file mode 100644 index 0000000..adb59d0 --- /dev/null +++ b/SOURCES/0015-nbdkit-qemuNBD-run_unix-formally-require-externally-.patch @@ -0,0 +1,343 @@ +From 6d99469c696ea691a908ad8a65314475e43b7bd0 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Wed, 23 Mar 2022 11:43:30 +0100 +Subject: [PATCH] nbdkit, qemuNBD: run_unix: formally require externally + provided socket + +At this point, virt-v2v never relies on the Unix domain sockets created +inside the "run_unix" implementations. Simplify the code by removing this +option. + +Consequently, the internally created temporary directory only holds the +NBD server's PID file, and never its UNIX domain socket. Therefore: + +(1) we no longer need the libguestfs socket dir to be our temp dir, + +(2) we need not change the file mode bits on the temp dir, + +(3) we can rename "tmpdir" to the more specific "piddir". + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2066773 +Signed-off-by: Laszlo Ersek +Message-Id: <20220323104330.9667-1-lersek@redhat.com> +Acked-by: Richard W.M. Jones +(cherry picked from commit 9788b06765af335b054aba03f41d1b829ed13092) +--- + input/input_disk.ml | 4 ++-- + input/input_libvirt.ml | 8 ++++---- + input/input_ova.ml | 2 +- + input/input_vddk.ml | 2 +- + input/input_vmx.ml | 4 ++-- + input/input_xen_ssh.ml | 2 +- + input/vCenter.ml | 2 +- + lib/nbdkit.ml | 24 +++++------------------- + lib/nbdkit.mli | 6 +----- + lib/qemuNBD.ml | 25 +++++-------------------- + lib/qemuNBD.mli | 6 +----- + output/output.ml | 4 ++-- + output/output_null.ml | 2 +- + output/output_rhv_upload.ml | 2 +- + 14 files changed, 28 insertions(+), 65 deletions(-) + +diff --git a/input/input_disk.ml b/input/input_disk.ml +index dc3bed6f..c08548ee 100644 +--- a/input/input_disk.ml ++++ b/input/input_disk.ml +@@ -109,7 +109,7 @@ module Disk = struct + Nbdkit.add_arg cmd "file" disk; + if Nbdkit.version nbdkit_config >= (1, 22, 0) then + Nbdkit.add_arg cmd "cache" "none"; +- let _, pid = Nbdkit.run_unix ~socket cmd in ++ let _, pid = Nbdkit.run_unix socket cmd in + + (* --exit-with-parent should ensure nbdkit is cleaned + * up when we exit, but it's not supported everywhere. +@@ -120,7 +120,7 @@ module Disk = struct + let cmd = QemuNBD.create disk in + QemuNBD.set_snapshot cmd true; (* protective overlay *) + QemuNBD.set_format cmd (Some format); +- let _, pid = QemuNBD.run_unix ~socket cmd in ++ let _, pid = QemuNBD.run_unix socket cmd in + On_exit.kill pid + ) args; + +diff --git a/input/input_libvirt.ml b/input/input_libvirt.ml +index ee836aa0..ad7e20e8 100644 +--- a/input/input_libvirt.ml ++++ b/input/input_libvirt.ml +@@ -87,7 +87,7 @@ and setup_servers dir disks = + Nbdkit.add_arg cmd "hostname" hostname; + Nbdkit.add_arg cmd "port" (string_of_int port); + Nbdkit.add_arg cmd "shared" "true"; +- let _, pid = Nbdkit.run_unix ~socket cmd in ++ let _, pid = Nbdkit.run_unix socket cmd in + + (* --exit-with-parent should ensure nbdkit is cleaned + * up when we exit, but it's not supported everywhere. +@@ -98,7 +98,7 @@ and setup_servers dir disks = + | HTTP url -> + let cor = dir // "convert" in + let cmd = Nbdkit_curl.create_curl ~cor url in +- let _, pid = Nbdkit.run_unix ~socket cmd in ++ let _, pid = Nbdkit.run_unix socket cmd in + + (* --exit-with-parent should ensure nbdkit is cleaned + * up when we exit, but it's not supported everywhere. +@@ -113,7 +113,7 @@ and setup_servers dir disks = + Nbdkit.add_arg cmd "file" filename; + if Nbdkit.version nbdkit_config >= (1, 22, 0) then + Nbdkit.add_arg cmd "cache" "none"; +- let _, pid = Nbdkit.run_unix ~socket cmd in ++ let _, pid = Nbdkit.run_unix socket cmd in + + (* --exit-with-parent should ensure nbdkit is cleaned + * up when we exit, but it's not supported everywhere. +@@ -125,7 +125,7 @@ and setup_servers dir disks = + let cmd = QemuNBD.create filename in + QemuNBD.set_snapshot cmd true; (* protective overlay *) + QemuNBD.set_format cmd format; +- let _, pid = QemuNBD.run_unix ~socket cmd in ++ let _, pid = QemuNBD.run_unix socket cmd in + On_exit.kill pid + ) disks + +diff --git a/input/input_ova.ml b/input/input_ova.ml +index c94ddc79..796cc3bc 100644 +--- a/input/input_ova.ml ++++ b/input/input_ova.ml +@@ -192,7 +192,7 @@ module OVA = struct + let cmd = QemuNBD.create qemu_uri in + QemuNBD.set_snapshot cmd true; (* protective overlay *) + QemuNBD.set_format cmd None; (* auto-detect format *) +- let _, pid = QemuNBD.run_unix ~socket cmd in ++ let _, pid = QemuNBD.run_unix socket cmd in + On_exit.kill pid + ) qemu_uris; + +diff --git a/input/input_vddk.ml b/input/input_vddk.ml +index 29764095..f8bf3d28 100644 +--- a/input/input_vddk.ml ++++ b/input/input_vddk.ml +@@ -196,7 +196,7 @@ information on these settings. + ?nfchostport ?password_file:options.input_password ?port + ~server ?snapshot ~thumbprint ?transports ?user + path in +- let _, pid = Nbdkit.run_unix ~socket nbdkit in ++ let _, pid = Nbdkit.run_unix socket nbdkit in + On_exit.kill pid + ) disks; + +diff --git a/input/input_vmx.ml b/input/input_vmx.ml +index 3aa49fa6..34ae99a3 100644 +--- a/input/input_vmx.ml ++++ b/input/input_vmx.ml +@@ -66,7 +66,7 @@ module VMX = struct + (absolute_path_from_other_file vmx_filename filename) in + QemuNBD.set_snapshot cmd true; (* protective overlay *) + QemuNBD.set_format cmd (Some "vmdk"); +- let _, pid = QemuNBD.run_unix ~socket cmd in ++ let _, pid = QemuNBD.run_unix socket cmd in + On_exit.kill pid + ) filenames + +@@ -108,7 +108,7 @@ module VMX = struct + let bandwidth = options.bandwidth in + let nbdkit = Nbdkit_ssh.create_ssh ?bandwidth ~cor ~password + ~server ?port ?user abs_path in +- let _, pid = Nbdkit.run_unix ~socket nbdkit in ++ let _, pid = Nbdkit.run_unix socket nbdkit in + On_exit.kill pid + ) filenames + ); +diff --git a/input/input_xen_ssh.ml b/input/input_xen_ssh.ml +index 85e24bce..989a0cc7 100644 +--- a/input/input_xen_ssh.ml ++++ b/input/input_xen_ssh.ml +@@ -118,7 +118,7 @@ module XenSSH = struct + let bandwidth = options.bandwidth in + let nbdkit = Nbdkit_ssh.create_ssh ?bandwidth ~cor ~password + ?port ~server ?user path in +- let _, pid = Nbdkit.run_unix ~socket nbdkit in ++ let _, pid = Nbdkit.run_unix socket nbdkit in + On_exit.kill pid + ) disks; + +diff --git a/input/vCenter.ml b/input/vCenter.ml +index 40d594f0..8a1a5655 100644 +--- a/input/vCenter.ml ++++ b/input/vCenter.ml +@@ -117,7 +117,7 @@ let rec start_nbdkit_for_path ?bandwidth ?cor ?password_file + Nbdkit_curl.create_curl ?bandwidth ?cor + ~cookie_script ~cookie_script_renew + ~sslverify https_url in +- let _, pid = Nbdkit.run_unix ~socket nbdkit in ++ let _, pid = Nbdkit.run_unix socket nbdkit in + pid + + and get_https_url dcPath uri server path = +diff --git a/lib/nbdkit.ml b/lib/nbdkit.ml +index 9ee6f39c..07896684 100644 +--- a/lib/nbdkit.ml ++++ b/lib/nbdkit.ml +@@ -102,27 +102,13 @@ let add_env cmd name value = cmd.env <- (name, value) :: cmd.env + let add_filter_if_available cmd filter = + if probe_filter filter then add_filter cmd filter + +-let run_unix ?socket cmd = +- (* Create a temporary directory where we place the socket and PID file. +- * Use the libguestfs socket directory, so it is more likely the full path +- * of the UNIX sockets will fit in the (limited) socket pathname. +- *) +- let tmpdir = +- let base_dir = (open_guestfs ())#get_sockdir () in +- let t = Mkdtemp.temp_dir ~base_dir "v2vnbdkit." in +- (* tmpdir must be readable (but not writable) by "other" so that +- * qemu can open the sockets. +- *) +- chmod t 0o755; +- On_exit.rmdir t; +- t in ++let run_unix socket cmd = ++ (* Create a temporary directory where we place the PID file. *) ++ let piddir = Mkdtemp.temp_dir "v2vnbdkit." in ++ On_exit.rmdir piddir; + + let id = unique () in +- let pidfile = tmpdir // sprintf "nbdkit%d.pid" id in +- let socket = +- match socket with +- | None -> tmpdir // sprintf "nbdkit%d.sock" id +- | Some socket -> socket in ++ let pidfile = piddir // sprintf "nbdkit%d.pid" id in + + (* Construct the final command line. *) + let add_arg, add_args_reversed, get_args = +diff --git a/lib/nbdkit.mli b/lib/nbdkit.mli +index dc2fd04b..5ba83ab0 100644 +--- a/lib/nbdkit.mli ++++ b/lib/nbdkit.mli +@@ -92,14 +92,10 @@ val add_args : cmd -> (string * string) list -> unit + val add_env : cmd -> string -> string -> unit + (** Add name=value environment variable. *) + +-val run_unix : ?socket:string -> cmd -> string * int ++val run_unix : string -> cmd -> string * int + (** Start nbdkit command listening on a Unix domain socket, waiting + for the process to start up. + +- If optional [?socket] parameter is omitted, then a temporary +- Unix domain socket name is created. If [?socket] is present +- then this overrides the temporary name. +- + Returns the Unix domain socket name and the nbdkit process ID. + + The --exit-with-parent, --foreground, --pidfile, --newstyle and +diff --git a/lib/qemuNBD.ml b/lib/qemuNBD.ml +index 2c999b9f..ae21b17c 100644 +--- a/lib/qemuNBD.ml ++++ b/lib/qemuNBD.ml +@@ -62,30 +62,15 @@ let create disk = { disk; snapshot = false; format = None } + let set_snapshot cmd snap = cmd.snapshot <- snap + let set_format cmd format = cmd.format <- format + +-let run_unix ?socket { disk; snapshot; format } = ++let run_unix socket { disk; snapshot; format } = + assert (disk <> ""); + +- (* Create a temporary directory where we place the socket and PID file. +- * Use the libguestfs socket directory, so it is more likely the full path +- * of the UNIX sockets will fit in the (limited) socket pathname. +- *) +- let tmpdir = +- let base_dir = (open_guestfs ())#get_sockdir () in +- let t = Mkdtemp.temp_dir ~base_dir "v2vqemunbd." in +- (* tmpdir must be readable (but not writable) by "other" so that +- * qemu can open the sockets. +- *) +- chmod t 0o755; +- On_exit.rmdir t; +- t in ++ (* Create a temporary directory where we place the PID file. *) ++ let piddir = Mkdtemp.temp_dir "v2vqemunbd." in ++ On_exit.rmdir piddir; + + let id = unique () in +- let pidfile = tmpdir // sprintf "qemunbd%d.pid" id in +- +- let socket = +- match socket with +- | Some socket -> socket +- | None -> tmpdir // sprintf "qemunbd%d.sock" id in ++ let pidfile = piddir // sprintf "qemunbd%d.pid" id in + + (* Construct the qemu-nbd command line. *) + let args = ref [] in +diff --git a/lib/qemuNBD.mli b/lib/qemuNBD.mli +index 83871c5b..e10d3106 100644 +--- a/lib/qemuNBD.mli ++++ b/lib/qemuNBD.mli +@@ -43,12 +43,8 @@ val set_snapshot : cmd -> bool -> unit + val set_format : cmd -> string option -> unit + (** Set the format [--format] parameter. *) + +-val run_unix : ?socket:string -> cmd -> string * int ++val run_unix : string -> cmd -> string * int + (** Start qemu-nbd command listening on a Unix domain socket, + waiting for the process to start up. + +- If optional [?socket] parameter is omitted, then a temporary +- Unix domain socket name is created. If [?socket] is present +- then this overrides the temporary name. +- + Returns the Unix domain socket name and the qemu-nbd process ID. *) +diff --git a/output/output.ml b/output/output.ml +index 7256b547..10e685c4 100644 +--- a/output/output.ml ++++ b/output/output.ml +@@ -90,7 +90,7 @@ let output_to_local_file ?(changeuid = fun f -> f ()) + let cmd = Nbdkit.add_arg cmd "cache" "none" in + cmd + ); +- let _, pid = Nbdkit.run_unix ~socket cmd in ++ let _, pid = Nbdkit.run_unix socket cmd in + + (* --exit-with-parent should ensure nbdkit is cleaned + * up when we exit, but it's not supported everywhere. +@@ -101,7 +101,7 @@ let output_to_local_file ?(changeuid = fun f -> f ()) + let cmd = QemuNBD.create filename in + QemuNBD.set_snapshot cmd false; + QemuNBD.set_format cmd (Some "qcow2"); +- let _, pid = QemuNBD.run_unix ~socket cmd in ++ let _, pid = QemuNBD.run_unix socket cmd in + On_exit.kill pid + + | _ -> +diff --git a/output/output_null.ml b/output/output_null.ml +index 86d81eaa..c8e27c0b 100644 +--- a/output/output_null.ml ++++ b/output/output_null.ml +@@ -70,7 +70,7 @@ module Null = struct + let () = + let cmd = Nbdkit.create ~quiet:true "null" in + Nbdkit.add_arg cmd "size" "7E"; +- let _, pid = Nbdkit.run_unix ~socket cmd in ++ let _, pid = Nbdkit.run_unix socket cmd in + + (* --exit-with-parent should ensure nbdkit is cleaned + * up when we exit, but it's not supported everywhere. +diff --git a/output/output_rhv_upload.ml b/output/output_rhv_upload.ml +index 72463e57..828996b3 100644 +--- a/output/output_rhv_upload.ml ++++ b/output/output_rhv_upload.ml +@@ -398,7 +398,7 @@ e command line has to match the number of guest disk images (for this guest: %d) + Nbdkit.add_arg cmd "insecure" "true"; + if is_ovirt_host then + Nbdkit.add_arg cmd "is_ovirt_host" "true"; +- let _, pid = Nbdkit.run_unix ~socket cmd in ++ let _, pid = Nbdkit.run_unix socket cmd in + List.push_front pid nbdkit_pids + ) (List.combine disks disk_uuids); + +-- +2.31.1 + diff --git a/SPECS/virt-v2v.spec b/SPECS/virt-v2v.spec index 7075010..522224f 100644 --- a/SPECS/virt-v2v.spec +++ b/SPECS/virt-v2v.spec @@ -15,7 +15,7 @@ Name: virt-v2v Epoch: 1 Version: 1.45.99 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Convert a virtual machine to run on KVM License: GPLv2+ @@ -60,6 +60,12 @@ Patch0006: 0006-RHEL-v2v-do-not-mention-SUSE-Xen-hosts-RHBZ-1430203.patch Patch0007: 0007-RHEL-point-to-KB-for-supported-v2v-hypervisors-guest.patch Patch0008: 0008-RHEL-Disable-o-glance.patch Patch0009: 0009-RHEL-Remove-the-in-place-option.patch +Patch0010: 0010-lib-Remove-Utils.metaversion.patch +Patch0011: 0011-lib-v2v-Move-common-code-for-creating-v2v-directory-.patch +Patch0012: 0012-v2v-Move-creation-of-v2v-directory-until-after-optio.patch +Patch0013: 0013-lib-nbdkit.ml-Correct-copy-paste-error-in-comment.patch +Patch0014: 0014-lib-Improve-security-of-in-out-sockets-when-running-.patch +Patch0015: 0015-nbdkit-qemuNBD-run_unix-formally-require-externally-.patch %endif %if 0%{patches_touch_autotools} @@ -302,6 +308,10 @@ popd %changelog +* Wed Mar 23 2022 Richard W.M. Jones - 1:1.45.99-2 +- Fix security issue when running virt-v2v as root + resolves: rhbz#2066775 + * Tue Feb 15 2022 Richard W.M. Jones - 1:1.45.99-1 - Rebase to upstream 1.45.99. - Add check for sufficient free space in the host