[prev in list] [next in list] [prev in thread] [next in thread] 

List:       oss-security
Subject:    [oss-security] Xen Security Advisory 72 (CVE-2013-4416) - ocaml xenstored mishandles oversized messa
From:       Xen.org security team <security () xen ! org>
Date:       2013-10-29 15:39:10
Message-ID: E1VbBNu-0001Jl-G5 () xenbits ! xen ! org
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

             Xen Security Advisory CVE-2013-4416 / XSA-72
                             version 3

         ocaml xenstored mishandles oversized message replies

UPDATES IN VERSION 3
====================

Public release.

ISSUE DESCRIPTION
=================

The Ocaml xenstored implementation ("oxenstored") cannot correctly handle
a message reply larger than XENSTORE_PAYLOAD_SIZE when communicating
with a client domain via the shared ring mechanism.

When this situation occurs the connection to the client domain will be
shutdown and cannot be restarted leading to a denial of service to
that domain.

Clients in the same domain as xenstored which are using the Unix
domain socket mechanism are not vulnerable.

IMPACT
======

A malicious domain can create a directory containing a large number of
entries in the hopes that a victim domain will attempt to list the
contents of that directory. If this happens then the victim domain's
xenstore connection will be shutdown leading to a denial of service
against that domain.

If the victim domain is a toolstack or control domain then this can
lead to a denial of service against the whole system.

VULNERABLE SYSTEMS
==================

All systems using oxenstored are potentially vulnerable.

oxenstored was added in Xen 4.1.0. From Xen 4.2.0 onward it is used by
default if an ocaml toolstack was present at build time.

In its default configuration the C xenstored implementation is not
vulnerable.  By default this implementation imposes a quota on the
maximum directory size which is less than XENSTORE_PAYLOAD_SIZE.  If
you have adjusted the quota using the --entry-size / -S option to a
value larger than XENSTORE_PAYLOAD_SIZE (4096 bytes) then you may be
vulnerable.

Systems where the toolstack and oxenstored live in the same domain
will default to using Unix domain socket based communications and
therefore are not vulnerable to the host wide denial of service by
default.  In such a configuration guest domains which do not list
xenstore paths belonging to untrusted foreign domains will not be
vulnerable to the DoS.  (In the common case guests will not have
permission to do so in any case.)

MITIGATION
==========

Switching to the C xenstored (in its default configuration), will
eliminate this vulnerability.

CREDITS
=======

This issue was discovered by Thomas Sanders at Citrix.

RESOLUTION
==========

Applying the appropriate attached patch resolves both the ocaml xenstore and C
xenstore issues.

xsa72.patch        xen-unstable, Xen 4.3.x, Xen 4.2.x

$ sha256sum xsa72*.patch
66e11513fc512173140f3ca12568f8ef79415e9a7884254a700991b3f1afd125  xsa72.patch
$
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (GNU/Linux)

iQEcBAEBAgAGBQJSb9aMAAoJEIP+FMlX6CvZU6MH/2Racg6r+JLka2jqPO3X+BCh
+Dvkp2s85lQ/i7lUDq7V/1Badc+GpqCAoysgjh0bMSyXpPwaz3N+JhcgSEzWbXoU
IlQQUWGA86jO7x0g1HBIfvmf6o+ALWKkoyLiOZ3ZgpibO/vkl+8qU6yiD+r0XDaM
TTcsuRrosw6wbVsPkL7wGpTsQD1JA/FSKd7BpsQRMjxUeMtTeBtPN1o+zsvGf7he
A8MYe55XXYZbHv/S9yuBCHXtCU+QRtuGJGODIPACOqsaqWETIf013sxCORAmqg3x
bNEm3R0EJl3pO8Hdd2kTzIjRHgLn9LEKTIQU4+IYj0jOqXsMYjalFIL2RFC2lzI=
=vgDt
-----END PGP SIGNATURE-----

["xsa72.patch" (application/octet-stream)]

tools: xenstored: if the reply is too big then send E2BIG error

This fixes the issue for both C and ocaml xenstored, however only the ocaml
xenstored is vulnerable in its default configuration.

Adding a new error appears to be safe, since bit libxenstore and the Linux
driver at least treat an unknown error code as EINVAL.

This is XSA-72

Original ocaml patch by Jerome Maloberti <jerome.maloberti@citrix.com>
Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Signed-off-by: Thomas Sanders <thomas.sanders@citrix.com>

diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 273fe4d..47695f8 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -18,6 +18,8 @@ exception End_of_file
 
 open Stdext
 
+let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+
 type watch = {
 	con: t;
 	token: string;
@@ -112,8 +114,15 @@ let restrict con domid =
 let set_target con target_domid =
 	con.perm <- Perms.Connection.set_target (get_perm con) ~perms:[Perms.READ; Perms.WRITE] target_domid
 
+let is_backend_mmap con = match con.xb.Xenbus.Xb.backend with
+	| Xenbus.Xb.Xenmmap _ -> true
+	| _ -> false
+
 let send_reply con tid rid ty data =
-	Xenbus.Xb.queue con.xb (Xenbus.Xb.Packet.create tid rid ty data)
+	if (String.length data) > xenstore_payload_max && (is_backend_mmap con) then
+		Xenbus.Xb.queue con.xb (Xenbus.Xb.Packet.create tid rid Xenbus.Xb.Op.Error "E2BIG\000")
+	else
+		Xenbus.Xb.queue con.xb (Xenbus.Xb.Packet.create tid rid ty data)
 
 let send_error con tid rid err = send_reply con tid rid Xenbus.Xb.Op.Error (err ^ "\000")
 let send_ack con tid rid ty = send_reply con tid rid ty "OK\000"
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 0f8ba64..ccfdaa3 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -629,6 +629,11 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
 {
 	struct buffered_data *bdata;
 
+	if ( len > XENSTORE_PAYLOAD_MAX ) {
+		send_error(conn, E2BIG);
+		return;
+	}
+
 	/* Message is a child of the connection context for auto-cleanup. */
 	bdata = new_buffer(conn);
 	bdata->buffer = talloc_array(bdata, char, len);
diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h
index 99d24e3..585f0c8 100644
--- a/xen/include/public/io/xs_wire.h
+++ b/xen/include/public/io/xs_wire.h
@@ -83,7 +83,8 @@ __attribute__((unused))
     XSD_ERROR(EROFS),
     XSD_ERROR(EBUSY),
     XSD_ERROR(EAGAIN),
-    XSD_ERROR(EISCONN)
+    XSD_ERROR(EISCONN),
+    XSD_ERROR(E2BIG)
 };
 #endif
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic