Kernel: Fix buffer overflow in VirtIOGPU create_3d_resource(..)

This code attempts to copy the `Protocol::Resource3DSpecification`
struct into request, starting at `Protocol::ResourceCreate3D::target`
member of the `Protocol::ResourceCreate3D` struct.

The problem is that the `Protocol::Resource3DSpecification` struct
does not having the trailing `u32 padding` that the `ResourceCreate3D`
struct has. Leading to memcopy overrunning the struct and corrupting
32 bits of data trailing the struct.

Found by SonarCloud:
 - Memory copy function overflows the destination buffer.
This commit is contained in:
Brian Gianforcaro 2022-03-13 20:07:31 -07:00 committed by Andreas Kling
parent af50895fa3
commit c0ed656c94
Notes: sideshowbarker 2024-07-17 17:26:07 +09:00
3 changed files with 7 additions and 2 deletions

View file

@ -114,7 +114,8 @@ ErrorOr<void> GPU3DDevice::ioctl(OpenFileDescription& description, unsigned requ
.array_size = spec.array_size, .array_size = spec.array_size,
.last_level = spec.last_level, .last_level = spec.last_level,
.nr_samples = spec.nr_samples, .nr_samples = spec.nr_samples,
.flags = spec.flags .flags = spec.flags,
.padding = 0,
}; };
MutexLocker locker(m_graphics_adapter.operation_lock()); MutexLocker locker(m_graphics_adapter.operation_lock());
auto resource_id = m_graphics_adapter.create_3d_resource(resource_spec).value(); auto resource_id = m_graphics_adapter.create_3d_resource(resource_spec).value();

View file

@ -284,7 +284,10 @@ ResourceID GraphicsAdapter::create_3d_resource(Protocol::Resource3DSpecification
request.resource_id = resource_id.value(); request.resource_id = resource_id.value();
// TODO: Abstract this out a bit more // TODO: Abstract this out a bit more
u32* start_of_copied_fields = &request.target; u32* start_of_copied_fields = &request.target;
memcpy(start_of_copied_fields, &resource_3d_specification, sizeof(Protocol::Resource3DSpecification));
// Validate that the sub copy from the resource_3d_specification to the offset of the request fits.
static_assert((sizeof(request) - offsetof(Protocol::ResourceCreate3D, target) == sizeof(resource_3d_specification)));
memcpy(start_of_copied_fields, &resource_3d_specification, sizeof(resource_3d_specification));
synchronous_virtio_gpu_command(start_of_scratch_space(), sizeof(request), sizeof(response)); synchronous_virtio_gpu_command(start_of_scratch_space(), sizeof(request), sizeof(response));

View file

@ -328,6 +328,7 @@ struct Resource3DSpecification {
u32 last_level; u32 last_level;
u32 nr_samples; u32 nr_samples;
u32 flags; u32 flags;
u32 padding;
}; };
} }