⬢ DragonFlyBSD Kernel Audit
DF-4968 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/drm/radeon/radeon_gart.c
+++ b/sys/dev/drm/radeon/radeon_gart.c
@@ -65,10 +65,30 @@
  * gart table to be in system memory.
  * Returns 0 for success, -ENOMEM for failure.
  */
+static int radeon_gart_table_size_ok(struct radeon_device *rdev)
+{
+	/* The table must be able to hold one entry (>= 4 bytes) per GPU page.
+	 * Both the per-asic table_size computation (num_gpu_pages * 4 or * 8,
+	 * 32-bit unsigned multiply) and the u32 num_gpu_pages field itself can
+	 * wrap for oversized GTT configurations - reject those here instead of
+	 * trusting the caller.
+	 */
+	if (rdev->gart.num_gpu_pages == 0 ||
+	    (uint64_t)rdev->gart.table_size / rdev->gart.num_gpu_pages < 4)
+		return 0;
+	return 1;
+}
+
 int radeon_gart_table_ram_alloc(struct radeon_device *rdev)
 {
 	void *ptr;
 
+	if (!radeon_gart_table_size_ok(rdev)) {
+		dev_err(rdev->dev, "GART table size %u too small for %u GPU pages\n",
+			rdev->gart.table_size, rdev->gart.num_gpu_pages);
+		return -EINVAL;
+	}
+
 	ptr = pci_alloc_consistent(rdev->pdev, rdev->gart.table_size,
 				   &rdev->gart.table_addr);
 	if (ptr == NULL) {
@@ -128,6 +148,12 @@
 {
 	int r;
 
+	if (!radeon_gart_table_size_ok(rdev)) {
+		dev_err(rdev->dev, "GART table size %u too small for %u GPU pages\n",
+			rdev->gart.table_size, rdev->gart.num_gpu_pages);
+		return -EINVAL;
+	}
+
 	if (rdev->gart.robj == NULL) {
 		r = radeon_bo_create(rdev, rdev->gart.table_size,
 				     PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,