Merge tag 'drm-intel-fixes-2026-07-02' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-fixes

- Input validation fixes for BIOS and EDID (Jani)
- Fix HDCP code buffer overflow and seq_num_v monotonic increase check (Jani)
- Fix near-NULL deref in i915_active during GFP_ATOMIC exhaustion (Joonas)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patch.msgid.link/akYLxDea3kEyHqJA@jlahtine-mobl
This commit is contained in:
Dave Airlie 2026-07-03 08:04:12 +10:00
commit 46d6719752
4 changed files with 46 additions and 13 deletions

View File

@ -623,6 +623,21 @@ get_lfp_data_tail(const struct bdb_lfp_data *data,
return NULL;
}
static bool is_panel_type_valid(int panel_type)
{
return panel_type >= 0 && panel_type < 16;
}
static bool is_panel_type_pnp(int panel_type)
{
return panel_type == 0xff;
}
static bool is_panel_type_valid_or_pnp(int panel_type)
{
return is_panel_type_valid(panel_type) || is_panel_type_pnp(panel_type);
}
static int opregion_get_panel_type(struct intel_display *display,
const struct intel_bios_encoder_data *devdata,
const struct drm_edid *drm_edid, bool use_fallback)
@ -640,15 +655,21 @@ static int vbt_get_panel_type(struct intel_display *display,
if (!lfp_options)
return -1;
if (lfp_options->panel_type > 0xf &&
lfp_options->panel_type != 0xff) {
if (!is_panel_type_valid_or_pnp(lfp_options->panel_type)) {
drm_dbg_kms(display->drm, "Invalid VBT panel type 0x%x\n",
lfp_options->panel_type);
return -1;
}
if (devdata && devdata->child.handle == DEVICE_HANDLE_LFP2)
if (devdata && devdata->child.handle == DEVICE_HANDLE_LFP2) {
if (!is_panel_type_valid_or_pnp(lfp_options->panel_type2)) {
drm_dbg_kms(display->drm, "Invalid VBT panel type 2 0x%x\n",
lfp_options->panel_type2);
return -1;
}
return lfp_options->panel_type2;
}
drm_WARN_ON(display->drm,
devdata && devdata->child.handle != DEVICE_HANDLE_LFP1);
@ -762,13 +783,12 @@ static int get_panel_type(struct intel_display *display,
panel_types[i].name, panel_types[i].panel_type);
}
if (panel_types[PANEL_TYPE_OPREGION].panel_type >= 0)
if (is_panel_type_valid(panel_types[PANEL_TYPE_OPREGION].panel_type))
i = PANEL_TYPE_OPREGION;
else if (panel_types[PANEL_TYPE_VBT].panel_type == 0xff &&
panel_types[PANEL_TYPE_PNPID].panel_type >= 0)
else if (is_panel_type_pnp(panel_types[PANEL_TYPE_VBT].panel_type) &&
is_panel_type_valid(panel_types[PANEL_TYPE_PNPID].panel_type))
i = PANEL_TYPE_PNPID;
else if (panel_types[PANEL_TYPE_VBT].panel_type != 0xff &&
panel_types[PANEL_TYPE_VBT].panel_type >= 0)
else if (is_panel_type_valid(panel_types[PANEL_TYPE_VBT].panel_type))
i = PANEL_TYPE_VBT;
else
i = PANEL_TYPE_FALLBACK;

View File

@ -145,6 +145,9 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state,
if (!new_conn_state || !new_conn_state->crtc)
continue;
if (drm_WARN_ON(display->drm, data->k >= INTEL_NUM_PIPES(display)))
return -EINVAL;
data->streams[data->k].stream_id =
intel_conn_to_vcpi(state, connector);
data->k++;
@ -155,7 +158,7 @@ intel_hdcp_required_content_stream(struct intel_atomic_state *state,
}
drm_connector_list_iter_end(&conn_iter);
if (drm_WARN_ON(display->drm, data->k > INTEL_NUM_PIPES(display) || data->k == 0))
if (drm_WARN_ON(display->drm, !data->k))
return -EINVAL;
/*
@ -1798,9 +1801,10 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
return -EINVAL;
}
if (seq_num_v < hdcp->seq_num_v) {
/* Roll over of the seq_num_v from repeater. Reauthenticate. */
drm_dbg_kms(display->drm, "Seq_num_v roll over.\n");
if (hdcp->hdcp2_encrypted && seq_num_v <= hdcp->seq_num_v) {
/* Reauthenticate on Seq_num_v repeat or rollover */
drm_dbg_kms(display->drm, "Seq_num_v %s\n",
seq_num_v == hdcp->seq_num_v ? "repeat" : "rollover");
return -EINVAL;
}

View File

@ -74,6 +74,10 @@ bool intel_vrr_is_capable(struct intel_connector *connector)
return false;
}
if (!info->monitor_range.min_vfreq || !info->monitor_range.max_vfreq ||
info->monitor_range.min_vfreq > info->monitor_range.max_vfreq)
return false;
return info->monitor_range.max_vfreq - info->monitor_range.min_vfreq > 10;
}

View File

@ -318,7 +318,7 @@ active_instance(struct i915_active *ref, u64 idx)
*/
node = kmem_cache_alloc(slab_cache, GFP_ATOMIC);
if (!node)
goto out;
goto err;
__i915_active_fence_init(&node->base, NULL, node_retire);
node->ref = ref;
@ -332,6 +332,11 @@ active_instance(struct i915_active *ref, u64 idx)
spin_unlock_irq(&ref->tree_lock);
return &node->base;
err:
spin_unlock_irq(&ref->tree_lock);
return NULL;
}
void __i915_active_init(struct i915_active *ref,