amdxdna_drm_sync_bo_ioctl() forms the range for a device BO by adding the caller's offset and size to the BO address without checking either, while amdxdna_flush_bo() one call down guards the same arithmetic with check_add_overflow().
A size that wraps flush_end leaves it below the heap it is clamped against, so every heap fails the start >= end test, and a sync that asked for more than the address space holds reports success having flushed nothing. Reject it instead. Signed-off-by: Taimuraz Kaitmazov <[email protected]> --- drivers/accel/amdxdna/amdxdna_gem.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c index 7df4bbb16..d944f1b99 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.c +++ b/drivers/accel/amdxdna/amdxdna_gem.c @@ -1287,8 +1287,13 @@ int amdxdna_drm_sync_bo_ioctl(struct drm_device *dev, struct amdxdna_gem_obj *heap; unsigned long heap_id; u64 bo_start = amdxdna_gem_dev_addr(abo); - u64 flush_start = bo_start + args->offset; - u64 flush_end = flush_start + args->size; + u64 flush_start, flush_end; + + if (check_add_overflow(bo_start, args->offset, &flush_start) || + check_add_overflow(flush_start, args->size, &flush_end)) { + ret = -EINVAL; + goto put_obj; + } xa_for_each_range(&client->dev_heap_xa, heap_id, heap, abo->heap_start_id, abo->heap_end_id) { -- 2.55.0
