--- si.c.orig 2026-09-15 05:59:44.826647602 +0000 +++ si.c.fix3592 2026-09-15 06:01:58.896946431 +0000 @@ -4569,6 +4569,11 @@ case PACKET3_ME_WRITE: break; case PACKET3_COPY_DATA: + if (pkt->count < 3) { + DRM_ERROR("Invalid COPY_DATA packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if ((idx_value & 0xf00) == 0) { reg = ib[idx + 3] * 4; if (!si_vm_reg_valid(reg)) @@ -4576,13 +4581,18 @@ } break; case PACKET3_WRITE_DATA: + if (pkt->count < 2) { + DRM_ERROR("Invalid WRITE_DATA packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if ((idx_value & 0xf00) == 0) { start_reg = ib[idx + 1] * 4; if (idx_value & 0x10000) { if (!si_vm_reg_valid(start_reg)) return -EINVAL; } else { - for (i = 0; i < (pkt->count - 2); i++) { + for (i = 0; i + 2 < pkt->count; i++) { reg = start_reg + (4 * i); if (!si_vm_reg_valid(reg)) return -EINVAL; @@ -4591,6 +4601,11 @@ } break; case PACKET3_COND_WRITE: + if (pkt->count < 5) { + DRM_ERROR("Invalid COND_WRITE packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if (idx_value & 0x100) { reg = ib[idx + 5] * 4; if (!si_vm_reg_valid(reg)) @@ -4598,6 +4613,11 @@ } break; case PACKET3_COPY_DW: + if (pkt->count < 3) { + DRM_ERROR("Invalid COPY_DW packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if (idx_value & 0x2) { reg = ib[idx + 3] * 4; if (!si_vm_reg_valid(reg)) @@ -4620,6 +4640,11 @@ } break; case PACKET3_CP_DMA: + if (pkt->count < 4) { + DRM_ERROR("Invalid CP_DMA packet3 count: %d\n", + pkt->count); + return -EINVAL; + } r = si_vm_packet3_cp_dma_check(ib, idx); if (r) return r; @@ -4672,6 +4697,11 @@ case PACKET3_ME_WRITE: break; case PACKET3_COPY_DATA: + if (pkt->count < 3) { + DRM_ERROR("Invalid COPY_DATA packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if ((idx_value & 0xf00) == 0) { reg = ib[idx + 3] * 4; if (!si_vm_reg_valid(reg)) @@ -4679,13 +4709,18 @@ } break; case PACKET3_WRITE_DATA: + if (pkt->count < 2) { + DRM_ERROR("Invalid WRITE_DATA packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if ((idx_value & 0xf00) == 0) { start_reg = ib[idx + 1] * 4; if (idx_value & 0x10000) { if (!si_vm_reg_valid(start_reg)) return -EINVAL; } else { - for (i = 0; i < (pkt->count - 2); i++) { + for (i = 0; i + 2 < pkt->count; i++) { reg = start_reg + (4 * i); if (!si_vm_reg_valid(reg)) return -EINVAL; @@ -4694,6 +4729,11 @@ } break; case PACKET3_COND_WRITE: + if (pkt->count < 5) { + DRM_ERROR("Invalid COND_WRITE packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if (idx_value & 0x100) { reg = ib[idx + 5] * 4; if (!si_vm_reg_valid(reg)) @@ -4701,6 +4741,11 @@ } break; case PACKET3_COPY_DW: + if (pkt->count < 3) { + DRM_ERROR("Invalid COPY_DW packet3 count: %d\n", + pkt->count); + return -EINVAL; + } if (idx_value & 0x2) { reg = ib[idx + 3] * 4; if (!si_vm_reg_valid(reg)) @@ -4708,6 +4753,11 @@ } break; case PACKET3_CP_DMA: + if (pkt->count < 4) { + DRM_ERROR("Invalid CP_DMA packet3 count: %d\n", + pkt->count); + return -EINVAL; + } r = si_vm_packet3_cp_dma_check(ib, idx); if (r) return r; @@ -4740,6 +4790,15 @@ break; case RADEON_PACKET_TYPE3: pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]); + /* the whole packet must fit within the IB + * (mirrors radeon_cs_packet_parse, radeon_cs.c:768) + */ + if (pkt.count + 2 > ib->length_dw - idx) { + dev_err(rdev->dev, "ib packet too big: idx %d count %d len %d\n", + idx, pkt.count, ib->length_dw); + ret = -EINVAL; + break; + } if (ib->is_const_ib) ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt); else {