* [PATCH v3 0/4] platform/x86: hp-bioscfg: fix ACPI package handling on HP EliteBook 840 G2
@ 2026-07-07 20:21 Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 1/4] platform/x86: hp-bioscfg: pass validated element count to package parsers Muhammad Bilal
` (3 more replies)
0 siblings, 4 replies; 7+ messages in thread
From: Muhammad Bilal @ 2026-07-07 20:21 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-kernel, ilpo.jarvinen, hdegoede, jorge.lopez2,
Thomas.Weissschuh, superm1, W_Armin, stable, Muhammad Bilal
This series fixes attribute enumeration failures on the HP EliteBook 840
G2 (BIOS M71 Ver. 01.31), whose BIOS returns shorter ACPI WMI packages
than hp_init_bios_package_attribute() currently accepts, plus occasional
type-mismatched elements after a failed WMI query.
Patches 1 and 2 are prerequisites: they make each per-type parser bound
itself on the real, validated package count instead of an incorrect value
derived from the NAME string's length. Both are no-ops today, since
every package the driver currently handles already meets the old
minimum size. They matter because patch 3 depends on them: once the
minimum size check is relaxed, the elements array can genuinely be
smaller than a parser's fixed per-type count, and without patches 1 and
2 this would result in an out-of-bounds heap read.
Patch 3 relaxes that minimum size check to accept packages missing
optional type-specific fields, as long as the common fields (NAME
through SECURITY_LEVEL) are present.
Patch 4 changes a type mismatch on one element from aborting the whole
attribute to warning and skipping the offending element, matching the
existing handling of unsupported element types.
Patches 1 through 3 are intended to be applied together, as patch 3
depends on the preparatory fixes in patches 1 and 2.
Changes since v2:
- Split the single "pass validated count and bound ordered list
parsing" patch into two: patch 1 fixes the count value passed to
each wrapper, patch 2 adds the missing elem < count bound to the
ordered list parser. (Ilpo)
- Rewrote patch 1's commit message to lead with the bug instead of
quoting code, and to state up front that a later patch depends on
it. (Ilpo)
- Reworded "thread the count down" and "guess at it" phrasing. (Ilpo)
Muhammad Bilal (4):
platform/x86: hp-bioscfg: pass validated element count to package
parsers
platform/x86: hp-bioscfg: bound ordered-list parsing by the package
count
platform/x86: hp-bioscfg: accept reduced ACPI packages from older HP
BIOS
platform/x86: hp-bioscfg: warn on element type mismatch instead of
failing
drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 16 +++++++++++++---
drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 8 ++++++++
.../platform/x86/hp/hp-bioscfg/enum-attributes.c | 10 ++++++----
.../platform/x86/hp/hp-bioscfg/int-attributes.c | 3 ++-
.../x86/hp/hp-bioscfg/order-list-attributes.c | 7 ++++---
.../x86/hp/hp-bioscfg/passwdobj-attributes.c | 5 +++--
.../x86/hp/hp-bioscfg/string-attributes.c | 3 ++-
7 files changed, 38 insertions(+), 14 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 1/4] platform/x86: hp-bioscfg: pass validated element count to package parsers
2026-07-07 20:21 [PATCH v3 0/4] platform/x86: hp-bioscfg: fix ACPI package handling on HP EliteBook 840 G2 Muhammad Bilal
@ 2026-07-07 20:21 ` Muhammad Bilal
2026-07-08 10:54 ` Ilpo Järvinen
2026-07-07 20:21 ` [PATCH v3 2/4] platform/x86: hp-bioscfg: bound ordered-list parsing by the package count Muhammad Bilal
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Muhammad Bilal @ 2026-07-07 20:21 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-kernel, ilpo.jarvinen, hdegoede, jorge.lopez2,
Thomas.Weissschuh, superm1, W_Armin, stable, Muhammad Bilal
The per-type package parsers are handed the wrong element count.
hp_init_bios_package_attribute() validates obj->package.count and then
calls one of the five hp_populate_*_package_data() wrappers (string,
integer, enumeration, ordered list, password). Each wrapper forwards a
count to its hp_populate_*_elements_from_package() parser, but instead
of forwarding the validated obj->package.count it derives the count
from elements[0]. elements[0] is the NAME field and is always an
ACPI_TYPE_STRING, so reading ->package.count from it in fact reads
->string.length through the union acpi_object. The parsers thus bound
themselves against the length of the name string rather than against
the real number of elements in the package.
This is safe today because hp_init_bios_package_attribute() refuses any
package that has fewer than the type's element count, so a parser only
ever runs on a full package and never reads past it regardless of the
bogus bound.
A later patch relaxes that check to accept shorter packages. Once a
parser can receive fewer elements than its per-type count, a bound
taken from the name length no longer reflects the array size, and the
"elem < count" loop conditions and "elem + n >= count" sub-loop guards
read past the end of elements[] - an out-of-bounds heap read.
Forward the validated obj->package.count to every *_package_data()
wrapper so the parsers bound themselves against the real package size.
This does not change behaviour for the packages that enumerate
correctly today and is a prerequisite for accepting shorter packages
safely.
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
---
drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 5 +++++
drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 5 +++++
drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c | 3 ++-
drivers/platform/x86/hp/hp-bioscfg/int-attributes.c | 3 ++-
drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c | 5 +++--
drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c | 5 +++--
drivers/platform/x86/hp/hp-bioscfg/string-attributes.c | 3 ++-
7 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
index 27fd6cd215290..768330d291da8 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
@@ -731,26 +731,31 @@ static int hp_init_bios_package_attribute(enum hp_wmi_data_type attr_type,
switch (attr_type) {
case HPWMI_STRING_TYPE:
ret = hp_populate_string_package_data(elements,
+ obj->package.count,
instance_id,
attr_name_kobj);
break;
case HPWMI_INTEGER_TYPE:
ret = hp_populate_integer_package_data(elements,
+ obj->package.count,
instance_id,
attr_name_kobj);
break;
case HPWMI_ENUMERATION_TYPE:
ret = hp_populate_enumeration_package_data(elements,
+ obj->package.count,
instance_id,
attr_name_kobj);
break;
case HPWMI_ORDERED_LIST_TYPE:
ret = hp_populate_ordered_list_package_data(elements,
+ obj->package.count,
instance_id,
attr_name_kobj);
break;
case HPWMI_PASSWORD_TYPE:
ret = hp_populate_password_package_data(elements,
+ obj->package.count,
instance_id,
attr_name_kobj);
break;
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
index f1eec0e4ba075..416d7e7aaaae3 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
@@ -401,6 +401,7 @@ int hp_populate_string_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
int hp_alloc_string_data(void);
void hp_exit_string_attributes(void);
int hp_populate_string_package_data(union acpi_object *str_obj,
+ int str_obj_count,
int instance_id,
struct kobject *attr_name_kobj);
@@ -411,6 +412,7 @@ int hp_populate_integer_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
int hp_alloc_integer_data(void);
void hp_exit_integer_attributes(void);
int hp_populate_integer_package_data(union acpi_object *integer_obj,
+ int integer_obj_count,
int instance_id,
struct kobject *attr_name_kobj);
@@ -421,6 +423,7 @@ int hp_populate_enumeration_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
int hp_alloc_enumeration_data(void);
void hp_exit_enumeration_attributes(void);
int hp_populate_enumeration_package_data(union acpi_object *enum_obj,
+ int enum_obj_count,
int instance_id,
struct kobject *attr_name_kobj);
@@ -432,6 +435,7 @@ int hp_populate_ordered_list_buffer_data(u8 *buffer_ptr,
int hp_alloc_ordered_list_data(void);
void hp_exit_ordered_list_attributes(void);
int hp_populate_ordered_list_package_data(union acpi_object *order_obj,
+ int order_obj_count,
int instance_id,
struct kobject *attr_name_kobj);
@@ -440,6 +444,7 @@ int hp_populate_password_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
int instance_id,
struct kobject *attr_name_kobj);
int hp_populate_password_package_data(union acpi_object *password_obj,
+ int password_obj_count,
int instance_id,
struct kobject *attr_name_kobj);
int hp_alloc_password_data(void);
diff --git a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
index af4d1920d4880..3aa2c440e0528 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
@@ -304,6 +304,7 @@ static int hp_populate_enumeration_elements_from_package(union acpi_object *enum
* @attr_name_kobj: The parent kernel object
*/
int hp_populate_enumeration_package_data(union acpi_object *enum_obj,
+ int enum_obj_count,
int instance_id,
struct kobject *attr_name_kobj)
{
@@ -312,7 +313,7 @@ int hp_populate_enumeration_package_data(union acpi_object *enum_obj,
enum_data->attr_name_kobj = attr_name_kobj;
hp_populate_enumeration_elements_from_package(enum_obj,
- enum_obj->package.count,
+ enum_obj_count,
instance_id);
hp_update_attribute_permissions(enum_data->common.is_readonly,
&enumeration_current_val);
diff --git a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c
index d96e160953e39..107e4cf1efb8a 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c
@@ -279,6 +279,7 @@ static int hp_populate_integer_elements_from_package(union acpi_object *integer_
* @attr_name_kobj: The parent kernel object
*/
int hp_populate_integer_package_data(union acpi_object *integer_obj,
+ int integer_obj_count,
int instance_id,
struct kobject *attr_name_kobj)
{
@@ -286,7 +287,7 @@ int hp_populate_integer_package_data(union acpi_object *integer_obj,
integer_data->attr_name_kobj = attr_name_kobj;
hp_populate_integer_elements_from_package(integer_obj,
- integer_obj->package.count,
+ integer_obj_count,
instance_id);
hp_update_attribute_permissions(integer_data->common.is_readonly,
&integer_current_val);
diff --git a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
index f09489a085c86..83ddf99f93954 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
@@ -301,7 +301,8 @@ static int hp_populate_ordered_list_elements_from_package(union acpi_object *ord
* @instance_id: The instance to enumerate
* @attr_name_kobj: The parent kernel object
*/
-int hp_populate_ordered_list_package_data(union acpi_object *order_obj, int instance_id,
+int hp_populate_ordered_list_package_data(union acpi_object *order_obj, int order_obj_count,
+ int instance_id,
struct kobject *attr_name_kobj)
{
struct ordered_list_data *ordered_list_data = &bioscfg_drv.ordered_list_data[instance_id];
@@ -309,7 +310,7 @@ int hp_populate_ordered_list_package_data(union acpi_object *order_obj, int inst
ordered_list_data->attr_name_kobj = attr_name_kobj;
hp_populate_ordered_list_elements_from_package(order_obj,
- order_obj->package.count,
+ order_obj_count,
instance_id);
hp_update_attribute_permissions(ordered_list_data->common.is_readonly,
&ordered_list_current_val);
diff --git a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c
index 4d79eb8056a5d..89316d90454d2 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c
@@ -388,7 +388,8 @@ static int hp_populate_password_elements_from_package(union acpi_object *passwor
* @instance_id: The instance to enumerate
* @attr_name_kobj: The parent kernel object
*/
-int hp_populate_password_package_data(union acpi_object *password_obj, int instance_id,
+int hp_populate_password_package_data(union acpi_object *password_obj, int password_obj_count,
+ int instance_id,
struct kobject *attr_name_kobj)
{
struct password_data *password_data = &bioscfg_drv.password_data[instance_id];
@@ -396,7 +397,7 @@ int hp_populate_password_package_data(union acpi_object *password_obj, int insta
password_data->attr_name_kobj = attr_name_kobj;
hp_populate_password_elements_from_package(password_obj,
- password_obj->package.count,
+ password_obj_count,
instance_id);
hp_friendly_user_name_update(password_data->common.path,
diff --git a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c
index fe5a9a3a4ef17..da5e81f1d188f 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c
@@ -267,6 +267,7 @@ static int hp_populate_string_elements_from_package(union acpi_object *string_ob
* @attr_name_kobj: The parent kernel object
*/
int hp_populate_string_package_data(union acpi_object *string_obj,
+ int string_obj_count,
int instance_id,
struct kobject *attr_name_kobj)
{
@@ -275,7 +276,7 @@ int hp_populate_string_package_data(union acpi_object *string_obj,
string_data->attr_name_kobj = attr_name_kobj;
hp_populate_string_elements_from_package(string_obj,
- string_obj->package.count,
+ string_obj_count,
instance_id);
hp_update_attribute_permissions(string_data->common.is_readonly,
--
2.55.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 2/4] platform/x86: hp-bioscfg: bound ordered-list parsing by the package count
2026-07-07 20:21 [PATCH v3 0/4] platform/x86: hp-bioscfg: fix ACPI package handling on HP EliteBook 840 G2 Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 1/4] platform/x86: hp-bioscfg: pass validated element count to package parsers Muhammad Bilal
@ 2026-07-07 20:21 ` Muhammad Bilal
2026-07-08 10:58 ` Ilpo Järvinen
2026-07-07 20:21 ` [PATCH v3 3/4] platform/x86: hp-bioscfg: accept reduced ACPI packages from older HP BIOS Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 4/4] platform/x86: hp-bioscfg: warn on element type mismatch instead of failing Muhammad Bilal
3 siblings, 1 reply; 7+ messages in thread
From: Muhammad Bilal @ 2026-07-07 20:21 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-kernel, ilpo.jarvinen, hdegoede, jorge.lopez2,
Thomas.Weissschuh, superm1, W_Armin, stable, Muhammad Bilal
hp_populate_ordered_list_elements_from_package() differs from the other
per-type parsers: its main loop is bounded only by the fixed per-type
count and never checks elem against the number of elements actually
present in the package,
for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT; elem++, eloc++)
whereas the string, integer, enumeration and password parsers bound
their main loop with "elem < count" as well.
This is safe today because hp_init_bios_package_attribute() rejects any
package with fewer than ORD_ELEM_CNT elements before the parser runs. A
later patch relaxes that check to accept shorter packages; once this
loop can be handed fewer than ORD_ELEM_CNT elements it indexes
order_obj[elem] past the end of the array - an out-of-bounds heap read.
Bound the loop by the validated element count as well, so it stops at
whichever comes first, the per-type count or the real package size,
for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT && elem < order_obj_count;
elem++, eloc++)
order_obj_count is the validated count plumbed in by the previous
patch. No functional change for packages that enumerate correctly
today.
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
---
drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
index 83ddf99f93954..a50d074125268 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
@@ -145,7 +145,7 @@ static int hp_populate_ordered_list_elements_from_package(union acpi_object *ord
if (!order_obj)
return -EINVAL;
- for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT; elem++, eloc++) {
+ for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT && elem < order_obj_count; elem++, eloc++) {
switch (order_obj[elem].type) {
case ACPI_TYPE_STRING:
--
2.55.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 3/4] platform/x86: hp-bioscfg: accept reduced ACPI packages from older HP BIOS
2026-07-07 20:21 [PATCH v3 0/4] platform/x86: hp-bioscfg: fix ACPI package handling on HP EliteBook 840 G2 Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 1/4] platform/x86: hp-bioscfg: pass validated element count to package parsers Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 2/4] platform/x86: hp-bioscfg: bound ordered-list parsing by the package count Muhammad Bilal
@ 2026-07-07 20:21 ` Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 4/4] platform/x86: hp-bioscfg: warn on element type mismatch instead of failing Muhammad Bilal
3 siblings, 0 replies; 7+ messages in thread
From: Muhammad Bilal @ 2026-07-07 20:21 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-kernel, ilpo.jarvinen, hdegoede, jorge.lopez2,
Thomas.Weissschuh, superm1, W_Armin, stable, Muhammad Bilal
hp_init_bios_package_attribute() hard-fails when a WMI ACPI package
contains fewer elements than the type-specific expected count (e.g. 11
elements instead of 13 for INTEGER or ENUMERATION attributes). This
causes the entire hp_bioscfg driver to skip attribute enumeration on
older HP hardware whose BIOS returns shortened packages when optional
fields like prerequisites or possible values are absent.
Observed on HP EliteBook 840 G2 (BIOS M71 Ver. 01.31):
hp_bioscfg: ACPI-package does not have enough elements: 11 < 13
The element layout has two tiers:
- Elements 0-9 (SECURITY_LEVEL+1 = 10): common to all attribute types
- Elements 10-N: type-specific (bounds, values, encodings, ...)
The per-type populate functions (hp_populate_*_elements_from_package)
already handle sparse packages correctly via their own elem < count
loop guards and inner-loop bounds checks. The only unsafe case is when
we lack even the common elements needed to register the attribute.
Fix by introducing COMMON_ELEM_CNT to mark the hard minimum (10), and
splitting the check into two tiers:
- Fewer than COMMON_ELEM_CNT elements: hard fail, can't proceed.
- Fewer than expected type-specific elements: warn, but let the
populate function parse what is available.
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
---
drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 11 ++++++++---
drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 3 +++
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
index 768330d291da8..78019644ec358 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
@@ -661,12 +661,17 @@ static int hp_init_bios_package_attribute(enum hp_wmi_data_type attr_type,
int ret = 0;
/* Take action appropriate to each ACPI TYPE */
- if (obj->package.count < min_elements) {
- pr_err("ACPI-package does not have enough elements: %d < %d\n",
- obj->package.count, min_elements);
+ if (obj->package.count < COMMON_ELEM_CNT) {
+ pr_err("ACPI-package is missing common elements: %d < %d\n",
+ obj->package.count, COMMON_ELEM_CNT);
goto pack_attr_exit;
}
+ if (obj->package.count < min_elements) {
+ pr_warn("ACPI-package has fewer elements than expected: %d < %d, parsing available elements\n",
+ obj->package.count, min_elements);
+ }
+
elements = obj->package.elements;
/* sanity checking */
diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
index 416d7e7aaaae3..ac57d6eab4c35 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
+++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
@@ -279,6 +279,9 @@ enum hp_wmi_data_elements {
PSWD_ENCODINGS = 13,
PSWD_IS_SET = 14,
PSWD_ELEM_CNT = 15,
+
+ /* Minimum elements shared by all attribute types (NAME..SECURITY_LEVEL) */
+ COMMON_ELEM_CNT = SECURITY_LEVEL + 1,
};
#define GET_INSTANCE_ID(type) \
--
2.55.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 4/4] platform/x86: hp-bioscfg: warn on element type mismatch instead of failing
2026-07-07 20:21 [PATCH v3 0/4] platform/x86: hp-bioscfg: fix ACPI package handling on HP EliteBook 840 G2 Muhammad Bilal
` (2 preceding siblings ...)
2026-07-07 20:21 ` [PATCH v3 3/4] platform/x86: hp-bioscfg: accept reduced ACPI packages from older HP BIOS Muhammad Bilal
@ 2026-07-07 20:21 ` Muhammad Bilal
3 siblings, 0 replies; 7+ messages in thread
From: Muhammad Bilal @ 2026-07-07 20:21 UTC (permalink / raw)
To: platform-driver-x86
Cc: linux-kernel, ilpo.jarvinen, hdegoede, jorge.lopez2,
Thomas.Weissschuh, superm1, W_Armin, stable, Muhammad Bilal
hp_populate_enumeration_elements_from_package() returns -EIO and aborts
enumeration of the entire attribute when any single element has an
unexpected ACPI type. This is observed on HP EliteBook 840 G2 when the
BIOS returns malformed ACPI data following a failed WMI query:
ACPI BIOS Error (bug): AE_AML_BUFFER_LIMIT, Index (0x000000032)
is beyond end of object (length 0x32)
ACPI Error: Aborting method \_SB.WMID.WQBE due to previous error
Error expected type 2 for elem 13, but got type 1 instead
hp_bioscfg: Returned error 0x3,
"Invalid command value/Feature not supported"
Aborting immediately discards the attribute entirely.
Warn about the unexpected element type, free the temporary string, skip
the offending element, and continue parsing the remaining package
instead of failing the whole attribute.
Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
---
drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
index 3aa2c440e0528..b834303e5bc79 100644
--- a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
+++ b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
@@ -163,10 +163,11 @@ static int hp_populate_enumeration_elements_from_package(union acpi_object *enum
/* Check that both expected and read object type match */
if (expected_enum_types[eloc] != enum_obj[elem].type) {
- pr_err("Error expected type %d for elem %d, but got type %d instead\n",
- expected_enum_types[eloc], elem, enum_obj[elem].type);
+ pr_warn("Unexpected element type at elem %d: expected %d, got %d, skipping\n",
+ elem, expected_enum_types[eloc], enum_obj[elem].type);
kfree(str_value);
- return -EIO;
+ str_value = NULL;
+ continue;
}
/* Assign appropriate element value to corresponding field */
--
2.55.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3 1/4] platform/x86: hp-bioscfg: pass validated element count to package parsers
2026-07-07 20:21 ` [PATCH v3 1/4] platform/x86: hp-bioscfg: pass validated element count to package parsers Muhammad Bilal
@ 2026-07-08 10:54 ` Ilpo Järvinen
0 siblings, 0 replies; 7+ messages in thread
From: Ilpo Järvinen @ 2026-07-08 10:54 UTC (permalink / raw)
To: Muhammad Bilal
Cc: platform-driver-x86, LKML, hdegoede, jorge.lopez2,
Thomas.Weissschuh, superm1, W_Armin, stable
On Wed, 8 Jul 2026, Muhammad Bilal wrote:
> The per-type package parsers are handed the wrong element count.
>
> hp_init_bios_package_attribute() validates obj->package.count and then
> calls one of the five hp_populate_*_package_data() wrappers (string,
> integer, enumeration, ordered list, password). Each wrapper forwards a
> count to its hp_populate_*_elements_from_package() parser, but instead
> of forwarding the validated obj->package.count it derives the count
> from elements[0]. elements[0] is the NAME field and is always an
> ACPI_TYPE_STRING, so reading ->package.count from it in fact reads
> ->string.length through the union acpi_object. The parsers thus bound
> themselves against the length of the name string rather than against
> the real number of elements in the package.
>
> This is safe today because hp_init_bios_package_attribute() refuses any
> package that has fewer than the type's element count, so a parser only
> ever runs on a full package and never reads past it regardless of the
> bogus bound.
>
> A later patch relaxes that check to accept shorter packages. Once a
A later patch -> An upcoming change
This is because once a patch is accepted, it becomes "commit" or "change",
it no longer is patch.
I probably explained it already once (but there have been multiple
submitters with this same wrong phrasing recently so I might confuse
people, I'm sorry about that if I did).
> parser can receive fewer elements than its per-type count, a bound
> taken from the name length no longer reflects the array size, and the
> "elem < count" loop conditions and "elem + n >= count" sub-loop guards
> read past the end of elements[] - an out-of-bounds heap read.
>
> Forward the validated obj->package.count to every *_package_data()
> wrapper so the parsers bound themselves against the real package size.
> This does not change behaviour for the packages that enumerate
> correctly today and is a prerequisite for accepting shorter packages
> safely.
>
> Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
Technically, this doesn't yet fix anything and stable people know to take
dependencies from the same series as long as you've the Cc stable in
place. So this Fixes tag can be dropped.
> Cc: stable@vger.kernel.org
> Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
> ---
> drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 5 +++++
> drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 5 +++++
> drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c | 3 ++-
> drivers/platform/x86/hp/hp-bioscfg/int-attributes.c | 3 ++-
> drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c | 5 +++--
> drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c | 5 +++--
> drivers/platform/x86/hp/hp-bioscfg/string-attributes.c | 3 ++-
> 7 files changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
> index 27fd6cd215290..768330d291da8 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
> +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c
> @@ -731,26 +731,31 @@ static int hp_init_bios_package_attribute(enum hp_wmi_data_type attr_type,
> switch (attr_type) {
> case HPWMI_STRING_TYPE:
> ret = hp_populate_string_package_data(elements,
> + obj->package.count,
> instance_id,
> attr_name_kobj);
> break;
> case HPWMI_INTEGER_TYPE:
> ret = hp_populate_integer_package_data(elements,
> + obj->package.count,
> instance_id,
> attr_name_kobj);
> break;
> case HPWMI_ENUMERATION_TYPE:
> ret = hp_populate_enumeration_package_data(elements,
> + obj->package.count,
> instance_id,
> attr_name_kobj);
> break;
> case HPWMI_ORDERED_LIST_TYPE:
> ret = hp_populate_ordered_list_package_data(elements,
> + obj->package.count,
> instance_id,
> attr_name_kobj);
> break;
> case HPWMI_PASSWORD_TYPE:
> ret = hp_populate_password_package_data(elements,
> + obj->package.count,
> instance_id,
> attr_name_kobj);
> break;
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
> index f1eec0e4ba075..416d7e7aaaae3 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
> +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.h
> @@ -401,6 +401,7 @@ int hp_populate_string_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
> int hp_alloc_string_data(void);
> void hp_exit_string_attributes(void);
> int hp_populate_string_package_data(union acpi_object *str_obj,
> + int str_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj);
>
> @@ -411,6 +412,7 @@ int hp_populate_integer_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
> int hp_alloc_integer_data(void);
> void hp_exit_integer_attributes(void);
> int hp_populate_integer_package_data(union acpi_object *integer_obj,
> + int integer_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj);
>
> @@ -421,6 +423,7 @@ int hp_populate_enumeration_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
> int hp_alloc_enumeration_data(void);
> void hp_exit_enumeration_attributes(void);
> int hp_populate_enumeration_package_data(union acpi_object *enum_obj,
> + int enum_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj);
>
> @@ -432,6 +435,7 @@ int hp_populate_ordered_list_buffer_data(u8 *buffer_ptr,
> int hp_alloc_ordered_list_data(void);
> void hp_exit_ordered_list_attributes(void);
> int hp_populate_ordered_list_package_data(union acpi_object *order_obj,
> + int order_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj);
>
> @@ -440,6 +444,7 @@ int hp_populate_password_buffer_data(u8 *buffer_ptr, u32 *buffer_size,
> int instance_id,
> struct kobject *attr_name_kobj);
> int hp_populate_password_package_data(union acpi_object *password_obj,
> + int password_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj);
> int hp_alloc_password_data(void);
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
> index af4d1920d4880..3aa2c440e0528 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
> +++ b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c
> @@ -304,6 +304,7 @@ static int hp_populate_enumeration_elements_from_package(union acpi_object *enum
> * @attr_name_kobj: The parent kernel object
> */
> int hp_populate_enumeration_package_data(union acpi_object *enum_obj,
> + int enum_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj)
> {
> @@ -312,7 +313,7 @@ int hp_populate_enumeration_package_data(union acpi_object *enum_obj,
> enum_data->attr_name_kobj = attr_name_kobj;
>
> hp_populate_enumeration_elements_from_package(enum_obj,
> - enum_obj->package.count,
> + enum_obj_count,
> instance_id);
> hp_update_attribute_permissions(enum_data->common.is_readonly,
> &enumeration_current_val);
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c
> index d96e160953e39..107e4cf1efb8a 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c
> +++ b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c
> @@ -279,6 +279,7 @@ static int hp_populate_integer_elements_from_package(union acpi_object *integer_
> * @attr_name_kobj: The parent kernel object
> */
> int hp_populate_integer_package_data(union acpi_object *integer_obj,
> + int integer_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj)
> {
> @@ -286,7 +287,7 @@ int hp_populate_integer_package_data(union acpi_object *integer_obj,
>
> integer_data->attr_name_kobj = attr_name_kobj;
> hp_populate_integer_elements_from_package(integer_obj,
> - integer_obj->package.count,
> + integer_obj_count,
> instance_id);
> hp_update_attribute_permissions(integer_data->common.is_readonly,
> &integer_current_val);
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
> index f09489a085c86..83ddf99f93954 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
> +++ b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
> @@ -301,7 +301,8 @@ static int hp_populate_ordered_list_elements_from_package(union acpi_object *ord
> * @instance_id: The instance to enumerate
> * @attr_name_kobj: The parent kernel object
> */
> -int hp_populate_ordered_list_package_data(union acpi_object *order_obj, int instance_id,
> +int hp_populate_ordered_list_package_data(union acpi_object *order_obj, int order_obj_count,
> + int instance_id,
> struct kobject *attr_name_kobj)
> {
> struct ordered_list_data *ordered_list_data = &bioscfg_drv.ordered_list_data[instance_id];
> @@ -309,7 +310,7 @@ int hp_populate_ordered_list_package_data(union acpi_object *order_obj, int inst
> ordered_list_data->attr_name_kobj = attr_name_kobj;
>
> hp_populate_ordered_list_elements_from_package(order_obj,
> - order_obj->package.count,
> + order_obj_count,
> instance_id);
> hp_update_attribute_permissions(ordered_list_data->common.is_readonly,
> &ordered_list_current_val);
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c
> index 4d79eb8056a5d..89316d90454d2 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c
> +++ b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c
> @@ -388,7 +388,8 @@ static int hp_populate_password_elements_from_package(union acpi_object *passwor
> * @instance_id: The instance to enumerate
> * @attr_name_kobj: The parent kernel object
> */
> -int hp_populate_password_package_data(union acpi_object *password_obj, int instance_id,
> +int hp_populate_password_package_data(union acpi_object *password_obj, int password_obj_count,
> + int instance_id,
> struct kobject *attr_name_kobj)
> {
> struct password_data *password_data = &bioscfg_drv.password_data[instance_id];
> @@ -396,7 +397,7 @@ int hp_populate_password_package_data(union acpi_object *password_obj, int insta
> password_data->attr_name_kobj = attr_name_kobj;
>
> hp_populate_password_elements_from_package(password_obj,
> - password_obj->package.count,
> + password_obj_count,
> instance_id);
>
> hp_friendly_user_name_update(password_data->common.path,
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c
> index fe5a9a3a4ef17..da5e81f1d188f 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c
> +++ b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c
> @@ -267,6 +267,7 @@ static int hp_populate_string_elements_from_package(union acpi_object *string_ob
> * @attr_name_kobj: The parent kernel object
> */
> int hp_populate_string_package_data(union acpi_object *string_obj,
> + int string_obj_count,
> int instance_id,
> struct kobject *attr_name_kobj)
> {
> @@ -275,7 +276,7 @@ int hp_populate_string_package_data(union acpi_object *string_obj,
> string_data->attr_name_kobj = attr_name_kobj;
>
> hp_populate_string_elements_from_package(string_obj,
> - string_obj->package.count,
> + string_obj_count,
> instance_id);
>
> hp_update_attribute_permissions(string_data->common.is_readonly,
>
--
i.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3 2/4] platform/x86: hp-bioscfg: bound ordered-list parsing by the package count
2026-07-07 20:21 ` [PATCH v3 2/4] platform/x86: hp-bioscfg: bound ordered-list parsing by the package count Muhammad Bilal
@ 2026-07-08 10:58 ` Ilpo Järvinen
0 siblings, 0 replies; 7+ messages in thread
From: Ilpo Järvinen @ 2026-07-08 10:58 UTC (permalink / raw)
To: Muhammad Bilal
Cc: platform-driver-x86, LKML, hdegoede, jorge.lopez2,
Thomas.Weissschuh, superm1, W_Armin, stable
On Wed, 8 Jul 2026, Muhammad Bilal wrote:
> hp_populate_ordered_list_elements_from_package() differs from the other
> per-type parsers: its main loop is bounded only by the fixed per-type
> count and never checks elem against the number of elements actually
> present in the package,
>
> for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT; elem++, eloc++)
>
> whereas the string, integer, enumeration and password parsers bound
> their main loop with "elem < count" as well.
>
> This is safe today because hp_init_bios_package_attribute() rejects any
> package with fewer than ORD_ELEM_CNT elements before the parser runs. A
> later patch relaxes that check to accept shorter packages;
An upcoming change, however, relaxes ...
> once this
> loop can be handed fewer than ORD_ELEM_CNT elements it indexes
> order_obj[elem] past the end of the array - an out-of-bounds heap read.
I don't think we need this part of the explanation, it will never happen
as you're fixing it beforehand. :-) So please drop it as unnecessary
detail.
It's pretty obvious to kernel developers anyway if there's a runaway index
so there's no big need in general to tell too simple basics like that.
> Bound the loop by the validated element count as well, so it stops at
> whichever comes first, the per-type count or the real package size,
>
> for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT && elem < order_obj_count;
> elem++, eloc++)
>
> order_obj_count is the validated count plumbed in by the previous
> patch. No functional change for packages that enumerate correctly
> today.
>
> Fixes: a34fc329b189 ("platform/x86: hp-bioscfg: bioscfg")
> Cc: stable@vger.kernel.org
> Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
> ---
> drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
> index 83ddf99f93954..a50d074125268 100644
> --- a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
> +++ b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c
> @@ -145,7 +145,7 @@ static int hp_populate_ordered_list_elements_from_package(union acpi_object *ord
> if (!order_obj)
> return -EINVAL;
>
> - for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT; elem++, eloc++) {
> + for (elem = 1, eloc = 1; eloc < ORD_ELEM_CNT && elem < order_obj_count; elem++, eloc++) {
>
> switch (order_obj[elem].type) {
> case ACPI_TYPE_STRING:
>
--
i.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-08 10:58 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 20:21 [PATCH v3 0/4] platform/x86: hp-bioscfg: fix ACPI package handling on HP EliteBook 840 G2 Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 1/4] platform/x86: hp-bioscfg: pass validated element count to package parsers Muhammad Bilal
2026-07-08 10:54 ` Ilpo Järvinen
2026-07-07 20:21 ` [PATCH v3 2/4] platform/x86: hp-bioscfg: bound ordered-list parsing by the package count Muhammad Bilal
2026-07-08 10:58 ` Ilpo Järvinen
2026-07-07 20:21 ` [PATCH v3 3/4] platform/x86: hp-bioscfg: accept reduced ACPI packages from older HP BIOS Muhammad Bilal
2026-07-07 20:21 ` [PATCH v3 4/4] platform/x86: hp-bioscfg: warn on element type mismatch instead of failing Muhammad Bilal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox