From: Greg Kroah-Hartman Date: Mon, 20 Jul 2026 11:18:38 +0000 (+0200) Subject: drop some broken thunderbolt patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f289bc5903c0656c00714f39bcecb982a523607b;p=thirdparty%2Fkernel%2Fstable-queue.git drop some broken thunderbolt patches --- diff --git a/queue-5.15/series b/queue-5.15/series index 72e981478d..cc07d4af89 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -384,9 +384,6 @@ staging-most-video-avoid-double-free-on-video-regist.patch 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 diff --git a/queue-5.15/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch b/queue-5.15/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch deleted file mode 100644 index 3f2ae6063a..0000000000 --- a/queue-5.15/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch +++ /dev/null @@ -1,121 +0,0 @@ -From cc950f463bdc0ed583d962ccd43ea9d6442a7166 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 23 Sep 2025 12:46:11 +0300 -Subject: thunderbolt: Add KUnit test for tb_property_merge_dir() - -From: Mika Westerberg - -[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ] - -This makes sure it keeps working if we ever need to change it. - -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.15/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch b/queue-5.15/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch deleted file mode 100644 index c8a16325af..0000000000 --- a/queue-5.15/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 753a4b28485ff9fe37ed0c720ba0954286d70732 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 10 May 2026 19:16:59 -0400 -Subject: thunderbolt: test: add KUnit regression tests for XDomain property - parser - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-5.15/thunderbolt-test-add-kunit-tests-for-property-parser.patch b/queue-5.15/thunderbolt-test-add-kunit-tests-for-property-parser.patch deleted file mode 100644 index d48151ede8..0000000000 --- a/queue-5.15/thunderbolt-test-add-kunit-tests-for-property-parser.patch +++ /dev/null @@ -1,87 +0,0 @@ -From c1e97bfd56b0e7c78cabaa13f5138f03ddba9071 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 May 2026 05:28:30 -0400 -Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.1/series b/queue-6.1/series index 7632a7492c..4930c7fc28 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -486,9 +486,6 @@ staging-most-video-avoid-double-free-on-video-regist.patch 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 diff --git a/queue-6.1/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch b/queue-6.1/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch deleted file mode 100644 index 08d9b136e8..0000000000 --- a/queue-6.1/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 00f372f44b5e01638854d7e2efa22512eddca999 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 23 Sep 2025 12:46:11 +0300 -Subject: thunderbolt: Add KUnit test for tb_property_merge_dir() - -From: Mika Westerberg - -[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ] - -This makes sure it keeps working if we ever need to change it. - -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.1/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch b/queue-6.1/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch deleted file mode 100644 index 4e0bfb87e5..0000000000 --- a/queue-6.1/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 1cb1c9a5d73c2eb03a2b204c3e64b75b1829e434 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 10 May 2026 19:16:59 -0400 -Subject: thunderbolt: test: add KUnit regression tests for XDomain property - parser - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.1/thunderbolt-test-add-kunit-tests-for-property-parser.patch b/queue-6.1/thunderbolt-test-add-kunit-tests-for-property-parser.patch deleted file mode 100644 index 5cd32fc578..0000000000 --- a/queue-6.1/thunderbolt-test-add-kunit-tests-for-property-parser.patch +++ /dev/null @@ -1,87 +0,0 @@ -From a37e7649f50dfbe1b186a9a94b9eaf2e1ac50af5 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 May 2026 05:28:30 -0400 -Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.12/series b/queue-6.12/series index 2c020299eb..73c6dc9523 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -442,9 +442,6 @@ staging-most-video-avoid-double-free-on-video-regist.patch 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 diff --git a/queue-6.12/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch b/queue-6.12/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch deleted file mode 100644 index 5e6cac9be4..0000000000 --- a/queue-6.12/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch +++ /dev/null @@ -1,121 +0,0 @@ -From d8d295756d87e47f61a915081f4a6905e88f03ba Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 23 Sep 2025 12:46:11 +0300 -Subject: thunderbolt: Add KUnit test for tb_property_merge_dir() - -From: Mika Westerberg - -[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ] - -This makes sure it keeps working if we ever need to change it. - -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.12/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch b/queue-6.12/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch deleted file mode 100644 index 4ebff79d9a..0000000000 --- a/queue-6.12/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 2e677c90f5c59018e6740531c1dde647e8a24460 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 10 May 2026 19:16:59 -0400 -Subject: thunderbolt: test: add KUnit regression tests for XDomain property - parser - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.12/thunderbolt-test-add-kunit-tests-for-property-parser.patch b/queue-6.12/thunderbolt-test-add-kunit-tests-for-property-parser.patch deleted file mode 100644 index bfccfc935c..0000000000 --- a/queue-6.12/thunderbolt-test-add-kunit-tests-for-property-parser.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 187470fa922ce87a10d88bd3d695b9b00be021ce Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 May 2026 05:28:30 -0400 -Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.18/series b/queue-6.18/series index 39bf45ea29..7f3a28cb5c 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -617,9 +617,6 @@ char-tlclk-fix-use-after-free-in-tlclk_cleanup.patch 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 diff --git a/queue-6.18/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch b/queue-6.18/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch deleted file mode 100644 index c50901823b..0000000000 --- a/queue-6.18/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 3b32ca97cdec2e6691a4bdf11173e5105b7466dc Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 23 Sep 2025 12:46:11 +0300 -Subject: thunderbolt: Add KUnit test for tb_property_merge_dir() - -From: Mika Westerberg - -[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ] - -This makes sure it keeps working if we ever need to change it. - -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.18/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch b/queue-6.18/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch deleted file mode 100644 index 693219380c..0000000000 --- a/queue-6.18/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch +++ /dev/null @@ -1,198 +0,0 @@ -From c9af08697fb51f426337b92feddb9a8409415d43 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 10 May 2026 19:16:59 -0400 -Subject: thunderbolt: test: add KUnit regression tests for XDomain property - parser - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.18/thunderbolt-test-add-kunit-tests-for-property-parser.patch b/queue-6.18/thunderbolt-test-add-kunit-tests-for-property-parser.patch deleted file mode 100644 index 0d1637118e..0000000000 --- a/queue-6.18/thunderbolt-test-add-kunit-tests-for-property-parser.patch +++ /dev/null @@ -1,87 +0,0 @@ -From fc083aff80c5333781297017ddf2d6396b4d9da8 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 May 2026 05:28:30 -0400 -Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.6/series b/queue-6.6/series index ca6432f6cc..d74ae100ab 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -620,9 +620,6 @@ staging-most-video-avoid-double-free-on-video-regist.patch 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 diff --git a/queue-6.6/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch b/queue-6.6/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch deleted file mode 100644 index 26b6c2e642..0000000000 --- a/queue-6.6/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch +++ /dev/null @@ -1,121 +0,0 @@ -From b92ea8dc99e5b7585238b933b577e1e72be1f474 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 23 Sep 2025 12:46:11 +0300 -Subject: thunderbolt: Add KUnit test for tb_property_merge_dir() - -From: Mika Westerberg - -[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ] - -This makes sure it keeps working if we ever need to change it. - -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.6/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch b/queue-6.6/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch deleted file mode 100644 index 83f297a006..0000000000 --- a/queue-6.6/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch +++ /dev/null @@ -1,198 +0,0 @@ -From bc21d14fa221989d05576df23e47238c5592f00c Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 10 May 2026 19:16:59 -0400 -Subject: thunderbolt: test: add KUnit regression tests for XDomain property - parser - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-6.6/thunderbolt-test-add-kunit-tests-for-property-parser.patch b/queue-6.6/thunderbolt-test-add-kunit-tests-for-property-parser.patch deleted file mode 100644 index 0ced56fd29..0000000000 --- a/queue-6.6/thunderbolt-test-add-kunit-tests-for-property-parser.patch +++ /dev/null @@ -1,87 +0,0 @@ -From a5b981855312b9d7ceffe8c178746d995dab73f5 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 May 2026 05:28:30 -0400 -Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-7.1/afs-fix-callback-service-message-parsers-to-pass-thr.patch b/queue-7.1/afs-fix-callback-service-message-parsers-to-pass-thr.patch index 6ee7bd8718..a1ddbb389b 100644 --- a/queue-7.1/afs-fix-callback-service-message-parsers-to-pass-thr.patch +++ b/queue-7.1/afs-fix-callback-service-message-parsers-to-pass-thr.patch @@ -25,14 +25,12 @@ cc: linux-afs@lists.infradead.org Signed-off-by: Christian Brauner (Amutable) Signed-off-by: Sasha Levin --- - 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; @@ -40,7 +38,7 @@ index 5540ae1cad599a..fe0072aaeb9012 100644 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; @@ -48,6 +46,3 @@ index 5540ae1cad599a..fe0072aaeb9012 100644 default: return ret; } --- -2.53.0 - diff --git a/queue-7.1/afs-fix-reinitialisation-of-the-inode-in-particular-.patch b/queue-7.1/afs-fix-reinitialisation-of-the-inode-in-particular-.patch index 1c8d0648bc..815f966d25 100644 --- a/queue-7.1/afs-fix-reinitialisation-of-the-inode-in-particular-.patch +++ b/queue-7.1/afs-fix-reinitialisation-of-the-inode-in-particular-.patch @@ -53,15 +53,13 @@ cc: linux-afs@lists.infradead.org Signed-off-by: Christian Brauner (Amutable) Signed-off-by: Sasha Levin --- - 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); } @@ -69,11 +67,9 @@ index 51c28f14884549..14f39a9bea6cfe 100644 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); @@ -81,7 +77,7 @@ index 942f3e9800d7dc..7fcb92ea3f6c48 100644 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); @@ -89,6 +85,3 @@ index 942f3e9800d7dc..7fcb92ea3f6c48 100644 _leave(" = %p", &vnode->netfs.inode); return &vnode->netfs.inode; --- -2.53.0 - diff --git a/queue-7.1/series b/queue-7.1/series index 2e0f5c5e06..7d5e34926f 100644 --- a/queue-7.1/series +++ b/queue-7.1/series @@ -910,9 +910,6 @@ 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 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 diff --git a/queue-7.1/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch b/queue-7.1/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch deleted file mode 100644 index 14930b7071..0000000000 --- a/queue-7.1/thunderbolt-add-kunit-test-for-tb_property_merge_dir.patch +++ /dev/null @@ -1,121 +0,0 @@ -From c90df0082333e78a6021b435368e6899be38fd89 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 23 Sep 2025 12:46:11 +0300 -Subject: thunderbolt: Add KUnit test for tb_property_merge_dir() - -From: Mika Westerberg - -[ Upstream commit aa4999c0297ae56143f67ecb3ef008a473afcc00 ] - -This makes sure it keeps working if we ever need to change it. - -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-7.1/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch b/queue-7.1/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch deleted file mode 100644 index 07b4817cca..0000000000 --- a/queue-7.1/thunderbolt-test-add-kunit-regression-tests-for-xdom.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 580aba94c5f2e8f55a778a8c6e13fd701c5a61b2 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sun, 10 May 2026 19:16:59 -0400 -Subject: thunderbolt: test: add KUnit regression tests for XDomain property - parser - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Stable-dep-of: d73a08958e66 ("thunderbolt: test: Add KUnit tests for property parser bounds checks") -Signed-off-by: Sasha Levin ---- - 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 - diff --git a/queue-7.1/thunderbolt-test-add-kunit-tests-for-property-parser.patch b/queue-7.1/thunderbolt-test-add-kunit-tests-for-property-parser.patch deleted file mode 100644 index 744d0e4d32..0000000000 --- a/queue-7.1/thunderbolt-test-add-kunit-tests-for-property-parser.patch +++ /dev/null @@ -1,87 +0,0 @@ -From d247fabfa7008569db953a8cd356a63627e10c3b Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 25 May 2026 05:28:30 -0400 -Subject: thunderbolt: test: Add KUnit tests for property parser bounds checks - -From: Michael Bommarito - -[ 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 -Signed-off-by: Mika Westerberg -Signed-off-by: Sasha Levin ---- - 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 -