From: Armin Wolf <W_Armin@gmx.de>
To: hansg@kernel.org
Cc: ilpo.jarvinen@linux.intel.com,
platform-driver-x86@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH 4/6] platform/wmi: Extend wmidev_invoke_method() to reject undersized data
Date: Mon, 6 Apr 2026 22:32:35 +0200 [thread overview]
Message-ID: <20260406203237.2970-5-W_Armin@gmx.de> (raw)
In-Reply-To: <20260406203237.2970-1-W_Armin@gmx.de>
WMI drivers using the buffer-based WMI API are expected to reject
undersized method return values. Extend wmidev_invoke_method() to
enable the WMI driver core to perform this size check internally.
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
---
drivers/platform/wmi/core.c | 23 ++++++++++-------------
drivers/platform/x86/bitland-mifs-wmi.c | 11 +++--------
include/linux/wmi.h | 2 +-
3 files changed, 14 insertions(+), 22 deletions(-)
diff --git a/drivers/platform/wmi/core.c b/drivers/platform/wmi/core.c
index 66ec885bffd7..a1a612f33233 100644
--- a/drivers/platform/wmi/core.c
+++ b/drivers/platform/wmi/core.c
@@ -364,20 +364,23 @@ acpi_status wmidev_evaluate_method(struct wmi_device *wdev, u8 instance, u32 met
EXPORT_SYMBOL_GPL(wmidev_evaluate_method);
/**
- * wmidev_invoke_method - Invoke a WMI method
+ * wmidev_invoke_method - Invoke a WMI method that returns values
* @wdev: A wmi bus device from a driver
* @instance: Instance index
* @method_id: Method ID to call
* @in: Mandatory WMI buffer containing input for the method call
- * @out: Optional WMI buffer to return the method results
+ * @out: Mandatory WMI buffer to return the method results
+ * @min_size: Minimum size of the method result data in bytes
*
- * Invoke a WMI method, the caller must free the resulting data inside @out.
- * Said data is guaranteed to be aligned on a 8-byte boundary.
+ * Invoke a WMI method that returns values, the caller must free the resulting
+ * data inside @out using kfree(). Said data is guaranteed to be aligned on a
+ * 8-byte boundary. Use wmidev_invoke_procedure() for WMI methods that
+ * return no values.
*
* Return: 0 on success or negative error code on failure.
*/
int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
- const struct wmi_buffer *in, struct wmi_buffer *out)
+ const struct wmi_buffer *in, struct wmi_buffer *out, size_t min_size)
{
struct wmi_block *wblock = container_of(wdev, struct wmi_block, dev);
struct acpi_buffer aout = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -398,10 +401,7 @@ int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
ain.pointer = in->data;
}
- if (out)
- status = wmidev_evaluate_method(wdev, instance, method_id, &ain, &aout);
- else
- status = wmidev_evaluate_method(wdev, instance, method_id, &ain, NULL);
+ status = wmidev_evaluate_method(wdev, instance, method_id, &ain, &aout);
if (wblock->gblock.flags & ACPI_WMI_STRING)
kfree(ain.pointer);
@@ -409,9 +409,6 @@ int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
if (ACPI_FAILURE(status))
return -EIO;
- if (!out)
- return 0;
-
obj = aout.pointer;
if (!obj) {
out->length = 0;
@@ -420,7 +417,7 @@ int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
return 0;
}
- ret = wmi_unmarshal_acpi_object(obj, out, 0);
+ ret = wmi_unmarshal_acpi_object(obj, out, min_size);
kfree(obj);
return ret;
diff --git a/drivers/platform/x86/bitland-mifs-wmi.c b/drivers/platform/x86/bitland-mifs-wmi.c
index cd3cdd087511..78639407d67e 100644
--- a/drivers/platform/x86/bitland-mifs-wmi.c
+++ b/drivers/platform/x86/bitland-mifs-wmi.c
@@ -10,7 +10,6 @@
#include <linux/acpi.h>
#include <linux/array_size.h>
#include <linux/bits.h>
-#include <linux/cleanup.h>
#include <linux/container_of.h>
#include <linux/dev_printk.h>
#include <linux/device.h>
@@ -167,7 +166,6 @@ static int bitland_mifs_wmi_call(struct bitland_mifs_wmi_data *data,
struct bitland_mifs_output *output)
{
struct wmi_buffer in_buf = { .length = sizeof(*input), .data = (void *)input };
- void *out_data __free(kfree) = NULL;
struct wmi_buffer out_buf = { 0 };
int ret;
@@ -176,15 +174,12 @@ static int bitland_mifs_wmi_call(struct bitland_mifs_wmi_data *data,
if (!output)
return wmidev_invoke_procedure(data->wdev, 0, 1, &in_buf);
- ret = wmidev_invoke_method(data->wdev, 0, 1, &in_buf, &out_buf);
+ ret = wmidev_invoke_method(data->wdev, 0, 1, &in_buf, &out_buf, sizeof(*output));
if (ret)
return ret;
- out_data = out_buf.data;
- if (out_buf.length < sizeof(*output))
- return -EIO;
-
- memcpy(output, out_data, sizeof(*output));
+ memcpy(output, out_buf.data, sizeof(*output));
+ kfree(out_buf.data);
return 0;
}
diff --git a/include/linux/wmi.h b/include/linux/wmi.h
index b00950dc1231..858398beb01a 100644
--- a/include/linux/wmi.h
+++ b/include/linux/wmi.h
@@ -68,7 +68,7 @@ ssize_t wmi_string_from_utf8s(struct wmi_string *str, size_t max_chars, const u8
size_t src_length);
int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
- const struct wmi_buffer *in, struct wmi_buffer *out);
+ const struct wmi_buffer *in, struct wmi_buffer *out, size_t min_size);
int wmidev_invoke_procedure(struct wmi_device *wdev, u8 instance, u32 method_id,
const struct wmi_buffer *in);
--
2.39.5
next prev parent reply other threads:[~2026-04-06 21:17 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-06 20:32 [PATCH 0/6] platform/wmi: Use WMI driver core for size checks Armin Wolf
2026-04-06 20:32 ` [PATCH 1/6] platform/wmi: Add wmidev_invoke_procedure() Armin Wolf
2026-04-06 20:32 ` [PATCH 2/6] platform/wmi: Convert drivers to use wmidev_invoke_procedure() Armin Wolf
2026-04-06 20:32 ` [PATCH 3/6] platform/wmi: Prepare to reject undersized unmarshalling results Armin Wolf
2026-04-06 20:32 ` Armin Wolf [this message]
2026-04-06 20:32 ` [PATCH 5/6] platform/wmi: Extend wmidev_query_block() to reject undersized data Armin Wolf
2026-04-06 20:32 ` [PATCH 6/6] platform/wmi: Replace .no_notify_data with .min_event_size Armin Wolf
2026-04-10 16:28 ` [PATCH 0/6] platform/wmi: Use WMI driver core for size checks Ilpo Järvinen
2026-04-13 6:20 ` Armin Wolf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260406203237.2970-5-W_Armin@gmx.de \
--to=w_armin@gmx.de \
--cc=hansg@kernel.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=platform-driver-x86@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®