From a2665bd0a4e1534d70430d4a4f4c0f6ef8aca4eb Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sat, 9 Mar 2019 14:37:17 +0000 Subject: [PATCH] getroot: Save/restore CWD more reliably on Unix Various GRUB utilities fail if the current directory doesn't exist, because grub_find_device() chdirs to a different directory and then fails when trying to chdir back. Gnulib's save-cwd module uses fchdir() instead when it can, avoiding this category of problem. Fixes Debian bug #918700. Signed-off-by: Colin Watson Reviewed-by: Daniel Kiper --- bootstrap.conf | 1 + grub-core/osdep/unix/getroot.c | 26 +++++++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 6781d25a7..988dda099 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -33,6 +33,7 @@ gnulib_modules=" progname realloc-gnu regex + save-cwd " gnulib_tool_option_extras="\ diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c index 3046e22cc..46d7116c6 100644 --- a/grub-core/osdep/unix/getroot.c +++ b/grub-core/osdep/unix/getroot.c @@ -34,6 +34,7 @@ #ifdef HAVE_LIMITS_H #include #endif + #include #include @@ -113,6 +114,8 @@ #include #endif +#include "save-cwd.h" + #if !defined (__GNU__) static void strip_extra_slashes (char *dir) @@ -352,7 +355,7 @@ char * grub_find_device (const char *dir, dev_t dev) { DIR *dp; - char *saved_cwd; + struct saved_cwd saved_cwd; struct dirent *ent; if (! dir) @@ -362,12 +365,17 @@ grub_find_device (const char *dir, dev_t dev) if (! dp) return 0; - saved_cwd = xgetcwd (); + if (save_cwd (&saved_cwd) < 0) + { + grub_util_error ("%s", _("cannot save the original directory")); + closedir (dp); + return 0; + } grub_util_info ("changing current directory to %s", dir); if (chdir (dir) < 0) { - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return 0; } @@ -410,11 +418,11 @@ grub_find_device (const char *dir, dev_t dev) if (res) { - if (chdir (saved_cwd) < 0) + if (restore_cwd (&saved_cwd) < 0) grub_util_error ("%s", _("cannot restore the original directory")); - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return res; } @@ -468,19 +476,19 @@ grub_find_device (const char *dir, dev_t dev) continue; } - if (chdir (saved_cwd) < 0) + if (restore_cwd (&saved_cwd) < 0) grub_util_error ("%s", _("cannot restore the original directory")); - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return res; } } - if (chdir (saved_cwd) < 0) + if (restore_cwd (&saved_cwd) < 0) grub_util_error ("%s", _("cannot restore the original directory")); - free (saved_cwd); + free_cwd (&saved_cwd); closedir (dp); return 0; }