[PATCH 2/2] hp-wmi: use modern cleanup and refactor allocation functions

yahia <[email protected]>
Newsgroups org.kernel.vger.platform-driver-x86
Message-ID <[email protected]>
From: yahia ahmed <[email protected]>

Refactor hp_wmi_perform_query() and encode_outsize_for_pvsz() to improve
readability, ensure memory zeroing, and verify bounds.

Replace the brittle if condition tree in encode_outsize_for_pvsz() with
a switch statement, replace the manual out_free label in
hp_wmi_perform_query() to free args and obj variables with compiler
provided cleanup __free(), replace kmalloc with kzalloc_flex to ensure
that memory is zeroed before use, and add a bounds check for
obj->buffer.length to attest that it is larger than
sizeof(struct bios_return).

Reported-by: [email protected]
Link: https://sashiko.dev/#/patchset/20260712191130.41183-1-yahia.a.abdrabou%40gmail.com
Signed-off-by: yahia ahmed <[email protected]>
---
 drivers/platform/x86/hp/hp-wmi.c | 49 ++++++++++++++------------------
 1 file changed, 21 insertions(+), 28 deletions(-)

diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
index 5845b169df39..67bd3d6825f4 100644
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -552,16 +552,20 @@ static inline u8 pwm_to_rpm(u8 pwm, struct hp_wmi_hwmon_priv *priv)
 /* map output size to the corresponding WMI method id */
 static inline int encode_outsize_for_pvsz(int outsize)
 {
-	if (outsize > 4096)
+	if (unlikely(outsize > 4096 || outsize < 0))
 		return -EINVAL;
-	if (outsize > 1024)
-		return 5;
-	if (outsize > 128)
-		return 4;
-	if (outsize > 4)
-		return 3;
-	if (outsize > 0)
+	switch (outsize) {
+	case 1 ... 4:
 		return 2;
+	case 5 ... 128:
+		return 3;
+	case 129 ... 1024:
+		return 4;
+	case 1025 ... 4096:
+		return 5;
+	default:
+		break;
+	}
 	return 1;
 }
 
@@ -590,8 +594,8 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
 {
 	struct acpi_buffer input, output = { ACPI_ALLOCATE_BUFFER, NULL };
 	struct bios_return *bios_return;
-	union acpi_object *obj = NULL;
-	struct bios_args *args = NULL;
+	union acpi_object *obj __free(kfree) = NULL;
+	struct bios_args *args __free(kfree) = NULL;
 	int mid, actual_insize, actual_outsize;
 	size_t bios_args_size;
 	int ret;
@@ -602,7 +606,7 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
 
 	actual_insize = max(insize, 128);
 	bios_args_size = struct_size(args, data, actual_insize);
-	args = kmalloc(bios_args_size, GFP_KERNEL);
+	args = kzalloc_flex(*args, data, actual_insize, GFP_KERNEL);
 	if (!args)
 		return -ENOMEM;
 
@@ -617,19 +621,12 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
 
 	ret = wmidev_evaluate_method(hp_wmi_wdev, 0, mid, &input, &output);
 	if (ret)
-		goto out_free;
+		return ret;
 
 	obj = output.pointer;
-	if (!obj) {
-		ret = -EINVAL;
-		goto out_free;
-	}
-
-	if (obj->type != ACPI_TYPE_BUFFER) {
-		pr_warn("query 0x%x returned an invalid object 0x%x\n", query, ret);
-		ret = -EINVAL;
-		goto out_free;
-	}
+	if (!obj || obj->type != ACPI_TYPE_BUFFER ||
+	    obj->buffer.length < sizeof(struct bios_return))
+		 return -EINVAL;
 
 	bios_return = (struct bios_return *)obj->buffer.pointer;
 	ret = bios_return->return_code;
@@ -638,20 +635,16 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command,
 		if (ret != HPWMI_RET_UNKNOWN_COMMAND &&
 		    ret != HPWMI_RET_UNKNOWN_CMDTYPE)
 			pr_warn("query 0x%x returned error 0x%x\n", query, ret);
-		goto out_free;
+		return ret;
 	}
 
 	/* Ignore output data of zero size */
 	if (!outsize)
-		goto out_free;
+		return 0;
 
 	actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
 	memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
 	memset(buffer + actual_outsize, 0, outsize - actual_outsize);
-
-out_free:
-	kfree(obj);
-	kfree(args);
 	return ret;
 }
 
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.