Skip to content

Commit 204b52f

Browse files
Wer-Wolfij-intel
authored andcommitted
platform/wmi: Prepare to reject undersized unmarshalling results
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>
1 parent 578bc2a commit 204b52f

4 files changed

Lines changed: 32 additions & 7 deletions

File tree

drivers/platform/wmi/core.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ int wmidev_invoke_method(struct wmi_device *wdev, u8 instance, u32 method_id,
420420
return 0;
421421
}
422422

423-
ret = wmi_unmarshal_acpi_object(obj, out);
423+
ret = wmi_unmarshal_acpi_object(obj, out, 0);
424424
kfree(obj);
425425

426426
return ret;
@@ -583,7 +583,7 @@ int wmidev_query_block(struct wmi_device *wdev, u8 instance, struct wmi_buffer *
583583
if (!obj)
584584
return -EIO;
585585

586-
ret = wmi_unmarshal_acpi_object(obj, out);
586+
ret = wmi_unmarshal_acpi_object(obj, out, 0);
587587
kfree(obj);
588588

589589
return ret;
@@ -1416,7 +1416,7 @@ static void wmi_notify_driver(struct wmi_block *wblock, union acpi_object *obj)
14161416
return;
14171417
}
14181418

1419-
ret = wmi_unmarshal_acpi_object(obj, &buffer);
1419+
ret = wmi_unmarshal_acpi_object(obj, &buffer, 0);
14201420
if (ret < 0) {
14211421
dev_warn(&wblock->dev.dev, "Failed to unmarshal event data: %d\n", ret);
14221422
return;

drivers/platform/wmi/internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
union acpi_object;
1212
struct wmi_buffer;
1313

14-
int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer);
14+
int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer,
15+
size_t min_size);
1516
int wmi_marshal_string(const struct wmi_buffer *buffer, struct acpi_buffer *out);
1617

1718
#endif /* _WMI_INTERNAL_H_ */

drivers/platform/wmi/marshalling.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ static int wmi_obj_transform(const union acpi_object *obj, u8 *buffer)
151151
return 0;
152152
}
153153

154-
int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer)
154+
int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *buffer,
155+
size_t min_size)
155156
{
156157
size_t length, alloc_length;
157158
u8 *data;
@@ -161,6 +162,9 @@ int wmi_unmarshal_acpi_object(const union acpi_object *obj, struct wmi_buffer *b
161162
if (ret < 0)
162163
return ret;
163164

165+
if (length < min_size)
166+
return -ENODATA;
167+
164168
if (ARCH_KMALLOC_MINALIGN < 8) {
165169
/*
166170
* kmalloc() guarantees that the alignment of the resulting memory allocation is at

drivers/platform/wmi/tests/marshalling_kunit.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ static void wmi_unmarshal_acpi_object_test(struct kunit *test)
372372
struct wmi_buffer result;
373373
int ret;
374374

375-
ret = wmi_unmarshal_acpi_object(&param->obj, &result);
375+
ret = wmi_unmarshal_acpi_object(&param->obj, &result, param->buffer.length);
376376
if (ret < 0)
377377
KUNIT_FAIL_AND_ABORT(test, "Unmarshalling of ACPI object failed\n");
378378

@@ -389,7 +389,7 @@ static void wmi_unmarshal_acpi_object_failure_test(struct kunit *test)
389389
struct wmi_buffer result;
390390
int ret;
391391

392-
ret = wmi_unmarshal_acpi_object(&param->obj, &result);
392+
ret = wmi_unmarshal_acpi_object(&param->obj, &result, 0);
393393
if (ret < 0)
394394
return;
395395

@@ -427,6 +427,25 @@ static void wmi_marshal_string_failure_test(struct kunit *test)
427427
KUNIT_FAIL(test, "Invalid string was not rejected\n");
428428
}
429429

430+
static void wmi_unmarshal_acpi_object_undersized_test(struct kunit *test)
431+
{
432+
const union acpi_object obj = {
433+
.integer = {
434+
.type = ACPI_TYPE_INTEGER,
435+
.value = 0xdeadbeef,
436+
},
437+
};
438+
struct wmi_buffer result;
439+
int ret;
440+
441+
ret = wmi_unmarshal_acpi_object(&obj, &result, sizeof(expected_single_integer) + 1);
442+
if (ret < 0)
443+
return;
444+
445+
kfree(result.data);
446+
KUNIT_FAIL(test, "Undersized unmarshalling result was not rejected\n");
447+
}
448+
430449
static struct kunit_case wmi_marshalling_test_cases[] = {
431450
KUNIT_CASE_PARAM(wmi_unmarshal_acpi_object_test,
432451
wmi_unmarshal_acpi_object_gen_params),
@@ -436,6 +455,7 @@ static struct kunit_case wmi_marshalling_test_cases[] = {
436455
wmi_unmarshal_acpi_object_failure_gen_params),
437456
KUNIT_CASE_PARAM(wmi_marshal_string_failure_test,
438457
wmi_marshal_string_failure_gen_params),
458+
KUNIT_CASE(wmi_unmarshal_acpi_object_undersized_test),
439459
{}
440460
};
441461

0 commit comments

Comments
 (0)