--- a/sys/dev/drm/radeon/radeon_acpi.c +++ b/sys/dev/drm/radeon/radeon_acpi.c @@ -206,16 +206,28 @@ info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); if (!info) return -EIO; + if (info->Type != ACPI_TYPE_BUFFER || info->Buffer.Pointer == NULL || + info->Buffer.Length < 2) { + DRM_INFO("ATIF returned an invalid object (type %u, length %u)\n", + info->Type, info->Buffer.Length); + AcpiOsFree(info); + return -EINVAL; + } memset(&output, 0, sizeof(output)); size = *(u16 *) info->Buffer.Pointer; - if (size < 12) { + if (size < 12 || info->Buffer.Length < size) { DRM_INFO("ATIF buffer is too small: %zu\n", size); err = -EINVAL; goto out; } size = min(sizeof(output), size); + if (info->Buffer.Length < size) { + DRM_INFO("ATCS buffer is truncated\n"); + err = -EINVAL; + goto out; + } memcpy(&output, info->Buffer.Pointer, size); @@ -255,6 +267,13 @@ err = -EIO; goto out; } + if (info->Type != ACPI_TYPE_BUFFER || info->Buffer.Pointer == NULL || + info->Buffer.Length < 2) { + DRM_INFO("ATIF returned an invalid object (type %u, length %u)\n", + info->Type, info->Buffer.Length); + err = -EINVAL; + goto out; + } size = *(u16 *) info->Buffer.Pointer; if (size < 10) { @@ -264,6 +283,11 @@ memset(¶ms, 0, sizeof(params)); size = min(sizeof(params), size); + if (info->Buffer.Length < size) { + DRM_INFO("ATIF system params buffer is truncated\n"); + err = -EINVAL; + goto out; + } memcpy(¶ms, info->Buffer.Pointer, size); DRM_DEBUG_DRIVER("SYSTEM_PARAMS: mask = %#x, flags = %#x\n", @@ -314,6 +338,13 @@ info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); if (!info) return -EIO; + if (info->Type != ACPI_TYPE_BUFFER || info->Buffer.Pointer == NULL || + info->Buffer.Length < 2) { + DRM_INFO("ATIF returned an invalid object (type %u, length %u)\n", + info->Type, info->Buffer.Length); + AcpiOsFree(info); + return -EINVAL; + } size = *(u16 *)info->Buffer.Pointer; if (size < 0xd) { @@ -323,6 +354,11 @@ memset(req, 0, sizeof(*req)); size = min(sizeof(*req), size); + if (info->Buffer.Length < size) { + DRM_INFO("ATIF sbios requests buffer is truncated\n"); + count = -EINVAL; + goto out; + } memcpy(req, info->Buffer.Pointer, size); DRM_DEBUG_DRIVER("SBIOS pending requests: %#x\n", req->pending); @@ -488,11 +524,18 @@ info = radeon_atcs_call(handle, ATCS_FUNCTION_VERIFY_INTERFACE, NULL); if (!info) return -EIO; + if (info->Type != ACPI_TYPE_BUFFER || info->Buffer.Pointer == NULL || + info->Buffer.Length < 2) { + DRM_INFO("ATCS returned an invalid object (type %u, length %u)\n", + info->Type, info->Buffer.Length); + AcpiOsFree(info); + return -EINVAL; + } memset(&output, 0, sizeof(output)); size = *(u16 *) info->Buffer.Pointer; - if (size < 8) { + if (size < 8 || info->Buffer.Length < size) { DRM_INFO("ATCS buffer is too small: %zu\n", size); err = -EINVAL; goto out;