In the vfio_ccw_async_region_write/vfio_ccw_async_region_read function of drivers/s390/cio/vfio_ccw_async.c, parameter "size_t count" is pass by userland, if "count" is very large, it will bypass "if (pos + count > sizeof(*region))".(such as count=0xffffffff). Then it will lead to buffer overflow in "copy_from_user((void *)region + pos, buf, count)". diff --git a/vfio_ccw_async.c_org b/vfio_ccw_async.c index 7a838e3..33339ad 100644 --- a/vfio_ccw_async.c_org +++ b/vfio_ccw_async.c @@ -21,7 +21,7 @@ static ssize_t vfio_ccw_async_region_read(struct vfio_ccw_private *private, struct ccw_cmd_region *region; int ret; - if (pos + count > sizeof(*region)) + if (pos + count > sizeof(*region) && pos + count > pos) return -EINVAL; mutex_lock(&private->io_mutex); @@ -43,7 +43,7 @@ static ssize_t vfio_ccw_async_region_write(struct vfio_ccw_private *private, struct ccw_cmd_region *region; int ret; - if (pos + count > sizeof(*region)) + if (pos + count > sizeof(*region) && pos + count > pos) return -EINVAL; if (!mutex_trylock(&private->io_mutex))