XSA-38

CVE-2013-0215


问题描述

http://xenbits.xen.org/xsa/advisory-38.html

oxenstored incorrect handling of certain Xenbus ring states

The oxenstored daemon (the ocaml version of the xenstore daemon) does not correctly handle unusual or malicious contents in the xenstore ring. A malicious guest can exploit this to cause oxenstored to read past the end of the ring (and very likely crash) or to allocate large amounts of RAM.

improper error handling (overread)


Patch描述

http://xenbits.xen.org/xsa/xsa38.patch

--- a/tools/ocaml/libs/xb/partial.ml
+++ b/tools/ocaml/libs/xb/partial.ml
@@ -27,8 +27,15 @@ external header_size: unit -> int = "stub_header_size"
 external header_of_string_internal: string -> int * int * int * int
          = "stub_header_of_string"
 
+let xenstore_payload_max = 4096 (* xen/include/public/io/xs_wire.h *)
+
 let of_string s =
    let tid, rid, opint, dlen = header_of_string_internal s in
+   (* A packet which is bigger than xenstore_payload_max is illegal.
+      This will leave the guest connection is a bad state and will
+      be hard to recover from without restarting the connection
+      (ie rebooting the guest) *)
+   let dlen = min xenstore_payload_max dlen in
    {
        tid = tid;
        rid = rid;
@@ -38,6 +45,7 @@ let of_string s =
    }
 
 let append pkt s sz =
+   if pkt.len > 4096 then failwith "Buffer.add: cannot grow buffer";
    Buffer.add_string pkt.buf (String.sub s 0 sz)
 
 let to_complete pkt =
diff --git a/tools/ocaml/libs/xb/xs_ring_stubs.c b/tools/ocaml/libs/xb/xs_ring_stubs.c
index 00414c5..4888ac5 100644
--- a/tools/ocaml/libs/xb/xs_ring_stubs.c
+++ b/tools/ocaml/libs/xb/xs_ring_stubs.c
@@ -39,21 +39,23 @@ static int xs_ring_read(struct mmap_interface *interface,
                              char *buffer, int len)
 {
    struct xenstore_domain_interface *intf = interface->addr;
-   XENSTORE_RING_IDX cons, prod;
+   XENSTORE_RING_IDX cons, prod; /* offsets only */
    int to_read;
 
-   cons = intf->req_cons;
-   prod = intf->req_prod;
+   cons = *(volatile uint32*)&intf->req_cons;
+   prod = *(volatile uint32*)&intf->req_prod;
    xen_mb();
    if (prod == cons)
        return 0;
-   if (MASK_XENSTORE_IDX(prod) > MASK_XENSTORE_IDX(cons)) 
+   cons = MASK_XENSTORE_IDX(cons);
+   prod = MASK_XENSTORE_IDX(prod);
+   if (prod > cons)
        to_read = prod - cons;
    else
-       to_read = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons);
+       to_read = XENSTORE_RING_SIZE - cons;
    if (to_read < len)
        len = to_read;
-   memcpy(buffer, intf->req + MASK_XENSTORE_IDX(cons), len);
+   memcpy(buffer, intf->req + cons, len);
    xen_mb();
    intf->req_cons += len;
    return len;
@@ -66,8 +68,8 @@ static int xs_ring_write(struct mmap_interface *interface,
    XENSTORE_RING_IDX cons, prod;
    int can_write;
 
-   cons = intf->rsp_cons;
-   prod = intf->rsp_prod;
+   cons = *(volatile uint32*)&intf->rsp_cons;
+   prod = *(volatile uint32*)&intf->rsp_prod;
    xen_mb();
    if ( (prod - cons) >= XENSTORE_RING_SIZE )
        return 0;

Consequence

A malicious guest administrator can mount a denial of service attack affecting domain control and management functions.

In more detail:

DoS