usb-host-max3421-fix-shift-out-of-bounds-in-max3421_.patch
usb-host-max3421-reject-hub-port-requests-for-non-ex.patch
char-tlclk-fix-use-after-free-in-tlclk_cleanup.patch
-thunderbolt-test-add-kunit-regression-tests-for-xdom.patch
-thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch
-thunderbolt-test-add-kunit-tests-for-property-parser.patch
perf-header-sanity-check-header_event_desc-attr.size.patch
iio-light-si1133-reset-counter-to-prevent-race-condi.patch
iio-light-si1133-prevent-race-condition-on-timeout.patch
+++ /dev/null
-From cc950f463bdc0ed583d962ccd43ea9d6442a7166 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Sep 2025 12:46:11 +0300
-Subject: thunderbolt: Add KUnit test for tb_property_merge_dir()
-
-From: Mika Westerberg <mika.westerberg@linux.intel.com>
-
-[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ]
-
-This makes sure it keeps working if we ever need to change it.
-
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 82 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 4411026613a825..3f57b0d98a3c62 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2802,6 +2802,87 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_merge(struct kunit *test)
-+{
-+ struct tb_property_dir *dir1, *dir2, *dir3;
-+ struct tb_property *p;
-+ uuid_t uuid;
-+ int ret;
-+
-+ dir1 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir1);
-+ ret = tb_property_add_immediate(dir1, "prtcid", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcvers", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcrevs", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcstns", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ dir2 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir2);
-+ ret = tb_property_add_text(dir2, "descr", "This is text");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ /* This replaces the value in dir1 */
-+ ret = tb_property_add_immediate(dir2, "prtcvers", 0x1234);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ uuid_gen(&uuid);
-+ dir3 = tb_property_create_dir(&uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir3);
-+ ret = tb_property_add_immediate(dir3, "value0", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_text(dir3, "value1", "Text value");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_dir(dir2, "my", dir3);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ ret = tb_property_merge_dir(dir1, dir2, true);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ p = tb_property_get_next(dir1, NULL);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcid");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 1);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcvers");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0x1234);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcrevs");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcstns");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "descr");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_TEXT);
-+ KUNIT_ASSERT_EQ(test, p->length, 4);
-+ KUNIT_ASSERT_STREQ(test, p->value.text, "This is text");
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "my");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_DIRECTORY);
-+ compare_dirs(test, p->value.dir, dir3);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NULL(test, p);
-+
-+ tb_property_free_dir(dir2);
-+ tb_property_free_dir(dir1);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse_u32_wrap),
- KUNIT_CASE(tb_test_property_parse_recursion),
-@@ -2843,6 +2924,7 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_merge),
- { }
- };
-
---
-2.53.0
-
+++ /dev/null
-From 753a4b28485ff9fe37ed0c720ba0954286d70732 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 10 May 2026 19:16:59 -0400
-Subject: thunderbolt: test: add KUnit regression tests for XDomain property
- parser
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit c12b5ee30fb665133b3119283cfe7ce9474e3589 ]
-
-Add three KUnit cases that exercise the defects fixed by the sibling
-commits in this series by feeding crafted XDomain property blocks to
-tb_property_parse_dir():
-
- tb_test_property_parse_u32_wrap - entry->value = 0xffffff00 and
- entry->length = 0x100 so their u32 sum 0x100000000 wraps to 0
- under the block_len guard; without the fix the subsequent
- parse_dwdata() reads attacker-directed OOB memory.
-
- tb_test_property_parse_recursion - two DIRECTORY entries pointing
- at each other, driving __tb_property_parse_dir() recursion;
- without the fix the kernel stack is exhausted.
-
- tb_test_property_parse_dir_len_underflow - a DIRECTORY entry with
- length < 4 placed near the end of the block so the non-root UUID
- kmemdup of 4 dwords from dir_offset reads OOB before the later
- content_len = dir_len - 4 underflow path is reached.
-
-Each test asserts tb_property_parse_dir() returns NULL on the
-crafted input. With CONFIG_KASAN=y, running these on the pre-fix
-kernel produces an oops inside __tb_property_parse_dir or its
-callees: u32_wrap takes a page fault on the KASAN shadow lookup for
-the wild ~16 GiB OOB offset; recursion trips a KASAN out-of-bounds
-report in __unwind_start as the per-task kernel stack is consumed;
-dir_len_underflow trips a KASAN slab-out-of-bounds report in
-kmemdup_noprof reading 16 bytes past the 28-byte block. Post-fix
-they pass cleanly.
-
-The crafted blocks are populated by writing u32 dwords directly,
-matching the existing root_directory[] style used elsewhere in
-this file rather than imposing a private struct overlay.
-
-Run with:
- ./tools/testing/kunit/kunit.py run --arch=x86_64 \
- --kconfig_add CONFIG_PCI=y --kconfig_add CONFIG_NVMEM=y \
- --kconfig_add CONFIG_USB4=y --kconfig_add CONFIG_USB4_KUNIT_TEST=y \
- --kconfig_add CONFIG_KASAN=y 'thunderbolt.tb_test_property_parse_*'
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 126 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 126 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 66b6e665e96f0b..4411026613a825 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2679,7 +2679,133 @@ static void tb_test_property_copy(struct kunit *test)
- tb_property_free_dir(src);
- }
-
-+/*
-+ * Reproducers for three memory-safety defects in
-+ * drivers/thunderbolt/property.c reached from a crafted XDomain
-+ * PROPERTIES_RESPONSE payload. Without the fix these trip KASAN or
-+ * smash the kernel stack; with the fix each returns NULL cleanly.
-+ *
-+ * The on-wire entry layout matches struct tb_property_entry in
-+ * property.c (private to that translation unit): u32 key_hi, u32
-+ * key_lo, then a packed u32 = (type << 24) | (reserved << 16) |
-+ * length, then u32 value. Each entry is 4 dwords.
-+ */
-+
-+static void tb_test_property_parse_u32_wrap(struct kunit *test)
-+{
-+ /*
-+ * 0x102 dwords: enough for the entry's length field (0x100) to
-+ * pass the "entry->length > block_len" gate so the wrap check
-+ * is actually exercised. parse_dwdata's downstream OOB read
-+ * lands ~16 GiB past the allocation regardless.
-+ */
-+ u32 *block = kunit_kzalloc(test, 0x102 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DATA entry whose value 0xffffff00 + length 0x100 wrap to 0
-+ * in u32, passing the sum <= block_len guard even though the
-+ * real offset is far past the allocation.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x64000100; /* type=DATA, reserved=0, length=0x100 */
-+ block[5] = 0xffffff00; /* value */
-+
-+ dir = tb_property_parse_dir(block, 0x102);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_recursion(struct kunit *test)
-+{
-+ /*
-+ * 10 dwords: rootdir header (2) + parent DIRECTORY entry (4) +
-+ * the child entry that lives at dir_offset(2) + UUID(4) = 6,
-+ * occupying block[6..9]. Each recursive level re-reads the
-+ * same block[6..9] as its first child entry, which is itself
-+ * a DIRECTORY pointing at offset 2.
-+ */
-+ u32 *block = kunit_kzalloc(test, 10 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry pointing at dir_offset = 2 with length = 8.
-+ * Non-root parse derives content_offset = 6, content_len = 4,
-+ * nentries = 1. block[6..9] is read both as the parent's UUID
-+ * (kmemdup'd into dir->uuid) and as the single child entry --
-+ * which is itself a DIRECTORY pointing at offset 2, so the
-+ * recursion never terminates and the kernel stack is exhausted.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[5] = 0x00000002; /* value = dir_offset */
-+
-+ block[6] = 0x62626262; /* doubles as UUID dword 0 / child key_hi */
-+ block[7] = 0x62626262; /* doubles as UUID dword 1 / child key_lo */
-+ block[8] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[9] = 0x00000002; /* value = dir_offset (back at parent) */
-+
-+ dir = tb_property_parse_dir(block, 10);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
-+{
-+ /*
-+ * Allocate exactly 7 dwords (28 bytes) so the kmalloc-32 chunk
-+ * leaves a 4-byte slab redzone tail that KASAN-Generic can flag.
-+ * With block_len = 7, dir_offset = 4, dir_len = 3, the non-root
-+ * UUID kmemdup reads 16 bytes from byte 16, so bytes 28..31 fall
-+ * in the redzone and trip a KASAN slab-out-of-bounds report on
-+ * the pre-fix kernel. Sizing the buffer at a power of two (32,
-+ * 64, ...) puts the over-read into the slab cache tail where
-+ * KASAN's generic shadow does not flag it, and the test reduces
-+ * to the downstream content_len = dir_len - 4 underflow path
-+ * which also returns NULL.
-+ */
-+ u32 *block = kunit_kzalloc(test, 7 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry with length = 3 pointing at dir_offset = 4.
-+ * tb_property_entry_valid() permits value(4) + length(3) <=
-+ * block_len(7). Non-root parse begins with a kmemdup of 4
-+ * dwords from dir_offset for the UUID; that read runs past the
-+ * 28-byte allocation before the dir_len < 4 reject would fire.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000003; /* type=DIRECTORY, reserved=0, length=3 */
-+ block[5] = 0x00000004; /* value = dir_offset */
-+ /* block[6] is the start of the four UUID dwords; block[7..] is OOB. */
-+
-+ dir = tb_property_parse_dir(block, 7);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
-+ KUNIT_CASE(tb_test_property_parse_u32_wrap),
-+ KUNIT_CASE(tb_test_property_parse_recursion),
-+ KUNIT_CASE(tb_test_property_parse_dir_len_underflow),
- KUNIT_CASE(tb_test_path_basic),
- KUNIT_CASE(tb_test_path_not_connected_walk),
- KUNIT_CASE(tb_test_path_single_hop_walk),
---
-2.53.0
-
+++ /dev/null
-From c1e97bfd56b0e7c78cabaa13f5138f03ddba9071 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 May 2026 05:28:30 -0400
-Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit d73a08958e66849ea713d2f458b2fcf7b183f987 ]
-
-Add regression tests for the zero-length entry and root directory
-bounds fixes:
-
-- tb_test_property_parse_zero_length: TEXT entry with length 0
- must be rejected by the validator.
-
-- tb_test_property_parse_rootdir_overflow: root directory whose
- content_offset + content_len exceeds block_len must be rejected.
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 40 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 3f57b0d98a3c62..c64a6977e61447 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2802,6 +2802,44 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_parse_zero_length(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 6 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length: one entry */
-+
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x74000000; /* type=TEXT, reserved=0, length=0 */
-+ block[5] = 0x00000000; /* value */
-+
-+ dir = tb_property_parse_dir(block, 6);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_rootdir_overflow(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 4 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length claims 4 dwords of content */
-+ block[2] = 0x61616161;
-+ block[3] = 0x61616161;
-+
-+ /* content_offset(2) + content_len(4) = 6 > block_len(4) */
-+ dir = tb_property_parse_dir(block, 4);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static void tb_test_property_merge(struct kunit *test)
- {
- struct tb_property_dir *dir1, *dir2, *dir3;
-@@ -2924,6 +2962,8 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_parse_zero_length),
-+ KUNIT_CASE(tb_test_property_parse_rootdir_overflow),
- KUNIT_CASE(tb_test_property_merge),
- { }
- };
---
-2.53.0
-
usb-host-max3421-fix-shift-out-of-bounds-in-max3421_.patch
usb-host-max3421-reject-hub-port-requests-for-non-ex.patch
char-tlclk-fix-use-after-free-in-tlclk_cleanup.patch
-thunderbolt-test-add-kunit-regression-tests-for-xdom.patch
-thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch
-thunderbolt-test-add-kunit-tests-for-property-parser.patch
perf-header-sanity-check-header_event_desc-attr.size.patch
iio-light-si1133-reset-counter-to-prevent-race-condi.patch
iio-light-si1133-prevent-race-condition-on-timeout.patch
+++ /dev/null
-From 00f372f44b5e01638854d7e2efa22512eddca999 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Sep 2025 12:46:11 +0300
-Subject: thunderbolt: Add KUnit test for tb_property_merge_dir()
-
-From: Mika Westerberg <mika.westerberg@linux.intel.com>
-
-[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ]
-
-This makes sure it keeps working if we ever need to change it.
-
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 82 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index bc6a2c780beab3..ca110661bdc52c 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2893,6 +2893,87 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_merge(struct kunit *test)
-+{
-+ struct tb_property_dir *dir1, *dir2, *dir3;
-+ struct tb_property *p;
-+ uuid_t uuid;
-+ int ret;
-+
-+ dir1 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir1);
-+ ret = tb_property_add_immediate(dir1, "prtcid", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcvers", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcrevs", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcstns", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ dir2 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir2);
-+ ret = tb_property_add_text(dir2, "descr", "This is text");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ /* This replaces the value in dir1 */
-+ ret = tb_property_add_immediate(dir2, "prtcvers", 0x1234);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ uuid_gen(&uuid);
-+ dir3 = tb_property_create_dir(&uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir3);
-+ ret = tb_property_add_immediate(dir3, "value0", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_text(dir3, "value1", "Text value");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_dir(dir2, "my", dir3);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ ret = tb_property_merge_dir(dir1, dir2, true);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ p = tb_property_get_next(dir1, NULL);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcid");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 1);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcvers");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0x1234);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcrevs");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcstns");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "descr");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_TEXT);
-+ KUNIT_ASSERT_EQ(test, p->length, 4);
-+ KUNIT_ASSERT_STREQ(test, p->value.text, "This is text");
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "my");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_DIRECTORY);
-+ compare_dirs(test, p->value.dir, dir3);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NULL(test, p);
-+
-+ tb_property_free_dir(dir2);
-+ tb_property_free_dir(dir1);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse_u32_wrap),
- KUNIT_CASE(tb_test_property_parse_recursion),
-@@ -2935,6 +3016,7 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_merge),
- { }
- };
-
---
-2.53.0
-
+++ /dev/null
-From 1cb1c9a5d73c2eb03a2b204c3e64b75b1829e434 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 10 May 2026 19:16:59 -0400
-Subject: thunderbolt: test: add KUnit regression tests for XDomain property
- parser
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit c12b5ee30fb665133b3119283cfe7ce9474e3589 ]
-
-Add three KUnit cases that exercise the defects fixed by the sibling
-commits in this series by feeding crafted XDomain property blocks to
-tb_property_parse_dir():
-
- tb_test_property_parse_u32_wrap - entry->value = 0xffffff00 and
- entry->length = 0x100 so their u32 sum 0x100000000 wraps to 0
- under the block_len guard; without the fix the subsequent
- parse_dwdata() reads attacker-directed OOB memory.
-
- tb_test_property_parse_recursion - two DIRECTORY entries pointing
- at each other, driving __tb_property_parse_dir() recursion;
- without the fix the kernel stack is exhausted.
-
- tb_test_property_parse_dir_len_underflow - a DIRECTORY entry with
- length < 4 placed near the end of the block so the non-root UUID
- kmemdup of 4 dwords from dir_offset reads OOB before the later
- content_len = dir_len - 4 underflow path is reached.
-
-Each test asserts tb_property_parse_dir() returns NULL on the
-crafted input. With CONFIG_KASAN=y, running these on the pre-fix
-kernel produces an oops inside __tb_property_parse_dir or its
-callees: u32_wrap takes a page fault on the KASAN shadow lookup for
-the wild ~16 GiB OOB offset; recursion trips a KASAN out-of-bounds
-report in __unwind_start as the per-task kernel stack is consumed;
-dir_len_underflow trips a KASAN slab-out-of-bounds report in
-kmemdup_noprof reading 16 bytes past the 28-byte block. Post-fix
-they pass cleanly.
-
-The crafted blocks are populated by writing u32 dwords directly,
-matching the existing root_directory[] style used elsewhere in
-this file rather than imposing a private struct overlay.
-
-Run with:
- ./tools/testing/kunit/kunit.py run --arch=x86_64 \
- --kconfig_add CONFIG_PCI=y --kconfig_add CONFIG_NVMEM=y \
- --kconfig_add CONFIG_USB4=y --kconfig_add CONFIG_USB4_KUNIT_TEST=y \
- --kconfig_add CONFIG_KASAN=y 'thunderbolt.tb_test_property_parse_*'
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 126 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 126 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 24c06e7354cd48..bc6a2c780beab3 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2770,7 +2770,133 @@ static void tb_test_property_copy(struct kunit *test)
- tb_property_free_dir(src);
- }
-
-+/*
-+ * Reproducers for three memory-safety defects in
-+ * drivers/thunderbolt/property.c reached from a crafted XDomain
-+ * PROPERTIES_RESPONSE payload. Without the fix these trip KASAN or
-+ * smash the kernel stack; with the fix each returns NULL cleanly.
-+ *
-+ * The on-wire entry layout matches struct tb_property_entry in
-+ * property.c (private to that translation unit): u32 key_hi, u32
-+ * key_lo, then a packed u32 = (type << 24) | (reserved << 16) |
-+ * length, then u32 value. Each entry is 4 dwords.
-+ */
-+
-+static void tb_test_property_parse_u32_wrap(struct kunit *test)
-+{
-+ /*
-+ * 0x102 dwords: enough for the entry's length field (0x100) to
-+ * pass the "entry->length > block_len" gate so the wrap check
-+ * is actually exercised. parse_dwdata's downstream OOB read
-+ * lands ~16 GiB past the allocation regardless.
-+ */
-+ u32 *block = kunit_kzalloc(test, 0x102 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DATA entry whose value 0xffffff00 + length 0x100 wrap to 0
-+ * in u32, passing the sum <= block_len guard even though the
-+ * real offset is far past the allocation.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x64000100; /* type=DATA, reserved=0, length=0x100 */
-+ block[5] = 0xffffff00; /* value */
-+
-+ dir = tb_property_parse_dir(block, 0x102);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_recursion(struct kunit *test)
-+{
-+ /*
-+ * 10 dwords: rootdir header (2) + parent DIRECTORY entry (4) +
-+ * the child entry that lives at dir_offset(2) + UUID(4) = 6,
-+ * occupying block[6..9]. Each recursive level re-reads the
-+ * same block[6..9] as its first child entry, which is itself
-+ * a DIRECTORY pointing at offset 2.
-+ */
-+ u32 *block = kunit_kzalloc(test, 10 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry pointing at dir_offset = 2 with length = 8.
-+ * Non-root parse derives content_offset = 6, content_len = 4,
-+ * nentries = 1. block[6..9] is read both as the parent's UUID
-+ * (kmemdup'd into dir->uuid) and as the single child entry --
-+ * which is itself a DIRECTORY pointing at offset 2, so the
-+ * recursion never terminates and the kernel stack is exhausted.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[5] = 0x00000002; /* value = dir_offset */
-+
-+ block[6] = 0x62626262; /* doubles as UUID dword 0 / child key_hi */
-+ block[7] = 0x62626262; /* doubles as UUID dword 1 / child key_lo */
-+ block[8] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[9] = 0x00000002; /* value = dir_offset (back at parent) */
-+
-+ dir = tb_property_parse_dir(block, 10);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
-+{
-+ /*
-+ * Allocate exactly 7 dwords (28 bytes) so the kmalloc-32 chunk
-+ * leaves a 4-byte slab redzone tail that KASAN-Generic can flag.
-+ * With block_len = 7, dir_offset = 4, dir_len = 3, the non-root
-+ * UUID kmemdup reads 16 bytes from byte 16, so bytes 28..31 fall
-+ * in the redzone and trip a KASAN slab-out-of-bounds report on
-+ * the pre-fix kernel. Sizing the buffer at a power of two (32,
-+ * 64, ...) puts the over-read into the slab cache tail where
-+ * KASAN's generic shadow does not flag it, and the test reduces
-+ * to the downstream content_len = dir_len - 4 underflow path
-+ * which also returns NULL.
-+ */
-+ u32 *block = kunit_kzalloc(test, 7 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry with length = 3 pointing at dir_offset = 4.
-+ * tb_property_entry_valid() permits value(4) + length(3) <=
-+ * block_len(7). Non-root parse begins with a kmemdup of 4
-+ * dwords from dir_offset for the UUID; that read runs past the
-+ * 28-byte allocation before the dir_len < 4 reject would fire.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000003; /* type=DIRECTORY, reserved=0, length=3 */
-+ block[5] = 0x00000004; /* value = dir_offset */
-+ /* block[6] is the start of the four UUID dwords; block[7..] is OOB. */
-+
-+ dir = tb_property_parse_dir(block, 7);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
-+ KUNIT_CASE(tb_test_property_parse_u32_wrap),
-+ KUNIT_CASE(tb_test_property_parse_recursion),
-+ KUNIT_CASE(tb_test_property_parse_dir_len_underflow),
- KUNIT_CASE(tb_test_path_basic),
- KUNIT_CASE(tb_test_path_not_connected_walk),
- KUNIT_CASE(tb_test_path_single_hop_walk),
---
-2.53.0
-
+++ /dev/null
-From a37e7649f50dfbe1b186a9a94b9eaf2e1ac50af5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 May 2026 05:28:30 -0400
-Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit d73a08958e66849ea713d2f458b2fcf7b183f987 ]
-
-Add regression tests for the zero-length entry and root directory
-bounds fixes:
-
-- tb_test_property_parse_zero_length: TEXT entry with length 0
- must be rejected by the validator.
-
-- tb_test_property_parse_rootdir_overflow: root directory whose
- content_offset + content_len exceeds block_len must be rejected.
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 40 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index ca110661bdc52c..474ad941c9dde9 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2893,6 +2893,44 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_parse_zero_length(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 6 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length: one entry */
-+
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x74000000; /* type=TEXT, reserved=0, length=0 */
-+ block[5] = 0x00000000; /* value */
-+
-+ dir = tb_property_parse_dir(block, 6);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_rootdir_overflow(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 4 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length claims 4 dwords of content */
-+ block[2] = 0x61616161;
-+ block[3] = 0x61616161;
-+
-+ /* content_offset(2) + content_len(4) = 6 > block_len(4) */
-+ dir = tb_property_parse_dir(block, 4);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static void tb_test_property_merge(struct kunit *test)
- {
- struct tb_property_dir *dir1, *dir2, *dir3;
-@@ -3016,6 +3054,8 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_parse_zero_length),
-+ KUNIT_CASE(tb_test_property_parse_rootdir_overflow),
- KUNIT_CASE(tb_test_property_merge),
- { }
- };
---
-2.53.0
-
usb-host-max3421-fix-shift-out-of-bounds-in-max3421_.patch
usb-host-max3421-reject-hub-port-requests-for-non-ex.patch
char-tlclk-fix-use-after-free-in-tlclk_cleanup.patch
-thunderbolt-test-add-kunit-regression-tests-for-xdom.patch
-thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch
-thunderbolt-test-add-kunit-tests-for-property-parser.patch
pci-qcom-disable-aspm-l0s-for-sa8775p.patch
perf-header-sanity-check-header_event_desc-attr.size.patch
iio-light-si1133-reset-counter-to-prevent-race-condi.patch
+++ /dev/null
-From d8d295756d87e47f61a915081f4a6905e88f03ba Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Sep 2025 12:46:11 +0300
-Subject: thunderbolt: Add KUnit test for tb_property_merge_dir()
-
-From: Mika Westerberg <mika.westerberg@linux.intel.com>
-
-[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ]
-
-This makes sure it keeps working if we ever need to change it.
-
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 82 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index df6307242bef89..88a8adae906103 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,87 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_merge(struct kunit *test)
-+{
-+ struct tb_property_dir *dir1, *dir2, *dir3;
-+ struct tb_property *p;
-+ uuid_t uuid;
-+ int ret;
-+
-+ dir1 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir1);
-+ ret = tb_property_add_immediate(dir1, "prtcid", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcvers", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcrevs", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcstns", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ dir2 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir2);
-+ ret = tb_property_add_text(dir2, "descr", "This is text");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ /* This replaces the value in dir1 */
-+ ret = tb_property_add_immediate(dir2, "prtcvers", 0x1234);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ uuid_gen(&uuid);
-+ dir3 = tb_property_create_dir(&uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir3);
-+ ret = tb_property_add_immediate(dir3, "value0", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_text(dir3, "value1", "Text value");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_dir(dir2, "my", dir3);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ ret = tb_property_merge_dir(dir1, dir2, true);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ p = tb_property_get_next(dir1, NULL);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcid");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 1);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcvers");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0x1234);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcrevs");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcstns");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "descr");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_TEXT);
-+ KUNIT_ASSERT_EQ(test, p->length, 4);
-+ KUNIT_ASSERT_STREQ(test, p->value.text, "This is text");
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "my");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_DIRECTORY);
-+ compare_dirs(test, p->value.dir, dir3);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NULL(test, p);
-+
-+ tb_property_free_dir(dir2);
-+ tb_property_free_dir(dir1);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse_u32_wrap),
- KUNIT_CASE(tb_test_property_parse_recursion),
-@@ -3018,6 +3099,7 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_merge),
- { }
- };
-
---
-2.53.0
-
+++ /dev/null
-From 2e677c90f5c59018e6740531c1dde647e8a24460 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 10 May 2026 19:16:59 -0400
-Subject: thunderbolt: test: add KUnit regression tests for XDomain property
- parser
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit c12b5ee30fb665133b3119283cfe7ce9474e3589 ]
-
-Add three KUnit cases that exercise the defects fixed by the sibling
-commits in this series by feeding crafted XDomain property blocks to
-tb_property_parse_dir():
-
- tb_test_property_parse_u32_wrap - entry->value = 0xffffff00 and
- entry->length = 0x100 so their u32 sum 0x100000000 wraps to 0
- under the block_len guard; without the fix the subsequent
- parse_dwdata() reads attacker-directed OOB memory.
-
- tb_test_property_parse_recursion - two DIRECTORY entries pointing
- at each other, driving __tb_property_parse_dir() recursion;
- without the fix the kernel stack is exhausted.
-
- tb_test_property_parse_dir_len_underflow - a DIRECTORY entry with
- length < 4 placed near the end of the block so the non-root UUID
- kmemdup of 4 dwords from dir_offset reads OOB before the later
- content_len = dir_len - 4 underflow path is reached.
-
-Each test asserts tb_property_parse_dir() returns NULL on the
-crafted input. With CONFIG_KASAN=y, running these on the pre-fix
-kernel produces an oops inside __tb_property_parse_dir or its
-callees: u32_wrap takes a page fault on the KASAN shadow lookup for
-the wild ~16 GiB OOB offset; recursion trips a KASAN out-of-bounds
-report in __unwind_start as the per-task kernel stack is consumed;
-dir_len_underflow trips a KASAN slab-out-of-bounds report in
-kmemdup_noprof reading 16 bytes past the 28-byte block. Post-fix
-they pass cleanly.
-
-The crafted blocks are populated by writing u32 dwords directly,
-matching the existing root_directory[] style used elsewhere in
-this file rather than imposing a private struct overlay.
-
-Run with:
- ./tools/testing/kunit/kunit.py run --arch=x86_64 \
- --kconfig_add CONFIG_PCI=y --kconfig_add CONFIG_NVMEM=y \
- --kconfig_add CONFIG_USB4=y --kconfig_add CONFIG_USB4_KUNIT_TEST=y \
- --kconfig_add CONFIG_KASAN=y 'thunderbolt.tb_test_property_parse_*'
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 126 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 126 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 9475c6698c7dde..df6307242bef89 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2852,7 +2852,133 @@ static void tb_test_property_copy(struct kunit *test)
- tb_property_free_dir(src);
- }
-
-+/*
-+ * Reproducers for three memory-safety defects in
-+ * drivers/thunderbolt/property.c reached from a crafted XDomain
-+ * PROPERTIES_RESPONSE payload. Without the fix these trip KASAN or
-+ * smash the kernel stack; with the fix each returns NULL cleanly.
-+ *
-+ * The on-wire entry layout matches struct tb_property_entry in
-+ * property.c (private to that translation unit): u32 key_hi, u32
-+ * key_lo, then a packed u32 = (type << 24) | (reserved << 16) |
-+ * length, then u32 value. Each entry is 4 dwords.
-+ */
-+
-+static void tb_test_property_parse_u32_wrap(struct kunit *test)
-+{
-+ /*
-+ * 0x102 dwords: enough for the entry's length field (0x100) to
-+ * pass the "entry->length > block_len" gate so the wrap check
-+ * is actually exercised. parse_dwdata's downstream OOB read
-+ * lands ~16 GiB past the allocation regardless.
-+ */
-+ u32 *block = kunit_kzalloc(test, 0x102 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DATA entry whose value 0xffffff00 + length 0x100 wrap to 0
-+ * in u32, passing the sum <= block_len guard even though the
-+ * real offset is far past the allocation.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x64000100; /* type=DATA, reserved=0, length=0x100 */
-+ block[5] = 0xffffff00; /* value */
-+
-+ dir = tb_property_parse_dir(block, 0x102);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_recursion(struct kunit *test)
-+{
-+ /*
-+ * 10 dwords: rootdir header (2) + parent DIRECTORY entry (4) +
-+ * the child entry that lives at dir_offset(2) + UUID(4) = 6,
-+ * occupying block[6..9]. Each recursive level re-reads the
-+ * same block[6..9] as its first child entry, which is itself
-+ * a DIRECTORY pointing at offset 2.
-+ */
-+ u32 *block = kunit_kzalloc(test, 10 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry pointing at dir_offset = 2 with length = 8.
-+ * Non-root parse derives content_offset = 6, content_len = 4,
-+ * nentries = 1. block[6..9] is read both as the parent's UUID
-+ * (kmemdup'd into dir->uuid) and as the single child entry --
-+ * which is itself a DIRECTORY pointing at offset 2, so the
-+ * recursion never terminates and the kernel stack is exhausted.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[5] = 0x00000002; /* value = dir_offset */
-+
-+ block[6] = 0x62626262; /* doubles as UUID dword 0 / child key_hi */
-+ block[7] = 0x62626262; /* doubles as UUID dword 1 / child key_lo */
-+ block[8] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[9] = 0x00000002; /* value = dir_offset (back at parent) */
-+
-+ dir = tb_property_parse_dir(block, 10);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
-+{
-+ /*
-+ * Allocate exactly 7 dwords (28 bytes) so the kmalloc-32 chunk
-+ * leaves a 4-byte slab redzone tail that KASAN-Generic can flag.
-+ * With block_len = 7, dir_offset = 4, dir_len = 3, the non-root
-+ * UUID kmemdup reads 16 bytes from byte 16, so bytes 28..31 fall
-+ * in the redzone and trip a KASAN slab-out-of-bounds report on
-+ * the pre-fix kernel. Sizing the buffer at a power of two (32,
-+ * 64, ...) puts the over-read into the slab cache tail where
-+ * KASAN's generic shadow does not flag it, and the test reduces
-+ * to the downstream content_len = dir_len - 4 underflow path
-+ * which also returns NULL.
-+ */
-+ u32 *block = kunit_kzalloc(test, 7 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry with length = 3 pointing at dir_offset = 4.
-+ * tb_property_entry_valid() permits value(4) + length(3) <=
-+ * block_len(7). Non-root parse begins with a kmemdup of 4
-+ * dwords from dir_offset for the UUID; that read runs past the
-+ * 28-byte allocation before the dir_len < 4 reject would fire.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000003; /* type=DIRECTORY, reserved=0, length=3 */
-+ block[5] = 0x00000004; /* value = dir_offset */
-+ /* block[6] is the start of the four UUID dwords; block[7..] is OOB. */
-+
-+ dir = tb_property_parse_dir(block, 7);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
-+ KUNIT_CASE(tb_test_property_parse_u32_wrap),
-+ KUNIT_CASE(tb_test_property_parse_recursion),
-+ KUNIT_CASE(tb_test_property_parse_dir_len_underflow),
- KUNIT_CASE(tb_test_path_basic),
- KUNIT_CASE(tb_test_path_not_connected_walk),
- KUNIT_CASE(tb_test_path_single_hop_walk),
---
-2.53.0
-
+++ /dev/null
-From 187470fa922ce87a10d88bd3d695b9b00be021ce Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 May 2026 05:28:30 -0400
-Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit d73a08958e66849ea713d2f458b2fcf7b183f987 ]
-
-Add regression tests for the zero-length entry and root directory
-bounds fixes:
-
-- tb_test_property_parse_zero_length: TEXT entry with length 0
- must be rejected by the validator.
-
-- tb_test_property_parse_rootdir_overflow: root directory whose
- content_offset + content_len exceeds block_len must be rejected.
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 40 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 88a8adae906103..28a791c5a34c91 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,44 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_parse_zero_length(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 6 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length: one entry */
-+
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x74000000; /* type=TEXT, reserved=0, length=0 */
-+ block[5] = 0x00000000; /* value */
-+
-+ dir = tb_property_parse_dir(block, 6);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_rootdir_overflow(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 4 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length claims 4 dwords of content */
-+ block[2] = 0x61616161;
-+ block[3] = 0x61616161;
-+
-+ /* content_offset(2) + content_len(4) = 6 > block_len(4) */
-+ dir = tb_property_parse_dir(block, 4);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static void tb_test_property_merge(struct kunit *test)
- {
- struct tb_property_dir *dir1, *dir2, *dir3;
-@@ -3099,6 +3137,8 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_parse_zero_length),
-+ KUNIT_CASE(tb_test_property_parse_rootdir_overflow),
- KUNIT_CASE(tb_test_property_merge),
- { }
- };
---
-2.53.0
-
gpib-fix-double-decrement-of-descriptor_busy-in-comm.patch
gpib-cb7210-fix-region-leak-when-request_irq-fails.patch
clk-renesas-rzg2l-rename-iterator-in-for_each_mod_cl.patch
-thunderbolt-test-add-kunit-regression-tests-for-xdom.patch
-thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch
-thunderbolt-test-add-kunit-tests-for-property-parser.patch
powerpc-tools-perf-initialize-error-code-in-auxtrace.patch
pci-qcom-disable-aspm-l0s-for-sa8775p.patch
perf-header-sanity-check-header_event_desc-attr.size.patch
+++ /dev/null
-From 3b32ca97cdec2e6691a4bdf11173e5105b7466dc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Sep 2025 12:46:11 +0300
-Subject: thunderbolt: Add KUnit test for tb_property_merge_dir()
-
-From: Mika Westerberg <mika.westerberg@linux.intel.com>
-
-[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ]
-
-This makes sure it keeps working if we ever need to change it.
-
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 82 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index f41fabf15456aa..fa8bee0ccf8b6a 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,87 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_merge(struct kunit *test)
-+{
-+ struct tb_property_dir *dir1, *dir2, *dir3;
-+ struct tb_property *p;
-+ uuid_t uuid;
-+ int ret;
-+
-+ dir1 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir1);
-+ ret = tb_property_add_immediate(dir1, "prtcid", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcvers", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcrevs", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcstns", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ dir2 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir2);
-+ ret = tb_property_add_text(dir2, "descr", "This is text");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ /* This replaces the value in dir1 */
-+ ret = tb_property_add_immediate(dir2, "prtcvers", 0x1234);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ uuid_gen(&uuid);
-+ dir3 = tb_property_create_dir(&uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir3);
-+ ret = tb_property_add_immediate(dir3, "value0", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_text(dir3, "value1", "Text value");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_dir(dir2, "my", dir3);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ ret = tb_property_merge_dir(dir1, dir2, true);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ p = tb_property_get_next(dir1, NULL);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcid");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 1);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcvers");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0x1234);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcrevs");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcstns");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "descr");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_TEXT);
-+ KUNIT_ASSERT_EQ(test, p->length, 4);
-+ KUNIT_ASSERT_STREQ(test, p->value.text, "This is text");
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "my");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_DIRECTORY);
-+ compare_dirs(test, p->value.dir, dir3);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NULL(test, p);
-+
-+ tb_property_free_dir(dir2);
-+ tb_property_free_dir(dir1);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse_u32_wrap),
- KUNIT_CASE(tb_test_property_parse_recursion),
-@@ -3018,6 +3099,7 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_merge),
- { }
- };
-
---
-2.53.0
-
+++ /dev/null
-From c9af08697fb51f426337b92feddb9a8409415d43 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 10 May 2026 19:16:59 -0400
-Subject: thunderbolt: test: add KUnit regression tests for XDomain property
- parser
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit c12b5ee30fb665133b3119283cfe7ce9474e3589 ]
-
-Add three KUnit cases that exercise the defects fixed by the sibling
-commits in this series by feeding crafted XDomain property blocks to
-tb_property_parse_dir():
-
- tb_test_property_parse_u32_wrap - entry->value = 0xffffff00 and
- entry->length = 0x100 so their u32 sum 0x100000000 wraps to 0
- under the block_len guard; without the fix the subsequent
- parse_dwdata() reads attacker-directed OOB memory.
-
- tb_test_property_parse_recursion - two DIRECTORY entries pointing
- at each other, driving __tb_property_parse_dir() recursion;
- without the fix the kernel stack is exhausted.
-
- tb_test_property_parse_dir_len_underflow - a DIRECTORY entry with
- length < 4 placed near the end of the block so the non-root UUID
- kmemdup of 4 dwords from dir_offset reads OOB before the later
- content_len = dir_len - 4 underflow path is reached.
-
-Each test asserts tb_property_parse_dir() returns NULL on the
-crafted input. With CONFIG_KASAN=y, running these on the pre-fix
-kernel produces an oops inside __tb_property_parse_dir or its
-callees: u32_wrap takes a page fault on the KASAN shadow lookup for
-the wild ~16 GiB OOB offset; recursion trips a KASAN out-of-bounds
-report in __unwind_start as the per-task kernel stack is consumed;
-dir_len_underflow trips a KASAN slab-out-of-bounds report in
-kmemdup_noprof reading 16 bytes past the 28-byte block. Post-fix
-they pass cleanly.
-
-The crafted blocks are populated by writing u32 dwords directly,
-matching the existing root_directory[] style used elsewhere in
-this file rather than imposing a private struct overlay.
-
-Run with:
- ./tools/testing/kunit/kunit.py run --arch=x86_64 \
- --kconfig_add CONFIG_PCI=y --kconfig_add CONFIG_NVMEM=y \
- --kconfig_add CONFIG_USB4=y --kconfig_add CONFIG_USB4_KUNIT_TEST=y \
- --kconfig_add CONFIG_KASAN=y 'thunderbolt.tb_test_property_parse_*'
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 126 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 126 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 1f4318249c2262..f41fabf15456aa 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2852,7 +2852,133 @@ static void tb_test_property_copy(struct kunit *test)
- tb_property_free_dir(src);
- }
-
-+/*
-+ * Reproducers for three memory-safety defects in
-+ * drivers/thunderbolt/property.c reached from a crafted XDomain
-+ * PROPERTIES_RESPONSE payload. Without the fix these trip KASAN or
-+ * smash the kernel stack; with the fix each returns NULL cleanly.
-+ *
-+ * The on-wire entry layout matches struct tb_property_entry in
-+ * property.c (private to that translation unit): u32 key_hi, u32
-+ * key_lo, then a packed u32 = (type << 24) | (reserved << 16) |
-+ * length, then u32 value. Each entry is 4 dwords.
-+ */
-+
-+static void tb_test_property_parse_u32_wrap(struct kunit *test)
-+{
-+ /*
-+ * 0x102 dwords: enough for the entry's length field (0x100) to
-+ * pass the "entry->length > block_len" gate so the wrap check
-+ * is actually exercised. parse_dwdata's downstream OOB read
-+ * lands ~16 GiB past the allocation regardless.
-+ */
-+ u32 *block = kunit_kzalloc(test, 0x102 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DATA entry whose value 0xffffff00 + length 0x100 wrap to 0
-+ * in u32, passing the sum <= block_len guard even though the
-+ * real offset is far past the allocation.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x64000100; /* type=DATA, reserved=0, length=0x100 */
-+ block[5] = 0xffffff00; /* value */
-+
-+ dir = tb_property_parse_dir(block, 0x102);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_recursion(struct kunit *test)
-+{
-+ /*
-+ * 10 dwords: rootdir header (2) + parent DIRECTORY entry (4) +
-+ * the child entry that lives at dir_offset(2) + UUID(4) = 6,
-+ * occupying block[6..9]. Each recursive level re-reads the
-+ * same block[6..9] as its first child entry, which is itself
-+ * a DIRECTORY pointing at offset 2.
-+ */
-+ u32 *block = kunit_kzalloc(test, 10 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry pointing at dir_offset = 2 with length = 8.
-+ * Non-root parse derives content_offset = 6, content_len = 4,
-+ * nentries = 1. block[6..9] is read both as the parent's UUID
-+ * (kmemdup'd into dir->uuid) and as the single child entry --
-+ * which is itself a DIRECTORY pointing at offset 2, so the
-+ * recursion never terminates and the kernel stack is exhausted.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[5] = 0x00000002; /* value = dir_offset */
-+
-+ block[6] = 0x62626262; /* doubles as UUID dword 0 / child key_hi */
-+ block[7] = 0x62626262; /* doubles as UUID dword 1 / child key_lo */
-+ block[8] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[9] = 0x00000002; /* value = dir_offset (back at parent) */
-+
-+ dir = tb_property_parse_dir(block, 10);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
-+{
-+ /*
-+ * Allocate exactly 7 dwords (28 bytes) so the kmalloc-32 chunk
-+ * leaves a 4-byte slab redzone tail that KASAN-Generic can flag.
-+ * With block_len = 7, dir_offset = 4, dir_len = 3, the non-root
-+ * UUID kmemdup reads 16 bytes from byte 16, so bytes 28..31 fall
-+ * in the redzone and trip a KASAN slab-out-of-bounds report on
-+ * the pre-fix kernel. Sizing the buffer at a power of two (32,
-+ * 64, ...) puts the over-read into the slab cache tail where
-+ * KASAN's generic shadow does not flag it, and the test reduces
-+ * to the downstream content_len = dir_len - 4 underflow path
-+ * which also returns NULL.
-+ */
-+ u32 *block = kunit_kzalloc(test, 7 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry with length = 3 pointing at dir_offset = 4.
-+ * tb_property_entry_valid() permits value(4) + length(3) <=
-+ * block_len(7). Non-root parse begins with a kmemdup of 4
-+ * dwords from dir_offset for the UUID; that read runs past the
-+ * 28-byte allocation before the dir_len < 4 reject would fire.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000003; /* type=DIRECTORY, reserved=0, length=3 */
-+ block[5] = 0x00000004; /* value = dir_offset */
-+ /* block[6] is the start of the four UUID dwords; block[7..] is OOB. */
-+
-+ dir = tb_property_parse_dir(block, 7);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
-+ KUNIT_CASE(tb_test_property_parse_u32_wrap),
-+ KUNIT_CASE(tb_test_property_parse_recursion),
-+ KUNIT_CASE(tb_test_property_parse_dir_len_underflow),
- KUNIT_CASE(tb_test_path_basic),
- KUNIT_CASE(tb_test_path_not_connected_walk),
- KUNIT_CASE(tb_test_path_single_hop_walk),
---
-2.53.0
-
+++ /dev/null
-From fc083aff80c5333781297017ddf2d6396b4d9da8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 May 2026 05:28:30 -0400
-Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit d73a08958e66849ea713d2f458b2fcf7b183f987 ]
-
-Add regression tests for the zero-length entry and root directory
-bounds fixes:
-
-- tb_test_property_parse_zero_length: TEXT entry with length 0
- must be rejected by the validator.
-
-- tb_test_property_parse_rootdir_overflow: root directory whose
- content_offset + content_len exceeds block_len must be rejected.
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 40 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index fa8bee0ccf8b6a..463186a1abf977 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,44 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_parse_zero_length(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 6 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length: one entry */
-+
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x74000000; /* type=TEXT, reserved=0, length=0 */
-+ block[5] = 0x00000000; /* value */
-+
-+ dir = tb_property_parse_dir(block, 6);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_rootdir_overflow(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 4 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length claims 4 dwords of content */
-+ block[2] = 0x61616161;
-+ block[3] = 0x61616161;
-+
-+ /* content_offset(2) + content_len(4) = 6 > block_len(4) */
-+ dir = tb_property_parse_dir(block, 4);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static void tb_test_property_merge(struct kunit *test)
- {
- struct tb_property_dir *dir1, *dir2, *dir3;
-@@ -3099,6 +3137,8 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_parse_zero_length),
-+ KUNIT_CASE(tb_test_property_parse_rootdir_overflow),
- KUNIT_CASE(tb_test_property_merge),
- { }
- };
---
-2.53.0
-
usb-host-max3421-fix-shift-out-of-bounds-in-max3421_.patch
usb-host-max3421-reject-hub-port-requests-for-non-ex.patch
char-tlclk-fix-use-after-free-in-tlclk_cleanup.patch
-thunderbolt-test-add-kunit-regression-tests-for-xdom.patch
-thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch
-thunderbolt-test-add-kunit-tests-for-property-parser.patch
perf-header-sanity-check-header_event_desc-attr.size.patch
iio-light-si1133-reset-counter-to-prevent-race-condi.patch
iio-light-si1133-prevent-race-condition-on-timeout.patch
+++ /dev/null
-From b92ea8dc99e5b7585238b933b577e1e72be1f474 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Sep 2025 12:46:11 +0300
-Subject: thunderbolt: Add KUnit test for tb_property_merge_dir()
-
-From: Mika Westerberg <mika.westerberg@linux.intel.com>
-
-[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ]
-
-This makes sure it keeps working if we ever need to change it.
-
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 82 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index df6307242bef89..88a8adae906103 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,87 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_merge(struct kunit *test)
-+{
-+ struct tb_property_dir *dir1, *dir2, *dir3;
-+ struct tb_property *p;
-+ uuid_t uuid;
-+ int ret;
-+
-+ dir1 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir1);
-+ ret = tb_property_add_immediate(dir1, "prtcid", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcvers", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcrevs", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcstns", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ dir2 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir2);
-+ ret = tb_property_add_text(dir2, "descr", "This is text");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ /* This replaces the value in dir1 */
-+ ret = tb_property_add_immediate(dir2, "prtcvers", 0x1234);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ uuid_gen(&uuid);
-+ dir3 = tb_property_create_dir(&uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir3);
-+ ret = tb_property_add_immediate(dir3, "value0", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_text(dir3, "value1", "Text value");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_dir(dir2, "my", dir3);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ ret = tb_property_merge_dir(dir1, dir2, true);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ p = tb_property_get_next(dir1, NULL);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcid");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 1);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcvers");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0x1234);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcrevs");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcstns");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "descr");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_TEXT);
-+ KUNIT_ASSERT_EQ(test, p->length, 4);
-+ KUNIT_ASSERT_STREQ(test, p->value.text, "This is text");
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "my");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_DIRECTORY);
-+ compare_dirs(test, p->value.dir, dir3);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NULL(test, p);
-+
-+ tb_property_free_dir(dir2);
-+ tb_property_free_dir(dir1);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse_u32_wrap),
- KUNIT_CASE(tb_test_property_parse_recursion),
-@@ -3018,6 +3099,7 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_merge),
- { }
- };
-
---
-2.53.0
-
+++ /dev/null
-From bc21d14fa221989d05576df23e47238c5592f00c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 10 May 2026 19:16:59 -0400
-Subject: thunderbolt: test: add KUnit regression tests for XDomain property
- parser
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit c12b5ee30fb665133b3119283cfe7ce9474e3589 ]
-
-Add three KUnit cases that exercise the defects fixed by the sibling
-commits in this series by feeding crafted XDomain property blocks to
-tb_property_parse_dir():
-
- tb_test_property_parse_u32_wrap - entry->value = 0xffffff00 and
- entry->length = 0x100 so their u32 sum 0x100000000 wraps to 0
- under the block_len guard; without the fix the subsequent
- parse_dwdata() reads attacker-directed OOB memory.
-
- tb_test_property_parse_recursion - two DIRECTORY entries pointing
- at each other, driving __tb_property_parse_dir() recursion;
- without the fix the kernel stack is exhausted.
-
- tb_test_property_parse_dir_len_underflow - a DIRECTORY entry with
- length < 4 placed near the end of the block so the non-root UUID
- kmemdup of 4 dwords from dir_offset reads OOB before the later
- content_len = dir_len - 4 underflow path is reached.
-
-Each test asserts tb_property_parse_dir() returns NULL on the
-crafted input. With CONFIG_KASAN=y, running these on the pre-fix
-kernel produces an oops inside __tb_property_parse_dir or its
-callees: u32_wrap takes a page fault on the KASAN shadow lookup for
-the wild ~16 GiB OOB offset; recursion trips a KASAN out-of-bounds
-report in __unwind_start as the per-task kernel stack is consumed;
-dir_len_underflow trips a KASAN slab-out-of-bounds report in
-kmemdup_noprof reading 16 bytes past the 28-byte block. Post-fix
-they pass cleanly.
-
-The crafted blocks are populated by writing u32 dwords directly,
-matching the existing root_directory[] style used elsewhere in
-this file rather than imposing a private struct overlay.
-
-Run with:
- ./tools/testing/kunit/kunit.py run --arch=x86_64 \
- --kconfig_add CONFIG_PCI=y --kconfig_add CONFIG_NVMEM=y \
- --kconfig_add CONFIG_USB4=y --kconfig_add CONFIG_USB4_KUNIT_TEST=y \
- --kconfig_add CONFIG_KASAN=y 'thunderbolt.tb_test_property_parse_*'
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 126 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 126 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 9475c6698c7dde..df6307242bef89 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2852,7 +2852,133 @@ static void tb_test_property_copy(struct kunit *test)
- tb_property_free_dir(src);
- }
-
-+/*
-+ * Reproducers for three memory-safety defects in
-+ * drivers/thunderbolt/property.c reached from a crafted XDomain
-+ * PROPERTIES_RESPONSE payload. Without the fix these trip KASAN or
-+ * smash the kernel stack; with the fix each returns NULL cleanly.
-+ *
-+ * The on-wire entry layout matches struct tb_property_entry in
-+ * property.c (private to that translation unit): u32 key_hi, u32
-+ * key_lo, then a packed u32 = (type << 24) | (reserved << 16) |
-+ * length, then u32 value. Each entry is 4 dwords.
-+ */
-+
-+static void tb_test_property_parse_u32_wrap(struct kunit *test)
-+{
-+ /*
-+ * 0x102 dwords: enough for the entry's length field (0x100) to
-+ * pass the "entry->length > block_len" gate so the wrap check
-+ * is actually exercised. parse_dwdata's downstream OOB read
-+ * lands ~16 GiB past the allocation regardless.
-+ */
-+ u32 *block = kunit_kzalloc(test, 0x102 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DATA entry whose value 0xffffff00 + length 0x100 wrap to 0
-+ * in u32, passing the sum <= block_len guard even though the
-+ * real offset is far past the allocation.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x64000100; /* type=DATA, reserved=0, length=0x100 */
-+ block[5] = 0xffffff00; /* value */
-+
-+ dir = tb_property_parse_dir(block, 0x102);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_recursion(struct kunit *test)
-+{
-+ /*
-+ * 10 dwords: rootdir header (2) + parent DIRECTORY entry (4) +
-+ * the child entry that lives at dir_offset(2) + UUID(4) = 6,
-+ * occupying block[6..9]. Each recursive level re-reads the
-+ * same block[6..9] as its first child entry, which is itself
-+ * a DIRECTORY pointing at offset 2.
-+ */
-+ u32 *block = kunit_kzalloc(test, 10 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry pointing at dir_offset = 2 with length = 8.
-+ * Non-root parse derives content_offset = 6, content_len = 4,
-+ * nentries = 1. block[6..9] is read both as the parent's UUID
-+ * (kmemdup'd into dir->uuid) and as the single child entry --
-+ * which is itself a DIRECTORY pointing at offset 2, so the
-+ * recursion never terminates and the kernel stack is exhausted.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[5] = 0x00000002; /* value = dir_offset */
-+
-+ block[6] = 0x62626262; /* doubles as UUID dword 0 / child key_hi */
-+ block[7] = 0x62626262; /* doubles as UUID dword 1 / child key_lo */
-+ block[8] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[9] = 0x00000002; /* value = dir_offset (back at parent) */
-+
-+ dir = tb_property_parse_dir(block, 10);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
-+{
-+ /*
-+ * Allocate exactly 7 dwords (28 bytes) so the kmalloc-32 chunk
-+ * leaves a 4-byte slab redzone tail that KASAN-Generic can flag.
-+ * With block_len = 7, dir_offset = 4, dir_len = 3, the non-root
-+ * UUID kmemdup reads 16 bytes from byte 16, so bytes 28..31 fall
-+ * in the redzone and trip a KASAN slab-out-of-bounds report on
-+ * the pre-fix kernel. Sizing the buffer at a power of two (32,
-+ * 64, ...) puts the over-read into the slab cache tail where
-+ * KASAN's generic shadow does not flag it, and the test reduces
-+ * to the downstream content_len = dir_len - 4 underflow path
-+ * which also returns NULL.
-+ */
-+ u32 *block = kunit_kzalloc(test, 7 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry with length = 3 pointing at dir_offset = 4.
-+ * tb_property_entry_valid() permits value(4) + length(3) <=
-+ * block_len(7). Non-root parse begins with a kmemdup of 4
-+ * dwords from dir_offset for the UUID; that read runs past the
-+ * 28-byte allocation before the dir_len < 4 reject would fire.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000003; /* type=DIRECTORY, reserved=0, length=3 */
-+ block[5] = 0x00000004; /* value = dir_offset */
-+ /* block[6] is the start of the four UUID dwords; block[7..] is OOB. */
-+
-+ dir = tb_property_parse_dir(block, 7);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
-+ KUNIT_CASE(tb_test_property_parse_u32_wrap),
-+ KUNIT_CASE(tb_test_property_parse_recursion),
-+ KUNIT_CASE(tb_test_property_parse_dir_len_underflow),
- KUNIT_CASE(tb_test_path_basic),
- KUNIT_CASE(tb_test_path_not_connected_walk),
- KUNIT_CASE(tb_test_path_single_hop_walk),
---
-2.53.0
-
+++ /dev/null
-From a5b981855312b9d7ceffe8c178746d995dab73f5 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 May 2026 05:28:30 -0400
-Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit d73a08958e66849ea713d2f458b2fcf7b183f987 ]
-
-Add regression tests for the zero-length entry and root directory
-bounds fixes:
-
-- tb_test_property_parse_zero_length: TEXT entry with length 0
- must be rejected by the validator.
-
-- tb_test_property_parse_rootdir_overflow: root directory whose
- content_offset + content_len exceeds block_len must be rejected.
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 40 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 88a8adae906103..28a791c5a34c91 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,44 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_parse_zero_length(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 6 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length: one entry */
-+
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x74000000; /* type=TEXT, reserved=0, length=0 */
-+ block[5] = 0x00000000; /* value */
-+
-+ dir = tb_property_parse_dir(block, 6);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_rootdir_overflow(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 4 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length claims 4 dwords of content */
-+ block[2] = 0x61616161;
-+ block[3] = 0x61616161;
-+
-+ /* content_offset(2) + content_len(4) = 6 > block_len(4) */
-+ dir = tb_property_parse_dir(block, 4);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static void tb_test_property_merge(struct kunit *test)
- {
- struct tb_property_dir *dir1, *dir2, *dir3;
-@@ -3099,6 +3137,8 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_parse_zero_length),
-+ KUNIT_CASE(tb_test_property_parse_rootdir_overflow),
- KUNIT_CASE(tb_test_property_merge),
- { }
- };
---
-2.53.0
-
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- fs/afs/cmservice.c | 2 --
+ fs/afs/cmservice.c | 2 --
1 file changed, 2 deletions(-)
-diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
-index 5540ae1cad599a..fe0072aaeb9012 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
-@@ -334,7 +334,6 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
+@@ -334,7 +334,6 @@ static int afs_deliver_cb_init_call_back
ret = afs_extract_data(call, false);
switch (ret) {
case 0: break;
default: return ret;
}
-@@ -451,7 +450,6 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call)
+@@ -456,7 +455,6 @@ static int afs_deliver_cb_probe_uuid(str
ret = afs_extract_data(call, false);
switch (ret) {
case 0: break;
default: return ret;
}
---
-2.53.0
-
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- fs/afs/inode.c | 1 +
- fs/afs/super.c | 2 +-
+ fs/afs/inode.c | 1 +
+ fs/afs/super.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
-diff --git a/fs/afs/inode.c b/fs/afs/inode.c
-index 51c28f14884549..14f39a9bea6cfe 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
-@@ -680,6 +680,7 @@ void afs_evict_inode(struct inode *inode)
+@@ -680,6 +680,7 @@ void afs_evict_inode(struct inode *inode
inode->i_mapping->a_ops->writepages(inode->i_mapping, &wbc);
}
netfs_wait_for_outstanding_io(inode);
truncate_inode_pages_final(&inode->i_data);
netfs_free_folioq_buffer(vnode->directory);
-diff --git a/fs/afs/super.c b/fs/afs/super.c
-index 942f3e9800d7dc..7fcb92ea3f6c48 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
-@@ -659,7 +659,6 @@ static void afs_i_init_once(void *_vnode)
+@@ -660,7 +660,6 @@ static void afs_i_init_once(void *_vnode
INIT_LIST_HEAD(&vnode->wb_keys);
INIT_LIST_HEAD(&vnode->pending_locks);
INIT_LIST_HEAD(&vnode->granted_locks);
INIT_LIST_HEAD(&vnode->cb_mmap_link);
seqlock_init(&vnode->cb_lock);
}
-@@ -693,6 +692,7 @@ static struct inode *afs_alloc_inode(struct super_block *sb)
+@@ -694,6 +693,7 @@ static struct inode *afs_alloc_inode(str
init_rwsem(&vnode->rmdir_lock);
INIT_WORK(&vnode->cb_work, afs_invalidate_mmap_work);
_leave(" = %p", &vnode->netfs.inode);
return &vnode->netfs.inode;
---
-2.53.0
-
gpib-cb7210-fix-region-leak-when-request_irq-fails.patch
clk-renesas-rzg2l-rename-iterator-in-for_each_mod_cl.patch
docs-threat-model-add-missing-closing-parenthesis.patch
-thunderbolt-test-add-kunit-regression-tests-for-xdom.patch
-thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch
-thunderbolt-test-add-kunit-tests-for-property-parser.patch
powerpc-tools-perf-initialize-error-code-in-auxtrace.patch
pci-qcom-disable-aspm-l0s-for-sa8775p.patch
timers-migration-update-stale-online-doc-to-availabl.patch
+++ /dev/null
-From c90df0082333e78a6021b435368e6899be38fd89 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 23 Sep 2025 12:46:11 +0300
-Subject: thunderbolt: Add KUnit test for tb_property_merge_dir()
-
-From: Mika Westerberg <mika.westerberg@linux.intel.com>
-
-[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ]
-
-This makes sure it keeps working if we ever need to change it.
-
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 82 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index f41fabf15456aa..fa8bee0ccf8b6a 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,87 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_merge(struct kunit *test)
-+{
-+ struct tb_property_dir *dir1, *dir2, *dir3;
-+ struct tb_property *p;
-+ uuid_t uuid;
-+ int ret;
-+
-+ dir1 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir1);
-+ ret = tb_property_add_immediate(dir1, "prtcid", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcvers", 1);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcrevs", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_immediate(dir1, "prtcstns", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ dir2 = tb_property_create_dir(&network_dir_uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir2);
-+ ret = tb_property_add_text(dir2, "descr", "This is text");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ /* This replaces the value in dir1 */
-+ ret = tb_property_add_immediate(dir2, "prtcvers", 0x1234);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ uuid_gen(&uuid);
-+ dir3 = tb_property_create_dir(&uuid);
-+ KUNIT_ASSERT_NOT_NULL(test, dir3);
-+ ret = tb_property_add_immediate(dir3, "value0", 0);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_text(dir3, "value1", "Text value");
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+ ret = tb_property_add_dir(dir2, "my", dir3);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ ret = tb_property_merge_dir(dir1, dir2, true);
-+ KUNIT_EXPECT_EQ(test, ret, 0);
-+
-+ p = tb_property_get_next(dir1, NULL);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcid");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 1);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcvers");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0x1234);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcrevs");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "prtcstns");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_VALUE);
-+ KUNIT_ASSERT_EQ(test, p->length, 1);
-+ KUNIT_ASSERT_EQ(test, p->value.immediate, 0);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "descr");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_TEXT);
-+ KUNIT_ASSERT_EQ(test, p->length, 4);
-+ KUNIT_ASSERT_STREQ(test, p->value.text, "This is text");
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NOT_NULL(test, p);
-+ KUNIT_ASSERT_STREQ(test, &p->key[0], "my");
-+ KUNIT_ASSERT_EQ(test, p->type, TB_PROPERTY_TYPE_DIRECTORY);
-+ compare_dirs(test, p->value.dir, dir3);
-+ p = tb_property_get_next(dir1, p);
-+ KUNIT_ASSERT_NULL(test, p);
-+
-+ tb_property_free_dir(dir2);
-+ tb_property_free_dir(dir1);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse_u32_wrap),
- KUNIT_CASE(tb_test_property_parse_recursion),
-@@ -3018,6 +3099,7 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_merge),
- { }
- };
-
---
-2.53.0
-
+++ /dev/null
-From 580aba94c5f2e8f55a778a8c6e13fd701c5a61b2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Sun, 10 May 2026 19:16:59 -0400
-Subject: thunderbolt: test: add KUnit regression tests for XDomain property
- parser
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit c12b5ee30fb665133b3119283cfe7ce9474e3589 ]
-
-Add three KUnit cases that exercise the defects fixed by the sibling
-commits in this series by feeding crafted XDomain property blocks to
-tb_property_parse_dir():
-
- tb_test_property_parse_u32_wrap - entry->value = 0xffffff00 and
- entry->length = 0x100 so their u32 sum 0x100000000 wraps to 0
- under the block_len guard; without the fix the subsequent
- parse_dwdata() reads attacker-directed OOB memory.
-
- tb_test_property_parse_recursion - two DIRECTORY entries pointing
- at each other, driving __tb_property_parse_dir() recursion;
- without the fix the kernel stack is exhausted.
-
- tb_test_property_parse_dir_len_underflow - a DIRECTORY entry with
- length < 4 placed near the end of the block so the non-root UUID
- kmemdup of 4 dwords from dir_offset reads OOB before the later
- content_len = dir_len - 4 underflow path is reached.
-
-Each test asserts tb_property_parse_dir() returns NULL on the
-crafted input. With CONFIG_KASAN=y, running these on the pre-fix
-kernel produces an oops inside __tb_property_parse_dir or its
-callees: u32_wrap takes a page fault on the KASAN shadow lookup for
-the wild ~16 GiB OOB offset; recursion trips a KASAN out-of-bounds
-report in __unwind_start as the per-task kernel stack is consumed;
-dir_len_underflow trips a KASAN slab-out-of-bounds report in
-kmemdup_noprof reading 16 bytes past the 28-byte block. Post-fix
-they pass cleanly.
-
-The crafted blocks are populated by writing u32 dwords directly,
-matching the existing root_directory[] style used elsewhere in
-this file rather than imposing a private struct overlay.
-
-Run with:
- ./tools/testing/kunit/kunit.py run --arch=x86_64 \
- --kconfig_add CONFIG_PCI=y --kconfig_add CONFIG_NVMEM=y \
- --kconfig_add CONFIG_USB4=y --kconfig_add CONFIG_USB4_KUNIT_TEST=y \
- --kconfig_add CONFIG_KASAN=y 'thunderbolt.tb_test_property_parse_*'
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 126 +++++++++++++++++++++++++++++++++++++
- 1 file changed, 126 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index 1f4318249c2262..f41fabf15456aa 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2852,7 +2852,133 @@ static void tb_test_property_copy(struct kunit *test)
- tb_property_free_dir(src);
- }
-
-+/*
-+ * Reproducers for three memory-safety defects in
-+ * drivers/thunderbolt/property.c reached from a crafted XDomain
-+ * PROPERTIES_RESPONSE payload. Without the fix these trip KASAN or
-+ * smash the kernel stack; with the fix each returns NULL cleanly.
-+ *
-+ * The on-wire entry layout matches struct tb_property_entry in
-+ * property.c (private to that translation unit): u32 key_hi, u32
-+ * key_lo, then a packed u32 = (type << 24) | (reserved << 16) |
-+ * length, then u32 value. Each entry is 4 dwords.
-+ */
-+
-+static void tb_test_property_parse_u32_wrap(struct kunit *test)
-+{
-+ /*
-+ * 0x102 dwords: enough for the entry's length field (0x100) to
-+ * pass the "entry->length > block_len" gate so the wrap check
-+ * is actually exercised. parse_dwdata's downstream OOB read
-+ * lands ~16 GiB past the allocation regardless.
-+ */
-+ u32 *block = kunit_kzalloc(test, 0x102 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DATA entry whose value 0xffffff00 + length 0x100 wrap to 0
-+ * in u32, passing the sum <= block_len guard even though the
-+ * real offset is far past the allocation.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x64000100; /* type=DATA, reserved=0, length=0x100 */
-+ block[5] = 0xffffff00; /* value */
-+
-+ dir = tb_property_parse_dir(block, 0x102);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_recursion(struct kunit *test)
-+{
-+ /*
-+ * 10 dwords: rootdir header (2) + parent DIRECTORY entry (4) +
-+ * the child entry that lives at dir_offset(2) + UUID(4) = 6,
-+ * occupying block[6..9]. Each recursive level re-reads the
-+ * same block[6..9] as its first child entry, which is itself
-+ * a DIRECTORY pointing at offset 2.
-+ */
-+ u32 *block = kunit_kzalloc(test, 10 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry pointing at dir_offset = 2 with length = 8.
-+ * Non-root parse derives content_offset = 6, content_len = 4,
-+ * nentries = 1. block[6..9] is read both as the parent's UUID
-+ * (kmemdup'd into dir->uuid) and as the single child entry --
-+ * which is itself a DIRECTORY pointing at offset 2, so the
-+ * recursion never terminates and the kernel stack is exhausted.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[5] = 0x00000002; /* value = dir_offset */
-+
-+ block[6] = 0x62626262; /* doubles as UUID dword 0 / child key_hi */
-+ block[7] = 0x62626262; /* doubles as UUID dword 1 / child key_lo */
-+ block[8] = 0x44000008; /* type=DIRECTORY, reserved=0, length=8 */
-+ block[9] = 0x00000002; /* value = dir_offset (back at parent) */
-+
-+ dir = tb_property_parse_dir(block, 10);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
-+{
-+ /*
-+ * Allocate exactly 7 dwords (28 bytes) so the kmalloc-32 chunk
-+ * leaves a 4-byte slab redzone tail that KASAN-Generic can flag.
-+ * With block_len = 7, dir_offset = 4, dir_len = 3, the non-root
-+ * UUID kmemdup reads 16 bytes from byte 16, so bytes 28..31 fall
-+ * in the redzone and trip a KASAN slab-out-of-bounds report on
-+ * the pre-fix kernel. Sizing the buffer at a power of two (32,
-+ * 64, ...) puts the over-read into the slab cache tail where
-+ * KASAN's generic shadow does not flag it, and the test reduces
-+ * to the downstream content_len = dir_len - 4 underflow path
-+ * which also returns NULL.
-+ */
-+ u32 *block = kunit_kzalloc(test, 7 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* "UXD" v1 magic */
-+ block[1] = 0x00000004; /* Root directory length: one entry */
-+
-+ /*
-+ * DIRECTORY entry with length = 3 pointing at dir_offset = 4.
-+ * tb_property_entry_valid() permits value(4) + length(3) <=
-+ * block_len(7). Non-root parse begins with a kmemdup of 4
-+ * dwords from dir_offset for the UUID; that read runs past the
-+ * 28-byte allocation before the dir_len < 4 reject would fire.
-+ */
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x44000003; /* type=DIRECTORY, reserved=0, length=3 */
-+ block[5] = 0x00000004; /* value = dir_offset */
-+ /* block[6] is the start of the four UUID dwords; block[7..] is OOB. */
-+
-+ dir = tb_property_parse_dir(block, 7);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static struct kunit_case tb_test_cases[] = {
-+ KUNIT_CASE(tb_test_property_parse_u32_wrap),
-+ KUNIT_CASE(tb_test_property_parse_recursion),
-+ KUNIT_CASE(tb_test_property_parse_dir_len_underflow),
- KUNIT_CASE(tb_test_path_basic),
- KUNIT_CASE(tb_test_path_not_connected_walk),
- KUNIT_CASE(tb_test_path_single_hop_walk),
---
-2.53.0
-
+++ /dev/null
-From d247fabfa7008569db953a8cd356a63627e10c3b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 May 2026 05:28:30 -0400
-Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks
-
-From: Michael Bommarito <michael.bommarito@gmail.com>
-
-[ Upstream commit d73a08958e66849ea713d2f458b2fcf7b183f987 ]
-
-Add regression tests for the zero-length entry and root directory
-bounds fixes:
-
-- tb_test_property_parse_zero_length: TEXT entry with length 0
- must be rejected by the validator.
-
-- tb_test_property_parse_rootdir_overflow: root directory whose
- content_offset + content_len exceeds block_len must be rejected.
-
-Assisted-by: Claude:claude-opus-4-7
-Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
-Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/thunderbolt/test.c | 40 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
-
-diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c
-index fa8bee0ccf8b6a..463186a1abf977 100644
---- a/drivers/thunderbolt/test.c
-+++ b/drivers/thunderbolt/test.c
-@@ -2975,6 +2975,44 @@ static void tb_test_property_parse_dir_len_underflow(struct kunit *test)
- tb_property_free_dir(dir);
- }
-
-+static void tb_test_property_parse_zero_length(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 6 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length: one entry */
-+
-+ block[2] = 0x61616161; /* key_hi */
-+ block[3] = 0x61616161; /* key_lo */
-+ block[4] = 0x74000000; /* type=TEXT, reserved=0, length=0 */
-+ block[5] = 0x00000000; /* value */
-+
-+ dir = tb_property_parse_dir(block, 6);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
-+static void tb_test_property_parse_rootdir_overflow(struct kunit *test)
-+{
-+ u32 *block = kunit_kzalloc(test, 4 * sizeof(u32), GFP_KERNEL);
-+ struct tb_property_dir *dir;
-+
-+ KUNIT_ASSERT_NOT_NULL(test, block);
-+
-+ block[0] = 0x55584401; /* rootdir magic */
-+ block[1] = 0x00000004; /* root length claims 4 dwords of content */
-+ block[2] = 0x61616161;
-+ block[3] = 0x61616161;
-+
-+ /* content_offset(2) + content_len(4) = 6 > block_len(4) */
-+ dir = tb_property_parse_dir(block, 4);
-+ KUNIT_EXPECT_NULL(test, dir);
-+ tb_property_free_dir(dir);
-+}
-+
- static void tb_test_property_merge(struct kunit *test)
- {
- struct tb_property_dir *dir1, *dir2, *dir3;
-@@ -3099,6 +3137,8 @@ static struct kunit_case tb_test_cases[] = {
- KUNIT_CASE(tb_test_property_parse),
- KUNIT_CASE(tb_test_property_format),
- KUNIT_CASE(tb_test_property_copy),
-+ KUNIT_CASE(tb_test_property_parse_zero_length),
-+ KUNIT_CASE(tb_test_property_parse_rootdir_overflow),
- KUNIT_CASE(tb_test_property_merge),
- { }
- };
---
-2.53.0
-