[Libguestfs] [PATCH 2/2] daemon: Change chdir to use openat/fdopendir.

Richard W.M. Jones rjones at redhat.com
Mon Oct 26 13:11:32 UTC 2009


-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
-------------- next part --------------
>From f1d199310e2c93509e50e8b0b70bfde344328c02 Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Mon, 26 Oct 2009 13:00:46 +0000
Subject: [PATCH 2/2] daemon: Change chdir to use openat/fdopendir.

---
 daemon/realpath.c |   35 ++++++++++++++++++++++++++---------
 1 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/daemon/realpath.c b/daemon/realpath.c
index bfe8e67..b4f2dcc 100644
--- a/daemon/realpath.c
+++ b/daemon/realpath.c
@@ -18,16 +18,19 @@
 
 #include <config.h>
 
+#ifndef _ATFILE_SOURCE
+#define _ATFILE_SOURCE
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <sys/types.h>
 #include <dirent.h>
 
-#include "ignore-value.h"
-
 #include "daemon.h"
 #include "actions.h"
 
@@ -52,9 +55,13 @@ do_case_sensitive_path (const char *path)
 {
   char ret[PATH_MAX+1] = "/";
   size_t next = 1;
+  int fd;
 
-  /* MUST chdir ("/") before leaving this function. */
-  if (chdir (sysroot) == -1) {
+  /* 'fd' here is a surrogate for the current working directory, so
+   * that we don't have to actually call chdir(2).
+   */
+  fd = open (sysroot, O_RDONLY | O_DIRECTORY);
+  if (fd == -1) {
     reply_with_perror ("%s", sysroot);
     return NULL;
   }
@@ -93,7 +100,12 @@ do_case_sensitive_path (const char *path)
     /* Read the current directory looking (case insensitively) for
      * this element of the path.
      */
-    DIR *dir = opendir (".");
+    int fd2 = dup (fd); /* because closedir will close it */
+    if (fd2 == -1) {
+      reply_with_perror ("dup");
+      goto error;
+    }
+    DIR *dir = fdopendir (fd2);
     if (dir == NULL) {
       reply_with_perror ("opendir");
       goto error;
@@ -136,10 +148,15 @@ do_case_sensitive_path (const char *path)
     next += i;
 
     /* Is it a directory?  Try going into it. */
-    if (chdir (d->d_name) == -1) {
+    fd2 = openat (fd, d->d_name, O_RDONLY | O_DIRECTORY);
+    int err = errno;
+    close (fd);
+    fd = fd2;
+    errno = err;
+    if (fd == -1) {
       /* ENOTDIR is OK provided we've reached the end of the path. */
       if (errno != ENOTDIR) {
-        reply_with_perror ("chdir: %s", d->d_name);
+        reply_with_perror ("openat: %s", d->d_name);
         goto error;
       }
 
@@ -150,7 +167,7 @@ do_case_sensitive_path (const char *path)
     }
   }
 
-  ignore_value (chdir ("/"));
+  close (fd);
 
   ret[next] = '\0';
   char *retp = strdup (ret);
@@ -161,6 +178,6 @@ do_case_sensitive_path (const char *path)
   return retp;                  /* caller frees */
 
  error:
-  ignore_value (chdir ("/"));
+  close (fd);
   return NULL;
 }
-- 
1.6.5.rc2



More information about the Libguestfs mailing list