--- a/sys/dev/drm/radeon/evergreen_cs.c +++ b/sys/dev/drm/radeon/evergreen_cs.c @@ -3354,6 +3354,24 @@ switch (pkt->opcode) { case PACKET3_NOP: break; + case PACKET3_COND_WRITE: + if (pkt->count != 5) { + DRM_ERROR("bad COND_WRITE\n"); + return -EINVAL; + } + break; + case PACKET3_COPY_DW: + if (pkt->count != 4) { + DRM_ERROR("bad COPY_DW\n"); + return -EINVAL; + } + break; + case PACKET3_CP_DMA: + if (pkt->count != 4) { + DRM_ERROR("bad CP DMA\n"); + return -EINVAL; + } + break; case PACKET3_SET_BASE: if (idx_value != 1) { DRM_ERROR("bad SET_BASE"); @@ -3524,6 +3542,11 @@ do { pkt.idx = idx; + if (idx + 1 >= ib->length_dw) { + dev_err(rdev->dev, "IB packet at %d doesn't fit (%d)\n", + idx, ib->length_dw); + return -EINVAL; + } pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]); pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]); pkt.one_reg_wr = 0; @@ -3536,6 +3559,12 @@ idx += 1; break; case RADEON_PACKET_TYPE3: + if (pkt.idx + pkt.count + 2 > ib->length_dw) { + dev_err(rdev->dev, + "Packet (%d:%d:%d) end after IB buffer (%d) !\n", + pkt.idx, pkt.type, pkt.count, ib->length_dw); + return -EINVAL; + } pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]); ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); idx += pkt.count + 2;