Am 21.11.2016 um 07:21 schrieb Eric Auger:
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]>
---
 drivers/vfio/vfio.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c
index d1d70e0..1e838d1 100644
--- a/drivers/vfio/vfio.c
+++ b/drivers/vfio/vfio.c
@@ -1763,7 +1763,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 */


Looks sane to me, tmp->next is always set to the old size, which corresponds to the offset from the start of the buffer.

        tmp->next = caps->size;
@@ -1776,8 +1776,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;


Reviewed-by: David Hildenbrand <[email protected]>

--

David

Reply via email to