aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/ocaml/libs/xb/xs_ring_stubs.c6
-rw-r--r--tools/ocaml/xenstored/connection.ml5
-rw-r--r--tools/ocaml/xenstored/domain.ml7
-rw-r--r--tools/ocaml/xenstored/process.ml12
-rw-r--r--tools/ocaml/xenstored/xenstored.ml7
5 files changed, 31 insertions, 6 deletions
diff --git a/tools/ocaml/libs/xb/xs_ring_stubs.c b/tools/ocaml/libs/xb/xs_ring_stubs.c
index fdd9983d1a..8bd1047490 100644
--- a/tools/ocaml/libs/xb/xs_ring_stubs.c
+++ b/tools/ocaml/libs/xb/xs_ring_stubs.c
@@ -45,6 +45,10 @@ static int xs_ring_read(struct mmap_interface *interface,
cons = *(volatile uint32*)&intf->req_cons;
prod = *(volatile uint32*)&intf->req_prod;
xen_mb();
+
+ if ((prod - cons) > XENSTORE_RING_SIZE)
+ return -1;
+
if (prod == cons)
return 0;
cons = MASK_XENSTORE_IDX(cons);
@@ -94,7 +98,7 @@ CAMLprim value ml_interface_read(value interface, value buffer, value len)
res = xs_ring_read(GET_C_STRUCT(interface),
String_val(buffer), Int_val(len));
if (res == -1)
- caml_failwith("huh");
+ caml_failwith("bad connection");
result = Val_int(res);
CAMLreturn(result);
}
diff --git a/tools/ocaml/xenstored/connection.ml b/tools/ocaml/xenstored/connection.ml
index 32e2f2e35d..273fe4dc11 100644
--- a/tools/ocaml/xenstored/connection.ml
+++ b/tools/ocaml/xenstored/connection.ml
@@ -38,6 +38,11 @@ and t = {
mutable perm: Perms.Connection.t;
}
+let mark_as_bad con =
+ match con.dom with
+ |None -> ()
+ | Some domain -> Domain.mark_as_bad domain
+
let get_path con =
Printf.sprintf "/local/domain/%i/" (match con.dom with None -> 0 | Some d -> Domain.get_id d)
diff --git a/tools/ocaml/xenstored/domain.ml b/tools/ocaml/xenstored/domain.ml
index c17f567a47..2c80f1387d 100644
--- a/tools/ocaml/xenstored/domain.ml
+++ b/tools/ocaml/xenstored/domain.ml
@@ -26,6 +26,7 @@ type t =
interface: Xenmmap.mmap_interface;
eventchn: Event.t;
mutable port: int;
+ mutable bad_client: bool;
}
let get_path dom = "/local/domain/" ^ (sprintf "%u" dom.id)
@@ -34,6 +35,9 @@ let get_interface d = d.interface
let get_mfn d = d.mfn
let get_remote_port d = d.remote_port
+let is_bad_domain domain = domain.bad_client
+let mark_as_bad domain = domain.bad_client <- true
+
let dump d chan =
fprintf chan "dom,%d,%nd,%d\n" d.id d.mfn d.port
@@ -56,7 +60,8 @@ let make id mfn remote_port interface eventchn = {
remote_port = remote_port;
interface = interface;
eventchn = eventchn;
- port = -1
+ port = -1;
+ bad_client = false
}
let is_dom0 d = d.id = 0
diff --git a/tools/ocaml/xenstored/process.ml b/tools/ocaml/xenstored/process.ml
index a4ff741264..89db56cd85 100644
--- a/tools/ocaml/xenstored/process.ml
+++ b/tools/ocaml/xenstored/process.ml
@@ -374,7 +374,17 @@ let write_answer_log ~ty ~tid ~con ~data =
Logging.xb_answer ~ty ~tid ~con:(Connection.get_domstr con) data
let do_input store cons doms con =
- if Connection.do_input con then (
+ let newpacket =
+ try
+ Connection.do_input con
+ with Failure exp ->
+ error "caught exception %s" exp;
+ error "got a bad client %s" (sprintf "%-8s" (Connection.get_domstr con));
+ Connection.mark_as_bad con;
+ false
+ in
+
+ if newpacket then (
let packet = Connection.pop_in con in
let tid, rid, ty, data = Xenbus.Xb.Packet.unpack packet in
(* As we don't log IO, do not call an unnecessary sanitize_data
diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml
index 64cc106461..2742e836b5 100644
--- a/tools/ocaml/xenstored/xenstored.ml
+++ b/tools/ocaml/xenstored/xenstored.ml
@@ -50,9 +50,10 @@ let process_connection_fds store cons domains rset wset =
let process_domains store cons domains =
let do_io_domain domain =
- let con = Connections.find_domain cons (Domain.get_id domain) in
- Process.do_input store cons domains con;
- Process.do_output store cons domains con in
+ if not (Domain.is_bad_domain domain) then
+ let con = Connections.find_domain cons (Domain.get_id domain) in
+ Process.do_input store cons domains con;
+ Process.do_output store cons domains con in
Domains.iter domains do_io_domain
let sigusr1_handler store =