⬢ DragonFlyBSD Kernel Audit
DF-4636 / fix.diff
← back to finding ↓ download raw
--- 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(&params, 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(&params, 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;