vfio: fix vfio_info_cap_add/shift
authorEric Auger <eric.auger@redhat.com>
Mon, 21 Nov 2016 06:21:02 +0000 (07:21 +0100)
committerAlex Williamson <alex.williamson@redhat.com>
Mon, 21 Nov 2016 18:51:53 +0000 (11:51 -0700)
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 <eric.auger@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
drivers/vfio/vfio.c

index c8150674787cb495f9b07ac9c3b1d01561ce8a70..0aac3ca54a536ad44cf7005b4cf0840c9694285e 100644 (file)
@@ -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);