misc: mic: fix possible signed underflow (undefined behavior) in userspace API
authorSudeep Dutt <sudeep.dutt@intel.com>
Mon, 3 Feb 2014 22:53:19 +0000 (14:53 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Feb 2014 23:30:34 +0000 (15:30 -0800)
iovcnt is declared as a signed integer in both the userspace API and
as a local variable in mic_virtio.c. The while() loop in mic_virtio.c
iterates until the local variable iovcnt reaches the value 0. If
userspace passes e.g. INT_MIN as iovcnt field, this loop then appears
to depend on an undefined behavior (signed underflow) to complete.
The fix is to use unsigned integers in both the userspace API and
the local variable.

This issue was reported @ https://lkml.org/lkml/2014/1/10/10

Reported-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Reviewed-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Signed-off-by: Sudeep Dutt <sudeep.dutt@intel.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mic/host/mic_virtio.c
include/uapi/linux/mic_ioctl.h

index 752ff873f891bb3dc502305506f3f782ede28296..7e1ef0ebbb800bfcf00d7d07aaff02f7a5af7b4a 100644 (file)
@@ -156,7 +156,8 @@ static int mic_vringh_copy(struct mic_vdev *mvdev, struct vringh_kiov *iov,
 static int _mic_virtio_copy(struct mic_vdev *mvdev,
        struct mic_copy_desc *copy)
 {
-       int ret = 0, iovcnt = copy->iovcnt;
+       int ret = 0;
+       u32 iovcnt = copy->iovcnt;
        struct iovec iov;
        struct iovec __user *u_iov = copy->iov;
        void __user *ubuf = NULL;
index 7fabba5059cf6c362e67093b9ee37ffc4d188276..feb0b4c0814c0ff3ec93318612300d260fdf8442 100644 (file)
@@ -39,7 +39,7 @@ struct mic_copy_desc {
 #else
        struct iovec *iov;
 #endif
-       int iovcnt;
+       __u32 iovcnt;
        __u8 vr_idx;
        __u8 update_used;
        __u32 out_len;