Richard W.M. Jones
2012-Sep-28 10:20 UTC
[Libguestfs] [PATCH 0/2] Fix calls to case_sensitive_path.
Proposed patches to fix https://bugzilla.redhat.com/show_bug.cgi?id=858126
Richard W.M. Jones
2012-Sep-28 10:20 UTC
[Libguestfs] [PATCH 1/2] virt-edit: If case_sensitive_path returns an error, exit.
From: "Richard W.M. Jones" <rjones at redhat.com> The 'windows_path' function was blindly copied from virt-cat. In virt-cat, errors are checked by the caller to 'windows_path'. But virt-edit lacks this check. Change the function in virt-edit to add a check and exit on error. --- edit/virt-edit.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/edit/virt-edit.c b/edit/virt-edit.c index 73d6f07..f763926 100644 --- a/edit/virt-edit.c +++ b/edit/virt-edit.c @@ -646,6 +646,8 @@ windows_path (guestfs_h *g, const char *root, const char *path) char *t = guestfs_case_sensitive_path (g, ret); free (ret); ret = t; + if (ret == NULL) + exit (EXIT_FAILURE); return ret; } -- 1.7.11.4
Richard W.M. Jones
2012-Sep-28 10:20 UTC
[Libguestfs] [PATCH 2/2] inspection: Fix calls to case_sensitive_path (RHBZ#858126).
From: "Richard W.M. Jones" <rjones at redhat.com> Don't assume that if guestfs_case_sensitive_path returns NULL, that it means the file does not exist. The (previously undefined) behaviour of case_sensitive_path was that a NULL return meant "either the file doesn't exist or some other error". However in commit 973581780d8a006f336684fef6762801402d775d this was changed so that if the last element of the path didn't exist, it was assumed to be a new file and the (non-NULL) path of the new file is returned. This change breaks code (including in libguestfs) which tries to use case_sensitive_path as a dual-purpose call to fix-up a path for Windows and test if the file exists. Such code should be rewritten so that it explicitly tests for file existence after calling case_sensitive_path. I examined all the calls to case_sensitive_path in libguestfs and modified them where necessary. --- examples/virt-dhcp-address.c | 4 +--- perl/lib/Sys/Guestfs/Lib.pm | 3 +++ src/inspect-apps.c | 7 ++----- src/inspect-fs-windows.c | 25 +++++++++---------------- tools/virt-win-reg | 14 ++------------ 5 files changed, 17 insertions(+), 36 deletions(-) diff --git a/examples/virt-dhcp-address.c b/examples/virt-dhcp-address.c index c4e3647..df06ebe 100644 --- a/examples/virt-dhcp-address.c +++ b/examples/virt-dhcp-address.c @@ -206,10 +206,8 @@ print_dhcp_address_windows (guestfs_h *g, char *root_fs) /* Locate the SYSTEM hive case-sensitive path. */ system_path guestfs_case_sensitive_path (g, "/windows/system32/config/system"); - if (!system_path) { - fprintf (stderr, "virt-dhcp-address: HKLM\\System not found in this guest."); + if (!system_path) exit (EXIT_FAILURE); - } /* Open the hive to parse it. Note that before libguestfs 1.19.35 * you had to download the file and parse it using hivex(3). Since diff --git a/perl/lib/Sys/Guestfs/Lib.pm b/perl/lib/Sys/Guestfs/Lib.pm index 33e8acb..5dde409 100644 --- a/perl/lib/Sys/Guestfs/Lib.pm +++ b/perl/lib/Sys/Guestfs/Lib.pm @@ -356,6 +356,9 @@ sub resolve_windows_path my $r; eval { $r = $g->case_sensitive_path ($path); }; + + $r = undef if defined $r && ! $g->exists ($r); + return $r; } diff --git a/src/inspect-apps.c b/src/inspect-apps.c index e9f020a..f65c70a 100644 --- a/src/inspect-apps.c +++ b/src/inspect-apps.c @@ -418,12 +418,9 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs) snprintf (software, len, "%s/system32/config/software", fs->windows_systemroot); - char *software_path = guestfs___case_sensitive_path_silently (g, software); - if (!software_path) { - /* Missing software hive is a problem. */ - error (g, "no HKLM\\SOFTWARE hive found in the guest"); + char *software_path = guestfs_case_sensitive_path (g, software); + if (!software_path) return NULL; - } struct guestfs_application_list *ret = NULL; const char *hivepath[] diff --git a/src/inspect-fs-windows.c b/src/inspect-fs-windows.c index c3a5aba..7031228 100644 --- a/src/inspect-fs-windows.c +++ b/src/inspect-fs-windows.c @@ -157,11 +157,9 @@ guestfs___check_windows_root (guestfs_h *g, struct inspect_fs *fs) return -1; } - systemroot = guestfs___case_sensitive_path_silently (g, systemroots[i]); - if (!systemroot) { - error (g, _("cannot resolve Windows %%SYSTEMROOT%%")); + systemroot = guestfs_case_sensitive_path (g, systemroots[i]); + if (!systemroot) return -1; - } debug (g, "windows %%SYSTEMROOT%% = %s", systemroot); @@ -189,9 +187,10 @@ check_windows_arch (guestfs_h *g, struct inspect_fs *fs) char cmd_exe[len]; snprintf (cmd_exe, len, "%s/system32/cmd.exe", fs->windows_systemroot); - char *cmd_exe_path = guestfs___case_sensitive_path_silently (g, cmd_exe); + /* Should exist because of previous check above in has_windows_systemroot. */ + char *cmd_exe_path = guestfs_case_sensitive_path (g, cmd_exe); if (!cmd_exe_path) - return 0; + return -1; char *arch = guestfs_file_architecture (g, cmd_exe_path); free (cmd_exe_path); @@ -216,12 +215,9 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs) snprintf (software, len, "%s/system32/config/software", fs->windows_systemroot); - char *software_path = guestfs___case_sensitive_path_silently (g, software); + char *software_path = guestfs_case_sensitive_path (g, software); if (!software_path) - /* If the software hive doesn't exist, just accept that we cannot - * find product_name etc. - */ - return 0; + return -1; int64_t node; const char *hivepath[] @@ -317,12 +313,9 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs) snprintf (system, len, "%s/system32/config/system", fs->windows_systemroot); - char *system_path = guestfs___case_sensitive_path_silently (g, system); + char *system_path = guestfs_case_sensitive_path (g, system); if (!system_path) - /* If the system hive doesn't exist, just accept that we cannot - * find hostname etc. - */ - return 0; + return -1; int ret = -1; int64_t root, node, value; diff --git a/tools/virt-win-reg b/tools/virt-win-reg index 9e053dd..0a1b754 100755 --- a/tools/virt-win-reg +++ b/tools/virt-win-reg @@ -516,12 +516,7 @@ sub download_hive my $hivefile = shift; my $hiveshortname = shift; - my $winfile; - eval { $winfile = $g->case_sensitive_path ($hivefile); }; - if ($@) { - die __x("virt-win-reg: {p}: file not found in guest: {err}\n", - p => $hivefile, err => $@); - } + my $winfile = $g->case_sensitive_path ($hivefile); warn "downloading $winfile ..." if $debug; eval { $g->download ($winfile, "$tmpdir/$hiveshortname"); }; @@ -538,12 +533,7 @@ sub upload_hive my $hiveshortname = shift; my $hivefile = shift; - my $winfile; - eval { $winfile = $g->case_sensitive_path ($hivefile); }; - if ($@) { - die __x("virt-win-reg: {p}: file not found in guest: {err}\n", - p => $hivefile, err => $@); - } + my $winfile = $g->case_sensitive_path ($hivefile); warn "uploading $winfile ..." if $debug; eval { $g->upload ("$tmpdir/$hiveshortname", $winfile); }; -- 1.7.11.4