The snd_usb_copy_string_desc() retrieves the usb string corresponding to
the index number thought the usb_string(). And for NULL-terminated, insert
'0' by using the return value of usb_string() as the index of buffer to
hold the string.
The problem is that the usb_string() also returns the length of the string
read(>= 0), but it can also return a negative value, the error or status
value of usb_control_msg(). If iClockSource is '0' as shown below,
usb_string() will return -EINVAL. This will result in '0' being inserted
into buf[-22], and the following KASAN out-of-bound error message will be
output.
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 10 (CLOCK_SOURCE)
bClockID 1
bmAttributes 0x07 Internal programmable Clock (synced to SOF)
bmControls 0x07
Clock Frequency Control (read/write)
Clock Validity Control (read-only)
bAssocTerminal 0
iClockSource 0
To fix out-of-bound error, insert 0 only if the return value of
usb_string() is greater than 0.
==================================================================
BUG: KASAN: stack-out-of-bounds in parse_audio_unit+0x1327/0x1960 [snd_usb_audio]
Write of size 1 at addr ffff88007e66735a by task systemd-udevd/18376
CPU: 0 PID: 18376 Comm: systemd-udevd Not tainted 4.13.0+ #3
Hardware name: LG Electronics 15N540-RFLGL/White Tip Mountain, BIOS 15N5
Call Trace:
dump_stack+0x63/0x8d
print_address_description+0x70/0x290
? parse_audio_unit+0x1327/0x1960 [snd_usb_audio]
kasan_report+0x265/0x350
__asan_store1+0x4a/0x50
parse_audio_unit+0x1327/0x1960 [snd_usb_audio]
? save_stack+0xb5/0xd0
? save_stack_trace+0x1b/0x20
? save_stack+0x46/0xd0
? kasan_kmalloc+0xad/0xe0
? kmem_cache_alloc_trace+0xff/0x230
? snd_usb_create_mixer+0xb0/0x4b0 [snd_usb_audio]
? usb_audio_probe+0x4de/0xf40 [snd_usb_audio]
? usb_probe_interface+0x1f5/0x440
? driver_probe_device+0x3ed/0x660
? build_feature_ctl+0xb10/0xb10 [snd_usb_audio]
? save_stack_trace+0x1b/0x20
? init_object+0x69/0xa0
? snd_usb_find_csint_desc+0xa8/0xf0 [snd_usb_audio]
snd_usb_mixer_controls+0x1dc/0x370 [snd_usb_audio]
? build_audio_procunit+0x890/0x890 [snd_usb_audio]
? snd_usb_create_mixer+0xb0/0x4b0 [snd_usb_audio]
? kmem_cache_alloc_trace+0xff/0x230
? usb_ifnum_to_if+0xbd/0xf0
snd_usb_create_mixer+0x25b/0x4b0 [snd_usb_audio]
? snd_usb_create_stream+0x255/0x2c0 [snd_usb_audio]
usb_audio_probe+0x4de/0xf40 [snd_usb_audio]
? snd_usb_autosuspend.part.7+0x30/0x30 [snd_usb_audio]
? __pm_runtime_idle+0x90/0x90
? kernfs_activate+0xa6/0xc0
? usb_match_one_id_intf+0xdc/0x130
? __pm_runtime_set_status+0x2d4/0x450
usb_probe_interface+0x1f5/0x440
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Jaejoong Kim <climbbb.kim(a)gmail.com>
---
The AudioControl Interface Descriptor in commit message is from
lsusb output with real usb audio DAC.
The usb audio product causing the OOB are as follows:
http://www.lg.com/uk/lg-friends/lg-AFD-1200
It only prints OOB error and usb audio works well. :)
sound/usb/mixer.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index e630813..5a83c2c 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -204,7 +204,8 @@ static int snd_usb_copy_string_desc(struct mixer_build *state,
int index, char *buf, int maxlen)
{
int len = usb_string(state->chip->dev, index, buf, maxlen - 1);
- buf[len] = 0;
+ if (len > 0)
+ buf[len] = 0;
return len;
}
--
2.7.4
From: Bob Moore <robert.moore(a)intel.com>
[ Upstream commit 57707a9a7780fab426b8ae9b4c7b65b912a748b3 ]
ACPICA commit 9f76de2d249b18804e35fb55d14b1c2604d627a1
ACPICA commit b2e89d72ef1e9deefd63c3fd1dee90f893575b3a
ACPICA commit 23b5bbe6d78afd3c5abf3adb91a1b098a3000b2e
The declared buffer length must be the same as the length of the
byte initializer list, otherwise not a valid resource descriptor.
Link: https://github.com/acpica/acpica/commit/9f76de2d
Link: https://github.com/acpica/acpica/commit/b2e89d72
Link: https://github.com/acpica/acpica/commit/23b5bbe6
Signed-off-by: Bob Moore <robert.moore(a)intel.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Signed-off-by: Sasha Levin <alexander.levin(a)verizon.com>
---
drivers/acpi/acpica/utresrc.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c
index 5cd017c7ac0e..94b3ee013761 100644
--- a/drivers/acpi/acpica/utresrc.c
+++ b/drivers/acpi/acpica/utresrc.c
@@ -421,8 +421,10 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
- /* The absolute minimum resource template is one end_tag descriptor */
-
+ /*
+ * The absolute minimum resource template is one end_tag descriptor.
+ * However, we will treat a lone end_tag as just a simple buffer.
+ */
if (aml_length < sizeof(struct aml_resource_end_tag)) {
return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}
@@ -454,9 +456,8 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
/* Invoke the user function */
if (user_function) {
- status =
- user_function(aml, length, offset, resource_index,
- context);
+ status = user_function(aml, length, offset,
+ resource_index, context);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -480,6 +481,12 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
*context = aml;
}
+ /* Check if buffer is defined to be longer than the resource length */
+
+ if (aml_length > (offset + length)) {
+ return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
+ }
+
/* Normal exit */
return_ACPI_STATUS(AE_OK);
--
2.11.0
From: Bob Moore <robert.moore(a)intel.com>
[ Upstream commit 57707a9a7780fab426b8ae9b4c7b65b912a748b3 ]
ACPICA commit 9f76de2d249b18804e35fb55d14b1c2604d627a1
ACPICA commit b2e89d72ef1e9deefd63c3fd1dee90f893575b3a
ACPICA commit 23b5bbe6d78afd3c5abf3adb91a1b098a3000b2e
The declared buffer length must be the same as the length of the
byte initializer list, otherwise not a valid resource descriptor.
Link: https://github.com/acpica/acpica/commit/9f76de2d
Link: https://github.com/acpica/acpica/commit/b2e89d72
Link: https://github.com/acpica/acpica/commit/23b5bbe6
Signed-off-by: Bob Moore <robert.moore(a)intel.com>
Signed-off-by: Lv Zheng <lv.zheng(a)intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki(a)intel.com>
Signed-off-by: Sasha Levin <alexander.levin(a)verizon.com>
---
drivers/acpi/acpica/utresrc.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c
index b3505dbc715e..3f903f4855db 100644
--- a/drivers/acpi/acpica/utresrc.c
+++ b/drivers/acpi/acpica/utresrc.c
@@ -421,8 +421,10 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
ACPI_FUNCTION_TRACE(ut_walk_aml_resources);
- /* The absolute minimum resource template is one end_tag descriptor */
-
+ /*
+ * The absolute minimum resource template is one end_tag descriptor.
+ * However, we will treat a lone end_tag as just a simple buffer.
+ */
if (aml_length < sizeof(struct aml_resource_end_tag)) {
return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
}
@@ -454,9 +456,8 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
/* Invoke the user function */
if (user_function) {
- status =
- user_function(aml, length, offset, resource_index,
- context);
+ status = user_function(aml, length, offset,
+ resource_index, context);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -480,6 +481,12 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
*context = aml;
}
+ /* Check if buffer is defined to be longer than the resource length */
+
+ if (aml_length > (offset + length)) {
+ return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
+ }
+
/* Normal exit */
return_ACPI_STATUS(AE_OK);
--
2.11.0
Fix child node-lookup during probe, which ended up searching the whole
device tree depth-first starting at parent rather than just matching on
its children.
Note that the original premature free of the parent node has already
been fixed separately, but that fix was apparently never backported to
stable.
Fixes: 9ac33b0ce81f ("CLK: TI: Driver for DRA7 ATL (Audio Tracking Logic)")
Fixes: 660e15519399 ("clk: ti: dra7-atl-clock: Fix of_node reference counting")
Cc: stable <stable(a)vger.kernel.org> # 3.16: 660e15519399
Cc: Peter Ujfalusi <peter.ujfalusi(a)ti.com>
Signed-off-by: Johan Hovold <johan(a)kernel.org>
---
drivers/clk/ti/clk-dra7-atl.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c
index 13eb04f72389..148815470431 100644
--- a/drivers/clk/ti/clk-dra7-atl.c
+++ b/drivers/clk/ti/clk-dra7-atl.c
@@ -274,8 +274,7 @@ static int of_dra7_atl_clk_probe(struct platform_device *pdev)
/* Get configuration for the ATL instances */
snprintf(prop, sizeof(prop), "atl%u", i);
- of_node_get(node);
- cfg_node = of_find_node_by_name(node, prop);
+ cfg_node = of_get_child_by_name(node, prop);
if (cfg_node) {
ret = of_property_read_u32(cfg_node, "bws",
&cdesc->bws);
--
2.15.0