DF-5778 / fix.diff
diff --git a/sys/dev/drm/amd/display/dc/irq/irq_service.c b/sys/dev/drm/amd/display/dc/irq/irq_service.c index 000000000000..000000000000 100644 --- a/sys/dev/drm/amd/display/dc/irq/irq_service.c +++ b/sys/dev/drm/amd/display/dc/irq/irq_service.c @@ -162,6 +162,11 @@ bool dal_irq_service_ack( enum dc_irq_source dal_irq_service_to_irq_source( struct irq_service *irq_service, uint32_t src_id, uint32_t ext_id) { + if (!irq_service || !irq_service->funcs || + !irq_service->funcs->to_dal_irq_source) + return DC_IRQ_SOURCE_INVALID; + return irq_service->funcs->to_dal_irq_source( irq_service, src_id, diff --git a/sys/dev/drm/amd/display/dc/core/dc.c b/sys/dev/drm/amd/display/dc/core/dc.c index 000000000000..000000000000 100644 --- a/sys/dev/drm/amd/display/dc/core/dc.c +++ b/sys/dev/drm/amd/display/dc/core/dc.c @@ -1672,12 +1672,22 @@ uint8_t dc_get_current_stream_count(struct dc *dc) enum dc_irq_source dc_interrupt_to_irq_source( struct dc *dc, uint32_t src_id, uint32_t ext_id) { + if (dc == NULL || dc->res_pool == NULL || dc->res_pool->irqs == NULL) + return DC_IRQ_SOURCE_INVALID; + return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); } bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) { if (dc == NULL) return false; return dal_irq_service_set(dc->res_pool->irqs, src, enable); } void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) { + if (dc == NULL || dc->res_pool == NULL || dc->res_pool->irqs == NULL) + return; + dal_irq_service_ack(dc->res_pool->irqs, src); } -- 2.11.0 DF-5778: dal_irq_service_to_irq_source() double-dereferences irq_service->funcs->to_dal_irq_source with no validation, unlike every sibling entry point in the same file (set/ack validate via find_irq_source_info; construct/destroy validate their handles), and unlike dc_interrupt_set() in the wrappers. dal_irq_service_construct()'s void failure is also swallowed by the family constructors (they wire info/funcs unconditionally), so a half-initialised service would carry NULL ctx/funcs into this path. No in-tree caller can produce the NULL object today (all 8 resource create-sites NULL-check irqs; dc->ctx is alloc-checked before pool creation), so this is defense-in-depth: guard the deref and mirror dc_interrupt_set's NULL check in the two wrappers that lack it. Returning DC_IRQ_SOURCE_INVALID is the established safe answer (the INVALID table slot is a dummy entry that logs and fails). Note: index/hash lines are placeholders (audit tree is read-only; diff authored for review, validated by context, not applied). |