Message ID | 5742C30902000078000ED9FC@prv-mh.provo.novell.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Mon, 23 May 2016, Jan Beulich wrote: > Commit f9e98e5d7a ("xen/blkif: Avoid double access to > src->nr_segments") didn't go far enough: src->operation is also being > used twice. And nothing was done to prevent the compiler from using the > source side of the copy done by blk_get_request() (granted that's very > unlikely). > > Move the barrier()s up, and add another one to blk_get_request(). > > Note that for completing XSA-155, the barrier() getting added to > blk_get_request() would suffice, and hence the changes to xen_blkif.h > are more like just cleanup. And since, as said, the unpatched code > getting compiled to something vulnerable is very unlikely (and not > observed in practice), this isn't being viewed as a new security issue. > > Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> Added to my queue > --- a/hw/block/xen_blkif.h > +++ b/hw/block/xen_blkif.h > @@ -79,14 +79,14 @@ static inline void blkif_get_x86_32_req( > dst->handle = src->handle; > dst->id = src->id; > dst->sector_number = src->sector_number; > - if (src->operation == BLKIF_OP_DISCARD) { > + /* Prevent the compiler from using src->... instead. */ > + barrier(); > + if (dst->operation == BLKIF_OP_DISCARD) { > struct blkif_request_discard *s = (void *)src; > struct blkif_request_discard *d = (void *)dst; > d->nr_sectors = s->nr_sectors; > return; > } > - /* prevent the compiler from optimizing the code and using src->nr_segments instead */ > - barrier(); > if (n > dst->nr_segments) > n = dst->nr_segments; > for (i = 0; i < n; i++) > @@ -102,14 +102,14 @@ static inline void blkif_get_x86_64_req( > dst->handle = src->handle; > dst->id = src->id; > dst->sector_number = src->sector_number; > - if (src->operation == BLKIF_OP_DISCARD) { > + /* Prevent the compiler from using src->... instead. */ > + barrier(); > + if (dst->operation == BLKIF_OP_DISCARD) { > struct blkif_request_discard *s = (void *)src; > struct blkif_request_discard *d = (void *)dst; > d->nr_sectors = s->nr_sectors; > return; > } > - /* prevent the compiler from optimizing the code and using src->nr_segments instead */ > - barrier(); > if (n > dst->nr_segments) > n = dst->nr_segments; > for (i = 0; i < n; i++) > --- a/hw/block/xen_disk.c > +++ b/hw/block/xen_disk.c > @@ -679,6 +679,8 @@ static int blk_get_request(struct XenBlk > RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc)); > break; > } > + /* Prevent the compiler from accessing the on-ring fields instead. */ > + barrier(); > return 0; > } > > > > >
--- a/hw/block/xen_blkif.h +++ b/hw/block/xen_blkif.h @@ -79,14 +79,14 @@ static inline void blkif_get_x86_32_req( dst->handle = src->handle; dst->id = src->id; dst->sector_number = src->sector_number; - if (src->operation == BLKIF_OP_DISCARD) { + /* Prevent the compiler from using src->... instead. */ + barrier(); + if (dst->operation == BLKIF_OP_DISCARD) { struct blkif_request_discard *s = (void *)src; struct blkif_request_discard *d = (void *)dst; d->nr_sectors = s->nr_sectors; return; } - /* prevent the compiler from optimizing the code and using src->nr_segments instead */ - barrier(); if (n > dst->nr_segments) n = dst->nr_segments; for (i = 0; i < n; i++) @@ -102,14 +102,14 @@ static inline void blkif_get_x86_64_req( dst->handle = src->handle; dst->id = src->id; dst->sector_number = src->sector_number; - if (src->operation == BLKIF_OP_DISCARD) { + /* Prevent the compiler from using src->... instead. */ + barrier(); + if (dst->operation == BLKIF_OP_DISCARD) { struct blkif_request_discard *s = (void *)src; struct blkif_request_discard *d = (void *)dst; d->nr_sectors = s->nr_sectors; return; } - /* prevent the compiler from optimizing the code and using src->nr_segments instead */ - barrier(); if (n > dst->nr_segments) n = dst->nr_segments; for (i = 0; i < n; i++) --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -679,6 +679,8 @@ static int blk_get_request(struct XenBlk RING_GET_REQUEST(&blkdev->rings.x86_64_part, rc)); break; } + /* Prevent the compiler from accessing the on-ring fields instead. */ + barrier(); return 0; }