oxenstored: Protect oxenstored from malicious domains.

add check logic when read from IO ring, and if error happens,
then mark the reading connection as "bad", Unless vm reboot,
oxenstored will not handle message from this connection any more.

xs_ring_stubs.c: add a more strict check on ring reading
connection.ml, domain.ml: add getter and setter for bad flag
process.ml: if exception raised when reading from domain's ring,
            mark this domain as "bad"
xenstored.ml: if a domain is marked as "bad", do not handle it.

Signed-off-by: John Liu <john.liuqiming@huawei.com>
Acked-by: David Scott <dave.scott@eu.citrix.com>
(cherry picked from commit 704302ce94)
(cherry picked from commit a978634bee)

Conflicts:
	tools/ocaml/xenstored/domain.ml

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
(cherry picked from commit 9f93027afd)
This commit is contained in:
Ian Jackson authored and Ian Jackson committed 2013-09-03 12:03:39 +01:00
1 parent 5b06843aa7
commit 070ab4c505
5 files changed
+31 -6

No files matched your search

+5 -1
View File
@@ -49,6 +49,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);
@@ -98,7 +102,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);
}
+5
View File
@@ -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)
+6 -1
View File
@@ -26,6 +26,7 @@ type t =
interface: Mmap.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
+11 -1
View File
@@ -368,7 +368,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 = Xb.Packet.unpack packet in
(* As we don't log IO, do not call an unnecessary sanitize_data
+4 -3
View File
@@ -49,9 +49,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 =
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.