diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 9fd83ea025..4322d3cf63 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -257,6 +257,8 @@ static void free_buffered_data(struct buffered_data *out, } } + domain_memory_add_nochk(conn->id, -out->hdr.msg.len - sizeof(out->hdr)); + if (out->hdr.msg.type == XS_WATCH_EVENT) { req = out->pend.req; if (req) { @@ -845,11 +847,14 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type, bdata->timeout_msec = 0; bdata->watch_event = false; - if (len <= DEFAULT_BUFFER_SIZE) + if (len <= DEFAULT_BUFFER_SIZE) { bdata->buffer = bdata->default_buffer; - else { + /* Don't check quota, path might be used for returning error. */ + domain_memory_add_nochk(conn->id, len + sizeof(bdata->hdr)); + } else { bdata->buffer = talloc_array(bdata, char, len); - if (!bdata->buffer) { + if (!bdata->buffer || + domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) { send_error(conn, ENOMEM); return; } @@ -914,6 +919,11 @@ void send_event(struct buffered_data *req, struct connection *conn, } } + if (domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) { + talloc_free(bdata); + return; + } + if (timeout_watch_event_msec && domain_is_unprivileged(conn)) { bdata->timeout_msec = get_now_msec() + timeout_watch_event_msec; if (!conn->timeout_msec)