|
|
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 |
|