]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
platform/wmi: Extend wmidev_query_block() to reject undersized data
authorArmin Wolf <W_Armin@gmx.de>
Mon, 6 Apr 2026 20:32:36 +0000 (22:32 +0200)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Mon, 13 Apr 2026 11:11:25 +0000 (14:11 +0300)
WMI drivers using the buffer-based WMI API are expected to reject
undersized query results. Extend wmidev_query_block() to enable
the WMI driver core to perform this size check internally.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/20260406203237.2970-6-W_Armin@gmx.de
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/wmi/core.c
drivers/platform/x86/intel/wmi/sbl-fw-update.c
drivers/platform/x86/wmi-bmof.c
include/linux/wmi.h

index a1a612f33233e9a0858e3a5e4545fd518f04147c..87b0e54dde5a6d5aefefc7b6db6602c7e7528d16 100644 (file)
@@ -565,13 +565,15 @@ EXPORT_SYMBOL_GPL(wmidev_block_query);
  * @wdev: A wmi bus device from a driver
  * @instance: Instance index
  * @out: WMI buffer to fill
+ * @min_size: Minimum size of the result data in bytes
  *
- * Query a WMI data block, the caller must free the resulting data inside @out.
- * Said data is guaranteed to be aligned on a 8-byte boundary.
+ * Query a WMI data block, the caller must free the resulting data inside @out
+ * using kfree(). Said data is guaranteed to be aligned on a 8-byte boundary.
  *
  * Return: 0 on success or a negative error code on failure.
  */
-int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *out)
+int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *out,
+                      size_t min_size)
 {
        union acpi_object *obj;
        int ret;
@@ -580,7 +582,7 @@ int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *
        if (!obj)
                return -EIO;
 
-       ret = wmi_unmarshal_acpi_object(obj, out, 0);
+       ret = wmi_unmarshal_acpi_object(obj, out, min_size);
        kfree(obj);
 
        return ret;
index 3716ccaaed6a5ab6e74ffe45f2e1c7de057908c2..62c9c7f1842ba7ba6467a0ae7c90ae0cccfce845 100644 (file)
@@ -28,15 +28,10 @@ static int get_fwu_request(struct device *dev, u32 *out)
        __le32 *result;
        int ret;
 
-       ret = wmidev_query_block(to_wmi_device(dev), 0, &buffer);
+       ret = wmidev_query_block(to_wmi_device(dev), 0, &buffer, sizeof(*result));
        if (ret < 0)
                return ret;
 
-       if (buffer.length < sizeof(*result)) {
-               kfree(buffer.data);
-               return -ENODATA;
-       }
-
        result = buffer.data;
        *out = le32_to_cpu(*result);
        kfree(result);
index e3a126de421b57417a0e8127afdc7f3f3391487d..6623cf60e4b4d7eb951c0d293b9d1f806c354a10 100644 (file)
@@ -62,7 +62,7 @@ static int wmi_bmof_probe(struct wmi_device *wdev, const void *context)
        if (!buffer)
                return -ENOMEM;
 
-       ret = wmidev_query_block(wdev, 0, buffer);
+       ret = wmidev_query_block(wdev, 0, buffer, 0);
        if (ret < 0)
                return ret;
 
index 858398beb01a6fb4bfcd92b3ac51420bf710b1c5..da94580572a91b12ff9fb7f1c3fd967a927450ee 100644 (file)
@@ -73,7 +73,8 @@ int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
 int wmidev_invoke_procedure(struct wmi_device *wdev, u8 instance, u32 method_id,
                            const struct wmi_buffer *in);
 
-int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *out);
+int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *out,
+                      size_t min_size);
 
 int wmidev_set_block(struct wmi_device *wdev, u8 instance, const struct wmi_buffer *in);