xen: fix ioreq handling
Avoid double fetches and bounds check size to avoid overflowing internal variables. This is CVE-2016-9381 / XSA-197. Reported-by: yanghongke <yanghongke@huawei.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
parent
a7764f1548
commit
b85f9dfdb1
16
xen-hvm.c
16
xen-hvm.c
@ -810,6 +810,10 @@ static void cpu_ioreq_pio(ioreq_t *req)
|
||||
trace_cpu_ioreq_pio(req, req->dir, req->df, req->data_is_ptr, req->addr,
|
||||
req->data, req->count, req->size);
|
||||
|
||||
if (req->size > sizeof(uint32_t)) {
|
||||
hw_error("PIO: bad size (%u)", req->size);
|
||||
}
|
||||
|
||||
if (req->dir == IOREQ_READ) {
|
||||
if (!req->data_is_ptr) {
|
||||
req->data = do_inp(req->addr, req->size);
|
||||
@ -846,6 +850,10 @@ static void cpu_ioreq_move(ioreq_t *req)
|
||||
trace_cpu_ioreq_move(req, req->dir, req->df, req->data_is_ptr, req->addr,
|
||||
req->data, req->count, req->size);
|
||||
|
||||
if (req->size > sizeof(req->data)) {
|
||||
hw_error("MMIO: bad size (%u)", req->size);
|
||||
}
|
||||
|
||||
if (!req->data_is_ptr) {
|
||||
if (req->dir == IOREQ_READ) {
|
||||
for (i = 0; i < req->count; i++) {
|
||||
@ -1010,11 +1018,13 @@ static int handle_buffered_iopage(XenIOState *state)
|
||||
req.df = 1;
|
||||
req.type = buf_req->type;
|
||||
req.data_is_ptr = 0;
|
||||
xen_rmb();
|
||||
qw = (req.size == 8);
|
||||
if (qw) {
|
||||
buf_req = &buf_page->buf_ioreq[(rdptr + 1) %
|
||||
IOREQ_BUFFER_SLOT_NUM];
|
||||
req.data |= ((uint64_t)buf_req->data) << 32;
|
||||
xen_rmb();
|
||||
}
|
||||
|
||||
handle_ioreq(state, &req);
|
||||
@ -1045,7 +1055,11 @@ static void cpu_handle_ioreq(void *opaque)
|
||||
|
||||
handle_buffered_iopage(state);
|
||||
if (req) {
|
||||
handle_ioreq(state, req);
|
||||
ioreq_t copy = *req;
|
||||
|
||||
xen_rmb();
|
||||
handle_ioreq(state, ©);
|
||||
req->data = copy.data;
|
||||
|
||||
if (req->state != STATE_IOREQ_INPROCESS) {
|
||||
fprintf(stderr, "Badness in I/O request ... not in service?!: "
|
||||
|
Loading…
Reference in New Issue
Block a user