Blame SOURCES/0033-fish-CVE-2013-4419-Fix-insecure-temporary-directory-.patch

022f11
From d572bdf341bccafe55367335b0fe1c83553e6993 Mon Sep 17 00:00:00 2001
022f11
From: "Richard W.M. Jones" <rjones@redhat.com>
022f11
Date: Wed, 9 Oct 2013 12:08:10 +0100
022f11
Subject: [PATCH] fish: CVE-2013-4419: Fix insecure temporary directory
022f11
 handling for remote guestfish (RHBZ#1016960).
022f11
022f11
When using the guestfish --remote or guestfish --listen options,
022f11
guestfish would create a socket in a known location
022f11
(/tmp/.guestfish-$UID/socket-$PID).
022f11
022f11
The location has to be a known one in order for both ends to
022f11
communicate.  However no checking was done that the containing
022f11
directory (/tmp/.guestfish-$UID) is owned by the user.  Thus another
022f11
user could create this directory and potentially modify sockets owned
022f11
by another user's guestfish client or server.
022f11
022f11
This commit fixes the issue by creating the directory unconditionally,
022f11
and then checking that the directory has the correct owner and
022f11
permissions, thus preventing another user from creating the directory
022f11
first.
022f11
022f11
If guestfish sees a suspicious socket directory it will print an error
022f11
like this and exit with an error status:
022f11
022f11
  guestfish: '/tmp/.guestfish-1000' is not a directory or has insecure owner or permissions
022f11
022f11
Thanks: Michael Scherer for discovering this issue.
022f11
022f11
Version 2:
022f11
 - Add assigned CVE number.
022f11
 - Update documentation.
022f11
022f11
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
022f11
---
022f11
 fish/guestfish.pod |  3 +++
022f11
 fish/rc.c          | 43 +++++++++++++++++++++++++++++++++++++++----
022f11
 src/guestfs.pod    | 17 +++++++++++++++++
022f11
 3 files changed, 59 insertions(+), 4 deletions(-)
022f11
022f11
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
022f11
index 06663ac..2ecc058 100644
022f11
--- a/fish/guestfish.pod
022f11
+++ b/fish/guestfish.pod
022f11
@@ -1006,6 +1006,9 @@ user ID of the process, and C<$PID> is the process ID of the server.
022f11
 
022f11
 Guestfish client and server versions must match exactly.
022f11
 
022f11
+Older versions of guestfish were vulnerable to CVE-2013-4419 (see
022f11
+L<guestfs(3)/CVE-2013-4419>).  This is fixed in the current version.
022f11
+
022f11
 =head2 USING REMOTE CONTROL ROBUSTLY FROM SHELL SCRIPTS
022f11
 
022f11
 From Bash, you can use the following code which creates a guestfish
022f11
diff --git a/fish/rc.c b/fish/rc.c
022f11
index aa4b849..c736042 100644
022f11
--- a/fish/rc.c
022f11
+++ b/fish/rc.c
022f11
@@ -29,6 +29,7 @@
022f11
 #include <sys/un.h>
022f11
 #include <signal.h>
022f11
 #include <sys/socket.h>
022f11
+#include <errno.h>
022f11
 
022f11
 #include <rpc/types.h>
022f11
 #include <rpc/xdr.h>
022f11
@@ -38,17 +39,49 @@
022f11
 #include "fish.h"
022f11
 #include "rc_protocol.h"
022f11
 
022f11
+/* Because this is a Unix domain socket, the total path length must be
022f11
+ * under 108 bytes.
022f11
+ */
022f11
+#define SOCKET_DIR "/tmp/.guestfish-%d" /* euid */
022f11
+#define SOCKET_PATH "/tmp/.guestfish-%d/socket-%d" /* euid, pid */
022f11
+
022f11
+static void
022f11
+create_sockdir (void)
022f11
+{
022f11
+  uid_t euid = geteuid ();
022f11
+  char dir[128];
022f11
+  int r;
022f11
+  struct stat statbuf;
022f11
+
022f11
+  /* Create the directory, and ensure it is owned by the user. */
022f11
+  snprintf (dir, sizeof dir, SOCKET_DIR, euid);
022f11
+  r = mkdir (dir, 0700);
022f11
+  if (r == -1 && errno != EEXIST) {
022f11
+  error:
022f11
+    perror (dir);
022f11
+    exit (EXIT_FAILURE);
022f11
+  }
022f11
+  if (lstat (dir, &statbuf) == -1)
022f11
+    goto error;
022f11
+  if (!S_ISDIR (statbuf.st_mode) ||
022f11
+      (statbuf.st_mode & 0777) != 0700 ||
022f11
+      statbuf.st_uid != euid) {
022f11
+    fprintf (stderr,
022f11
+             _("guestfish: '%s' is not a directory or has insecure owner or permissions\n"),
022f11
+             dir);
022f11
+    exit (EXIT_FAILURE);
022f11
+  }
022f11
+}
022f11
+
022f11
 static void
022f11
 create_sockpath (pid_t pid, char *sockpath, size_t len,
022f11
                  struct sockaddr_un *addr)
022f11
 {
022f11
-  char dir[128];
022f11
   uid_t euid = geteuid ();
022f11
 
022f11
-  snprintf (dir, sizeof dir, "/tmp/.guestfish-%d", euid);
022f11
-  ignore_value (mkdir (dir, 0700));
022f11
+  create_sockdir ();
022f11
 
022f11
-  snprintf (sockpath, len, "/tmp/.guestfish-%d/socket-%d", euid, pid);
022f11
+  snprintf (sockpath, len, SOCKET_PATH, euid, pid);
022f11
 
022f11
   addr->sun_family = AF_UNIX;
022f11
   strcpy (addr->sun_path, sockpath);
022f11
@@ -196,6 +229,8 @@ rc_listen (void)
022f11
   memset (&hello, 0, sizeof hello);
022f11
   memset (&call, 0, sizeof call);
022f11
 
022f11
+  create_sockdir ();
022f11
+
022f11
   pid = fork ();
022f11
   if (pid == -1) {
022f11
     perror ("fork");
022f11
diff --git a/src/guestfs.pod b/src/guestfs.pod
022f11
index 0c57f50..eedea94 100644
022f11
--- a/src/guestfs.pod
022f11
+++ b/src/guestfs.pod
022f11
@@ -1998,6 +1998,23 @@ double-free in the C library (denial of service).
022f11
 It is sufficient to update libguestfs to a version that is not
022f11
 vulnerable: libguestfs E<ge> 1.20.8, E<ge> 1.22.2 or E<ge> 1.23.2.
022f11
 
022f11
+=head2 CVE-2013-4419
022f11
+
022f11
+L<https://bugzilla.redhat.com/1016960>
022f11
+
022f11
+When using the L<guestfish(1)> I<--remote> or guestfish I<--listen>
022f11
+options, guestfish would create a socket in a known location
022f11
+(C</tmp/.guestfish-$UID/socket-$PID>).
022f11
+
022f11
+The location has to be a known one in order for both ends to
022f11
+communicate.  However no checking was done that the containing
022f11
+directory (C</tmp/.guestfish-$UID>) is owned by the user.  Thus
022f11
+another user could create this directory and potentially hijack
022f11
+sockets owned by another user's guestfish client or server.
022f11
+
022f11
+It is sufficient to update libguestfs to a version that is not
022f11
+vulnerable: libguestfs E<ge> 1.20.12, E<ge> 1.22.7 or E<ge> 1.24.
022f11
+
022f11
 =head1 CONNECTION MANAGEMENT
022f11
 
022f11
 =head2 guestfs_h *
022f11
-- 
022f11
1.8.3.1
022f11