[Fakeroot-commits] [SCM] fakeroot branch, upstream, updated. debian/1.14.3-200-gb232f8a

Timo Savola tsavola at movial.fi
Tue Aug 23 13:05:37 UTC 2011


The following commit has been merged in the upstream branch:
commit dea10c4c964d6a1d015b5879401a29d66778e089
Author: Timo Savola <tsavola at movial.fi>
Date:   Fri May 20 14:14:12 2005 +0000

    Wrap close and dup2 to avoid closing TCP socket
    
    close(2) doesn't allow closing of the communication socket used by the TCP
    version.  When dup2(2) is called with the communication socket as the
    target file descriptor, it will first dup(2) the socket to a new number.
    This makes the --fd-base option and the checking obsolete.
    
    The comm_sd variable is exported for libfakeroot.c which is also
    responsible for locking.  comm_sd and the comm_sd-related functions are
    not exported for faked.c because it doesn't use that functionality AND it
    has its own comm_sd variable...  (Declarations needed by the TCP version
    of faked.c should be split away from communication.h in the future.)
    
    The fork(2) wrapper is changed to preserve errno correctly, and it no
    longer locks when closing the comm_sd of the child process.  The socket is
    now also set to close-on-exec.
    
    git-archimport-id: fakeroot at packages.debian.org--fakeroot/fakeroot--main--0.0--patch-67

diff --git a/communicate.c b/communicate.c
index ec66b0c..a99c222 100644
--- a/communicate.c
+++ b/communicate.c
@@ -49,7 +49,7 @@ int msg_snd=-1;
 int msg_get=-1;
 int sem_id=-1;
 #else /* FAKEROOT_FAKENET */
-static int comm_sd = -1;
+volatile int comm_sd = -1;
 static pthread_mutex_t comm_sd_mutex = PTHREAD_MUTEX_INITIALIZER;
 #endif /* FAKEROOT_FAKENET */
 
@@ -277,64 +277,17 @@ static struct sockaddr *get_addr(void)
 
 static void open_comm_sd(void)
 {
-  char *str;
-  int base, val;
+  int val;
 
-  if (comm_sd >= 0) {
-    int rc;
-    socklen_t len;
-
-    val = 0;
-    len = sizeof (val);
-    rc = getsockopt(comm_sd, SOL_SOCKET, SO_TYPE, &val, &len);
-
-    if (rc >= 0 && val == SOCK_STREAM) {
-      val = 0;
-      len = sizeof (val);
-      rc = getsockopt(comm_sd, SOL_SOCKET, SO_REUSEADDR, &val, &len);
-
-      if (rc >= 0 && val)
-        return;
-    }
-
-    fprintf(stderr, "libfakeroot: file descriptor %d was hijacked ", comm_sd);
-    if (rc < 0)
-      fprintf(stderr, "(getsockopt said \"%s\")\n", strerror(errno));
-    else
-      fprintf(stderr, "(socket options changed)\n");
-
-    comm_sd = -1;
-  }
-
-  base = getdtablesize() - 100;
-  if (base < 3)
-    base = 3;
-
-  if ((str = getenv(FD_BASE_ENV))) {
-    int fd = atoi(str);
-    if (fd >= 3)
-      base = fd;
-  }
+  if (comm_sd >= 0)
+    return;
 
   comm_sd = socket(PF_INET, SOCK_STREAM, 0);
   if (comm_sd < 0)
     fail("socket");
 
-  if (comm_sd < base) {
-    int fd;
-
-    do {
-      fd = fcntl(comm_sd, F_DUPFD, base);
-      if (fd < 0) {
-	if (errno == EINTR)
-	  continue;
-	fail("fcntl(F_DUPFD)");
-      }
-    } while (0);
-
-    close(comm_sd);
-    comm_sd = fd;
-  }
+  if (fcntl(comm_sd, F_SETFD, FD_CLOEXEC) < 0)
+    fail("fcntl(F_SETFD, FD_CLOEXEC)");
 
   val = 1;
   if (setsockopt(comm_sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof (val)) < 0)
@@ -344,16 +297,13 @@ static void open_comm_sd(void)
     fail("connect");
 }
 
-void close_comm_sd(void)
+void lock_comm_sd(void)
 {
-  /* We must synchronize since the vfork calls us in the parent process. */
   pthread_mutex_lock(&comm_sd_mutex);
+}
 
-  if (comm_sd >= 0) {
-    close(comm_sd);
-    comm_sd = -1;
-  }
-
+void unlock_comm_sd(void)
+{
   pthread_mutex_unlock(&comm_sd_mutex);
 }
 
@@ -467,12 +417,12 @@ static void send_fakem_nr(const struct fake_msg *buf)
 
 void send_fakem(const struct fake_msg *buf)
 {
-  pthread_mutex_lock(&comm_sd_mutex);
+  lock_comm_sd();
 
   open_comm_sd();
   send_fakem_nr(buf);
 
-  pthread_mutex_unlock(&comm_sd_mutex);
+  unlock_comm_sd();
 }
 
 static void get_fakem_nr(struct fake_msg *buf)
@@ -505,13 +455,13 @@ static void get_fakem_nr(struct fake_msg *buf)
 
 void send_get_fakem(struct fake_msg *buf)
 {
-  pthread_mutex_lock(&comm_sd_mutex);
+  lock_comm_sd();
 
   open_comm_sd();
   send_fakem_nr(buf);
   get_fakem_nr(buf);
 
-  pthread_mutex_unlock(&comm_sd_mutex);
+  unlock_comm_sd();
 }
 
 #endif /* FAKEROOT_FAKENET */
diff --git a/communicate.h b/communicate.h
index 44b4a78..0324c1d 100644
--- a/communicate.h
+++ b/communicate.h
@@ -129,7 +129,11 @@ extern int init_get_msg();
 extern key_t get_ipc_key();
 extern void cpyfakemstat(struct fake_msg *b1, const struct stat     *st);
 #else /* FAKEROOT_FAKENET */
-extern void close_comm_sd(void);
+# ifdef FAKEROOT_LIBFAKEROOT
+extern volatile int comm_sd;
+extern void lock_comm_sd(void);
+extern void unlock_comm_sd(void);
+# endif
 #endif /* FAKEROOT_FAKENET */
 
 #ifdef STAT64_SUPPORT  
diff --git a/libfakeroot.c b/libfakeroot.c
index ee137f1..7035890 100644
--- a/libfakeroot.c
+++ b/libfakeroot.c
@@ -19,6 +19,8 @@
 */
 #define _GNU_SOURCE 
 
+#define FAKEROOT_LIBFAKEROOT
+
 #include "config.h"
 #include "communicate.h"
 #include <stdlib.h>
@@ -899,8 +901,17 @@ pid_t fork(void)
 
   pid = next_fork();
 
-  if (pid == 0)
-    close_comm_sd();
+  if (pid == 0) {
+    int err = errno;
+
+    /* No need to lock in the child process. */
+    if (comm_sd >= 0) {
+      next_close(comm_sd);
+      comm_sd = -1;
+    }
+
+    errno = err;
+  }
 
   return pid;
 }
@@ -911,7 +922,50 @@ pid_t vfork(void)
   return fork();
 }
 
+/* Return an error when trying to close the comm_sd file descriptor
+   (pretend that it's closed). */
+int close(int fd)
+{
+  int retval, reterr;
+
+  lock_comm_sd();
+
+  if (comm_sd >= 0 && comm_sd == fd) {
+    retval = -1;
+    reterr = EBADF;
+  } else {
+    retval = next_close(fd);
+    reterr = errno;
+  }
+
+  unlock_comm_sd();
+
+  errno = reterr;
+  return retval;
+}
+
+int dup2(int oldfd, int newfd)
+{
+  int retval, reterr;
+
+  lock_comm_sd();
+
+  if (comm_sd >= 0 && comm_sd == newfd) {
+    /* If dup fails, comm_sd gets set to -1, which is fine. */
+    comm_sd = dup(newfd);
+    next_close(newfd);
+  }
+
+  retval = next_dup2(oldfd, newfd);
+  reterr = errno;
+
+  unlock_comm_sd();
+
+  errno = reterr;
+  return retval;
+}
 #endif /* FAKEROOT_FAKENET */
+
 uid_t getuid(void){
   if (fakeroot_disabled)
     return next_getuid();
diff --git a/wrapfunc.inp b/wrapfunc.inp
index 691ba66..04cebaf 100644
--- a/wrapfunc.inp
+++ b/wrapfunc.inp
@@ -53,6 +53,8 @@ rename;int;(const char *oldpath, const char *newpath);(oldpath, newpath)
 #ifdef FAKEROOT_FAKENET
 fork;pid_t;(void);()
 vfork;pid_t;(void);()
+close;int;(int fd);(fd)
+dup2;int;(int oldfd, int newfd);(oldfd, newfd)
 #endif /* FAKEROOT_FAKENET */
 
 /* for fakeroot */

-- 
fakeroot



More information about the Fakeroot-commits mailing list