aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Auger <[email protected]>2016-11-21 07:21:02 +0100
committerAlex Williamson <[email protected]>2016-11-21 11:51:53 -0700
commit5ba6de98c78ac45166036516e34bec487887ba5d (patch)
treec7102457c64e098736aab3ca8a11c21b53a34116
parentf4cb410019388e450388ab001bb639b018558b71 (diff)
vfio: fix vfio_info_cap_add/shift
Capability header next field is an offset relative to the start of the INFO buffer. tmp->next is assigned the proper value but iterations implemented in vfio_info_cap_add and vfio_info_cap_shift use next as an offset between the headers. When coping with multiple capabilities this leads to an Oops. Signed-off-by: Eric Auger <[email protected]> Reviewed-by: David Hildenbrand <[email protected]> Signed-off-by: Alex Williamson <[email protected]>
-rw-r--r--drivers/vfio/vfio.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index c8150674787c..0aac3ca54a53 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1780,7 +1780,7 @@ struct vfio_info_cap_header *vfio_info_cap_add(struct vfio_info_cap *caps,
header->version = version;
/* Add to the end of the capability chain */
- for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next)
+ for (tmp = buf; tmp->next; tmp = buf + tmp->next)
; /* nothing */
tmp->next = caps->size;
@@ -1793,8 +1793,9 @@ EXPORT_SYMBOL_GPL(vfio_info_cap_add);
void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset)
{
struct vfio_info_cap_header *tmp;
+ void *buf = (void *)caps->buf;
- for (tmp = caps->buf; tmp->next; tmp = (void *)tmp + tmp->next - offset)
+ for (tmp = buf; tmp->next; tmp = buf + tmp->next - offset)
tmp->next += offset;
}
EXPORT_SYMBOL(vfio_info_cap_shift);