]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
platform/wmi: Prepare to reject undersized unmarshalling results
authorArmin Wolf <W_Armin@gmx.de>
Mon, 6 Apr 2026 20:32:34 +0000 (22:32 +0200)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Mon, 13 Apr 2026 11:11:22 +0000 (14:11 +0300)
Driver using the buffer-based WMI API usually reject buffers resulting
from WMI method calls or block queries if they contain not enough data.
Prepare the WMI core for assisting in this by automatically rejecting
undersized unmarshalling results.

Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/20260406203237.2970-4-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/wmi/internal.h
drivers/platform/wmi/marshalling.c
drivers/platform/wmi/tests/marshalling_kunit.c

index 7cc5ca11a60d067b125ca00608827885a35adc5d..66ec885bffd7afa992ed821421098528a96875dd 100644 (file)
@@ -420,7 +420,7 @@ int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
                return 0;
        }
 
-       ret = wmi_unmarshal_acpi_object(obj, out);
+       ret = wmi_unmarshal_acpi_object(obj, out, 0);
        kfree(obj);
 
        return ret;
@@ -583,7 +583,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);
+       ret = wmi_unmarshal_acpi_object(obj, out, 0);
        kfree(obj);
 
        return ret;
@@ -1416,7 +1416,7 @@ static void wmi_notify_driver(struct wmi_block *wblock, union acpi_object *obj)
                        return;
                }
 
-               ret = wmi_unmarshal_acpi_object(obj, &buffer);
+               ret = wmi_unmarshal_acpi_object(obj, &buffer, 0);
                if (ret < 0) {
                        dev_warn(&wblock->dev.dev, "Failed to unmarshal event data: %d\n", ret);
                        return;
index 9a39ffa31ad156916cf4a115e09ccd2e0f128319..c02908694563339dc280127c1d67e1e47afcfba7 100644 (file)
@@ -11,7 +11,8 @@
 union acpi_object;
 struct wmi_buffer;
 
-int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer);
+int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer,
+                             size_t min_size);
 int wmi_marshal_string(const struct wmi_buffer *buffer, struct acpi_buffer *out);
 
 #endif /* _WMI_INTERNAL_H_ */
index 63a92c4ebab53c6232b37b66afe0bf476ef7ba03..87091832568e5bebee38ace8e1c403e5f4ed332a 100644 (file)
@@ -151,7 +151,8 @@ static int wmi_obj_transform(const union acpi_object *obj, u8 *buffer)
        return 0;
 }
 
-int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer)
+int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer,
+                             size_t min_size)
 {
        size_t length, alloc_length;
        u8 *data;
@@ -161,6 +162,9 @@ int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *b
        if (ret < 0)
                return ret;
 
+       if (length < min_size)
+               return -ENODATA;
+
        if (ARCH_KMALLOC_MINALIGN < 8) {
                /*
                 * kmalloc() guarantees that the alignment of the resulting memory allocation is at
index 0c7cd8774aa30b2fead78709f33f062635724924..471963076d588cad6357ab9a987bfadfd8f03986 100644 (file)
@@ -372,7 +372,7 @@ static void wmi_unmarshal_acpi_object_test(struct kunit *test)
        struct wmi_buffer result;
        int ret;
 
-       ret = wmi_unmarshal_acpi_object(&param->obj, &result);
+       ret = wmi_unmarshal_acpi_object(&param->obj, &result, param->buffer.length);
        if (ret < 0)
                KUNIT_FAIL_AND_ABORT(test, "Unmarshalling of ACPI object failed\n");
 
@@ -389,7 +389,7 @@ static void wmi_unmarshal_acpi_object_failure_test(struct kunit *test)
        struct wmi_buffer result;
        int ret;
 
-       ret = wmi_unmarshal_acpi_object(&param->obj, &result);
+       ret = wmi_unmarshal_acpi_object(&param->obj, &result, 0);
        if (ret < 0)
                return;
 
@@ -427,6 +427,25 @@ static void wmi_marshal_string_failure_test(struct kunit *test)
        KUNIT_FAIL(test, "Invalid string was not rejected\n");
 }
 
+static void wmi_unmarshal_acpi_object_undersized_test(struct kunit *test)
+{
+       const union acpi_object obj = {
+               .integer = {
+                       .type = ACPI_TYPE_INTEGER,
+                       .value = 0xdeadbeef,
+               },
+       };
+       struct wmi_buffer result;
+       int ret;
+
+       ret = wmi_unmarshal_acpi_object(&obj, &result, sizeof(expected_single_integer) + 1);
+       if (ret < 0)
+               return;
+
+       kfree(result.data);
+       KUNIT_FAIL(test, "Undersized unmarshalling result was not rejected\n");
+}
+
 static struct kunit_case wmi_marshalling_test_cases[] = {
        KUNIT_CASE_PARAM(wmi_unmarshal_acpi_object_test,
                         wmi_unmarshal_acpi_object_gen_params),
@@ -436,6 +455,7 @@ static struct kunit_case wmi_marshalling_test_cases[] = {
                         wmi_unmarshal_acpi_object_failure_gen_params),
        KUNIT_CASE_PARAM(wmi_marshal_string_failure_test,
                         wmi_marshal_string_failure_gen_params),
+       KUNIT_CASE(wmi_unmarshal_acpi_object_undersized_test),
        {}
 };