Commit 5ab58d69 authored by Ville Syrjälä's avatar Ville Syrjälä

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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220405173410.11436-7-ville.syrjala@linux.intel.comReviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
parent 58b2e382
...@@ -206,7 +206,7 @@ static const struct { ...@@ -206,7 +206,7 @@ static const struct {
static bool validate_lfp_data_ptrs(const void *bdb, static bool validate_lfp_data_ptrs(const void *bdb,
const struct bdb_lvds_lfp_data_ptrs *ptrs) 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 data_block_size, lfp_data_size;
int i; int i;
...@@ -221,6 +221,7 @@ static bool validate_lfp_data_ptrs(const void *bdb, ...@@ -221,6 +221,7 @@ static bool validate_lfp_data_ptrs(const void *bdb,
fp_timing_size = ptrs->ptr[0].fp_timing.table_size; fp_timing_size = ptrs->ptr[0].fp_timing.table_size;
dvo_timing_size = ptrs->ptr[0].dvo_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_pnp_id_size = ptrs->ptr[0].panel_pnp_id.table_size;
panel_name_size = ptrs->panel_name.table_size;
/* fp_timing has variable size */ /* fp_timing has variable size */
if (fp_timing_size < 32 || if (fp_timing_size < 32 ||
...@@ -228,6 +229,11 @@ static bool validate_lfp_data_ptrs(const void *bdb, ...@@ -228,6 +229,11 @@ static bool validate_lfp_data_ptrs(const void *bdb,
panel_pnp_id_size != sizeof(struct lvds_pnp_id)) panel_pnp_id_size != sizeof(struct lvds_pnp_id))
return false; 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; lfp_data_size = ptrs->ptr[1].fp_timing.offset - ptrs->ptr[0].fp_timing.offset;
if (16 * lfp_data_size > data_block_size) if (16 * lfp_data_size > data_block_size)
return false; return false;
...@@ -268,6 +274,9 @@ static bool validate_lfp_data_ptrs(const void *bdb, ...@@ -268,6 +274,9 @@ static bool validate_lfp_data_ptrs(const void *bdb,
return false; return false;
} }
if (ptrs->panel_name.offset + 16 * panel_name_size > data_block_size)
return false;
return true; return true;
} }
...@@ -291,6 +300,13 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block) ...@@ -291,6 +300,13 @@ static bool fixup_lfp_data_ptrs(const void *bdb, void *ptrs_block)
ptrs->ptr[i].panel_pnp_id.offset -= offset; 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); return validate_lfp_data_ptrs(bdb, ptrs);
} }
......
...@@ -737,6 +737,7 @@ struct lvds_lfp_data_ptr { ...@@ -737,6 +737,7 @@ struct lvds_lfp_data_ptr {
struct bdb_lvds_lfp_data_ptrs { struct bdb_lvds_lfp_data_ptrs {
u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */ u8 lvds_entries; /* followed by one or more lvds_data_ptr structs */
struct lvds_lfp_data_ptr ptr[16]; struct lvds_lfp_data_ptr ptr[16];
struct lvds_lfp_data_ptr_table panel_name; /* 156-163? */
} __packed; } __packed;
/* /*
...@@ -778,6 +779,10 @@ struct bdb_lvds_lfp_data { ...@@ -778,6 +779,10 @@ struct bdb_lvds_lfp_data {
struct lvds_lfp_data_entry data[16]; struct lvds_lfp_data_entry data[16];
} __packed; } __packed;
struct lvds_lfp_panel_name {
u8 name[13];
} __packed;
/* /*
* Block 43 - LFP Backlight Control Data Block * Block 43 - LFP Backlight Control Data Block
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment