The bug is here: lo = pstate->base.domain[domain->name]; The list iterator 'pstate' will point to a bogus position containing HEAD if the list is empty or no element is found. This case should be checked before any use of the iterator, otherwise it will lead to a invalid memory access. To fix this bug, add an check. Use a new value 'iter' as the list iterator, while use the old value 'pstate' as a dedicated variable to point to the found element. Cc: stable@xxxxxxxxxxxxxxx Fixes: 9838366c1597d ("drm/nouveau/device: initial control object class, with pstate control methods") Signed-off-by: Xiaomeng Tong <xiam0nd.tong@xxxxxxxxx> --- drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c index ce774579c89d..6b768635e8ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c @@ -72,7 +72,7 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void *data, u32 size) } *args = data; struct nvkm_clk *clk = ctrl->device->clk; const struct nvkm_domain *domain; - struct nvkm_pstate *pstate; + struct nvkm_pstate *pstate = NULL, *iter; struct nvkm_cstate *cstate; int i = 0, j = -1; u32 lo, hi; @@ -103,11 +103,16 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void *data, u32 size) return -EINVAL; if (args->v0.state != NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT) { - list_for_each_entry(pstate, &clk->states, head) { - if (i++ == args->v0.state) + list_for_each_entry(iter, &clk->states, head) { + if (i++ == args->v0.state) { + pstate = iter; break; + } } + if (!pstate) + return -EINVAL; + lo = pstate->base.domain[domain->name]; hi = lo; list_for_each_entry(cstate, &pstate->list, head) { -- 2.17.1