diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2022-04-05 20:33:54 +0300 |
---|---|---|
committer | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2022-04-12 09:18:19 +0300 |
commit | 5ab58d6996d7befd3273379100f45214d7f58790 (patch) | |
tree | c610536a579585199e7844fd131b4777c5e8e16b /drivers/gpu/drm/i915/display/intel_bios.c | |
parent | 58b2e3829ec6558d6d0edf709579b82550ecea61 (diff) |
drm/i915/bios: Validate the panel_name table
In addition to the fp_timing,dvo_timing,panel_pnp_id tables
there also exists a panel_name table. Unlike the others this
is just one offset+table_size even though there are still 16
actual panel_names in the data block.
The panel_name table made its first appearance somewhere
around VBT version 156-163. The exact version is not known.
But we don't need to know that since we can just check whether
the pointers block has enough room for it or not.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220405173410.11436-7-ville.syrjala@linux.intel.com
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_bios.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_bios.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index 762acf82f7c4..bc195769dd07 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -206,7 +206,7 @@ static const struct { static bool validate_lfp_data_ptrs(const void *bdb, const struct bdb_lvds_lfp_data_ptrs *ptrs) { - int fp_timing_size, dvo_timing_size, panel_pnp_id_size; + int fp_timing_size, dvo_timing_size, panel_pnp_id_size, panel_name_size; int data_block_size, lfp_data_size; int i; @@ -221,6 +221,7 @@ static bool validate_lfp_data_ptrs(const void *bdb, fp_timing_size = ptrs->ptr[0].fp_timing.table_size; dvo_timing_size = ptrs->ptr[0].dvo_timing.table_size; panel_pnp_id_size = ptrs->ptr[0].panel_pnp_id.table_size; + panel_name_size = ptrs->panel_name.table_size; /* fp_timing has variable size */ if (fp_timing_size < 32 || @@ -228,6 +229,11 @@ static bool validate_lfp_data_ptrs(const void *bdb, panel_pnp_id_size != sizeof(struct lvds_pnp_id)) return false; + /* panel_name is not present in old VBTs */ + if (panel_name_size != 0 && + panel_name_size != sizeof(struct lvds_lfp_panel_name)) + return false; + lfp_data_size = ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset; if (16 * lfp_data_size > data_block_size) return false; @@ -268,6 +274,9 @@ static bool validate_lfp_data_ptrs(const void *bdb, return false; } + if (ptrs->panel_name.offset + 16 * panel_name_size > data_block_size) + return false; + return true; } @@ -291,6 +300,13 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block) ptrs->ptr[i].panel_pnp_id.offset -= offset; } + if (ptrs->panel_name.table_size) { + if (ptrs->panel_name.offset < offset) + return false; + + ptrs->panel_name.offset -= offset; + } + return validate_lfp_data_ptrs(bdb, ptrs); } |