]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
vhost: detect 32 bit integer wrap around
authorMichael S. Tsirkin <mst@redhat.com>
Mon, 1 Aug 2016 20:20:53 +0000 (23:20 +0300)
committerMichael S. Tsirkin <mst@redhat.com>
Tue, 2 Aug 2016 13:54:28 +0000 (16:54 +0300)
Detect and fail early if long wrap around is triggered.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
drivers/vhost/vhost.c

index d02c1614921f95c329f8f363c560c6661552bf59..c6f2d89c0e97cd4c184e615be6e3d86aca722a0d 100644 (file)
@@ -657,6 +657,12 @@ static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz)
                         (sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8);
 }
 
+static bool vhost_overflow(u64 uaddr, u64 size)
+{
+       /* Make sure 64 bit math will not overflow. */
+       return uaddr > ULONG_MAX || size > ULONG_MAX || uaddr > ULONG_MAX - size;
+}
+
 /* Caller should have vq mutex and device mutex. */
 static int vq_memory_access_ok(void __user *log_base, struct vhost_umem *umem,
                               int log_all)
@@ -669,9 +675,11 @@ static int vq_memory_access_ok(void __user *log_base, struct vhost_umem *umem,
        list_for_each_entry(node, &umem->umem_list, link) {
                unsigned long a = node->userspace_addr;
 
-               if (node->size > ULONG_MAX)
+               if (vhost_overflow(node->userspace_addr, node->size))
                        return 0;
-               else if (!access_ok(VERIFY_WRITE, (void __user *)a,
+
+
+               if (!access_ok(VERIFY_WRITE, (void __user *)a,
                                    node->size))
                        return 0;
                else if (log_all && !log_access_ok(log_base,
@@ -913,6 +921,10 @@ static int umem_access_ok(u64 uaddr, u64 size, int access)
 {
        unsigned long a = uaddr;
 
+       /* Make sure 64 bit math will not overflow. */
+       if (vhost_overflow(uaddr, size))
+               return -EFAULT;
+
        if ((access & VHOST_ACCESS_RO) &&
            !access_ok(VERIFY_READ, (void __user *)a, size))
                return -EFAULT;