From nobody Sun Jun 14 03:53:12 2026 Received: from mail-qk1-f175.google.com (mail-qk1-f175.google.com [209.85.222.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 163BD3CD8CC for ; Sun, 3 May 2026 14:15:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817735; cv=none; b=LmN321PvBqQ+wA939RuWPXjj93uhyx/vgBjDqMfq2bb9VWQIa0tEQQRRQ4M6/vMFIPXwlCJdo4D1ZRBq7ERduvrlFaXN7nUgM7wXGuG+kbe16dVH6dHktABOr7c52nAe6Y41snxYoLshqhKjBDiBaBhHbHr7b5K7Spb8/MzKILE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817735; c=relaxed/simple; bh=da761sZYS8Qfcqjx7tTH+rDqBWoz2Abmcj82tsKx624=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bxlm2xjRQZD2w6tJLROWiljAyeTznRnm5uorInahCmCx9ApUHjgVS7Dovy4MnL2hbzfW22w0gXG2a1IbEsDFUcHB7WlPn+b5YiQWkJ+I7BwwXk56FWfzMv/JG5ybrmRoOqAB14TQX1nkYVFPgFTG1D1MrT9cPqyygy2hbOSaibg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=cMnpt3DX; arc=none smtp.client-ip=209.85.222.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cMnpt3DX" Received: by mail-qk1-f175.google.com with SMTP id af79cd13be357-8eae9229110so593205485a.1 for ; Sun, 03 May 2026 07:15:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777817733; x=1778422533; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9iAjdO9SNYauCKwr63OH+1/upS4pxxHhAek9kVw0MsI=; b=cMnpt3DX4qyyj9S05I043vTa5A8ZutsEFrFxRJIpBdnwvcWGR0iYuu+G2uwTba4VhZ KBhJ4AEKeged0naEkU4Jzs03boayyQUdTC93Z90hhIsPt5qcEdgjaizr9m0NqNr/r12a 2pymdWVUcQ0dzTmpiyT4eZSCXmnXOeWXR+IEF7ZYc4u4VqMBQvFGV1mbGxxY3wGedl/5 A2y0kMdfRiDZL6V+GHy2uRXCDC3l5vsnGq+RaRpZZIEaLdFRoUanc0VJ6AfdZsY/zG+m cmKr9Fh0VLz1sAjh8oCK/dyYuPVBBqsfbm+gaeA3FbxDlSPHfryiVBiA1Sp1W4291AqT ka/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777817733; x=1778422533; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=9iAjdO9SNYauCKwr63OH+1/upS4pxxHhAek9kVw0MsI=; b=K3RPwjIWIWDdz7ziVk/iFIMfhUwIps5KAu+xTm9ENQBI4YnElZ5wH0oKoNBWWWxu2c rioXvs35erNox9uJQqZY3mKAivw+vhH1ocJMOa9QnVz1plNTgXqeAtWGWFv++LtADC0w CIGRFu/pHtWjXcU8o0g77xj0scUggp+V+yeet2Zd4tQQggtlSD0Zj5dS7PdRiaYcwG4K P55JADFu+0W3Lfc/2oynbYszP6740Jaao5cJDTPAqasVUaQ44AUSAmuqmhwY4zE2ogjM dcu/7UqGb7LYWrdvyVkHZiB4fjWzxcGLR90ewFV+90Y0qaNDNU/2XBlNedCiTtzxTFJL NHfQ== X-Forwarded-Encrypted: i=1; AFNElJ/uD3ngJ1/Ohln5s9hJpfouf6Ucj5mikbKmW8pPWYGyU0hVFQS/0HkEOT7PhXYLzcN40imlfZRgNWsagLw=@vger.kernel.org X-Gm-Message-State: AOJu0YyeqxoownPYScZnqZD1hC/i+CGq4TbbrA2kRBGrt/HNR8tqPAy4 dq1pCj5flN2CG4xlD4Ne/yJNgPYRsAHdTcFd5AneyrfHE6oIpKpMNw1a X-Gm-Gg: AeBDievtDscidh8Hnx1mmDTvydMwFQHZzjLK3j9+r+COD3/cnoEBWJNKGGuRSwAzaNp GbpXc7JzB6br9tBKHPPd5TjFvv2i7UtLQ8iyeO2erE9aZKUDIBChCAw+1BHrgJGcKGvW2C2hvXd 2zvQSd9VWCPN0fbPkVWBSaQuKJAP8up+CNmvPmztiGWnyzFHpQXAR/D7NwLWNXs1a5jexZ0vzz9 dhThXDMYdId9eLXF37zJ3iIPkffNjG5NHhMeS08kRwFCoU3PG825/yX59yQXGPCOVySVBL/waGD 5LUJO7vzUHwj5sHxdy9pTQWGZLPDQXNBIgshdDWoRj3Tp5KTnXK80ShIIGNM2caP/COFUq0oP+z oUbbfBHL4/iZHf65tCmpvpMVevIz3p9PonAn7rHkEShifhiiDHUf/cp9v5W6W+Qodw/dXPN5Iop Y14gk+LSyQtaE+B/pBJYbw5SEPa5S7L90fQf6nZevVJgFjYYmlIsnZna5ljlmbZbh/jK8dFUes8 Xqk+Kym7Ev4LHbhZ35kuHqwWTphWZE= X-Received: by 2002:a05:620a:2a0c:b0:8ee:630e:351d with SMTP id af79cd13be357-8fd15ade400mr1019838985a.12.1777817728309; Sun, 03 May 2026 07:15:28 -0700 (PDT) Received: from server1 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8fc2938e0b9sm766261985a.9.2026.05.03.07.15.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 07:15:27 -0700 (PDT) From: Michael Bommarito To: Mika Westerberg , linux-usb@vger.kernel.org Cc: Andreas Noever , Yehezkel Bernat , Andy Shevchenko , Michael Jamet , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v3 1/4] thunderbolt: property: reject u32 wrap in tb_property_entry_valid() Date: Sun, 3 May 2026 10:15:05 -0400 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: <20260415123221.225149-1-michael.bommarito@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" entry->value is u32 and entry->length is u16; the sum is performed in u32 and wraps. A malicious XDomain peer can pick value =3D 0xffffff00, length =3D 0x100 so the sum 0x100000000 wraps to 0 and passes the > block_len check. tb_property_parse() then passes entry->value to parse_dwdata() as a dword offset into the property block, reading attacker-directed memory far past the allocation. For TEXT-typed entries with the "deviceid" or "vendorid" keys this lands in xd->device_name / xd->vendor_name and is readable back via the per-XDomain device_name / vendor_name sysfs attributes; the leak is NUL-bounded (kstrdup() stops at the first zero byte) and untargeted (the attacker picks a delta, not an absolute address). DATA-typed entries are parsed into property->value.data but not generically surfaced to userspace. Use check_add_overflow() so a wrapped sum is rejected. Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito --- v2 -> v3 (no code changes): - Lowercase 0xffffff00 in commit message. - Fix Fixes: SHA (was e69b6c02b4c3, "net: Add support for networking over Thunderbolt cable"; correct is cdae7c07e3e3). drivers/thunderbolt/property.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/thunderbolt/property.c b/drivers/thunderbolt/property.c index 50cbfc92fe65..f5ee8f531300 100644 --- a/drivers/thunderbolt/property.c +++ b/drivers/thunderbolt/property.c @@ -8,6 +8,7 @@ */ =20 #include +#include #include #include #include @@ -52,13 +53,16 @@ static inline void format_dwdata(void *dst, const void = *src, size_t dwords) static bool tb_property_entry_valid(const struct tb_property_entry *entry, size_t block_len) { + u32 end; + switch (entry->type) { case TB_PROPERTY_TYPE_DIRECTORY: case TB_PROPERTY_TYPE_DATA: case TB_PROPERTY_TYPE_TEXT: if (entry->length > block_len) return false; - if (entry->value + entry->length > block_len) + if (check_add_overflow(entry->value, (u32)entry->length, &end) || + end > block_len) return false; break; =20 --=20 2.53.0 From nobody Sun Jun 14 03:53:12 2026 Received: from mail-qk1-f179.google.com (mail-qk1-f179.google.com [209.85.222.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7BF153CD8AC for ; Sun, 3 May 2026 14:15:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817734; cv=none; b=A0WMnSOiv6jDHxrtjRBh0xanlxxNa8EH9csdOzA2YtXH+QNLlNIQfiROv9yjOKSjNjPULFNFEFvRixN6drRri0OyYEx4Gwsh1rLnGtjo0TYZr3Q84wWsB4FHlN2kjnHiKQviedF+QVccfIxehEbFBF/F3cC7yCVqIyOSI2VXZN4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817734; c=relaxed/simple; bh=sNYg3v35X3Zb6ai1EEiwl45wwE7v2/fvnp/4sYLMCpA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BYjS3YPdDvmWFggHcfFI716cIrqz3IEto2uiDm+HOmkNmN07f4YrtzDr5W5hVhAi8WkUzzkMQpOya8c9xDPbc0zzGVgKy99s+hIiS0HXvdrWzB0XiRL1nxXdDhdXGWX0OJVf1AScFsrBJ4jQ877GAgxhpOaDGHf6NFX3oy9VCV0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=N4OZm5fB; arc=none smtp.client-ip=209.85.222.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="N4OZm5fB" Received: by mail-qk1-f179.google.com with SMTP id af79cd13be357-8f0a87e23daso344456185a.1 for ; Sun, 03 May 2026 07:15:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777817732; x=1778422532; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=i+ka8zjHbzrAJc7Li4EgptLPQUFhFF6o2unBqDH+EWo=; b=N4OZm5fBSV3d40wA+/gFKdacCBK6iqA8fy7trjJrmUP4dRQA7fmYPnXeAs1A9bVQY9 E7NbdUNv7A/FxerTZFSI3du2E4zHhbczBeb609Dcf1GkWuSvLSUv2LUSe4zw3Rd+bfbj 8b2giS4luaKrFSY3gwc7R+JF+c6Ww7sCIh0xybWrOA6P5DtqEJRUdb/ZKYet8QmVQ+UE PdhGbkRe2SCUMoFx2Ud0xnE+FQYqigDaQIcMnLcMrXZEastvivnqgSvk5x2Z6sAa1Qxj jnTHZQ4iVuNDD0+TmVJDA/4I2sySGXFKIvxZDv1whb/9D2ipl1detkOGGTHTmkkKU6iU qHJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777817732; x=1778422532; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=i+ka8zjHbzrAJc7Li4EgptLPQUFhFF6o2unBqDH+EWo=; b=m9YRgeBurkg/M4YGIxLywHTNFSNpmmvlEoETLK+ib33dvYraOiqZE9IPLI6oSQfhcr u23jKX8Srt/fGIKq9no1X9XpNzqzwAm3KoM+VdG3NGlD9H+UdImPPTn33Ept5huHZJ7l nNDlqVi5xwrPEp8SwOgdqE210h6T8KbGmImiU+dwRHcNs3Jeo4tBIHBNpZ8d2lzyFgZR lm4ivlchJhZWS21YurEcScsq/9b2V/iqmKWnWXdadnjc2TPRbar8nDUmZJrmgOWbhtEc pmz0QR5GcFJ4PG6887brSDTcU+Xz1m7XyoiZx+QdhgD+nvJw5FQbwpwe947zbBMrSthZ JHuw== X-Forwarded-Encrypted: i=1; AFNElJ9Je8NnifYoyRPACLOiZa6lbpLw/1zIznmVrHQWhIxN0SCcefx5fYQsCytk2rjrTxE2z6QnTzx3reNhAz0=@vger.kernel.org X-Gm-Message-State: AOJu0Ywb6dm7pyGA2EUOO4SPq/Z5awRGQMaubb7I9Q8I1SPH6UM8VsnN RDa5+TIyL9s/duEbfs99Y8FhqAHRfhSiU0LF+uZujPMkzBq8MJjKR+f4 X-Gm-Gg: AeBDieu28oig7mJFBSOnVYirPTrZUoRMD+CCm+JOw6cf6FANYenczZtT3gjowUN3gbG hwf3j6ND+4M/wUuBEgy/9yPod6S48FGwtxJZaNEdEQYZeOUS/HQWKGKJdAfkG+/AwdbBBJk6y1S kYyZdlgtf9/Zpj+uWERAvA+SOmxkGwtoHVYWDZjZA6S1Lctbxcs7LnODbwel4o4hrJXpAf+qsOl rgobohX/2JT8GuCGXkQ92oDWzFVmlt3Qdl/OKjqLmeRIu+Bz9NNf/m5O4tGTUs+vi9uWewVklNN aUzuQAB0BoFVVNG5Jl/3AxajR6DALo6J4w9RIPkoP0epCIcOZzszUnN5S0nI1S45b3Yf2rVRgAj 1ZyHsPdsJyeUQ0zrdu7909Y5IepGV+fO+J4ijM/38caWhn4N2xd0jx/+ke/jkLhnt0atw+UZz9g qWqLraYUy5FnCN6KrLGDOvX34K1t6jl7endT0Nz6GL/pUuoDd4wvnqcikyLp6ToqVg7Ti8yznoj 6nbsK2i2F5zk5IFPxxBza7RA9Ls42k= X-Received: by 2002:a05:620a:450c:b0:8d7:e3ab:4c17 with SMTP id af79cd13be357-8fd1824178bmr976368885a.41.1777817730017; Sun, 03 May 2026 07:15:30 -0700 (PDT) Received: from server1 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8fc2938e0b9sm766261985a.9.2026.05.03.07.15.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 07:15:29 -0700 (PDT) From: Michael Bommarito To: Mika Westerberg , linux-usb@vger.kernel.org Cc: Andreas Noever , Yehezkel Bernat , Andy Shevchenko , Michael Jamet , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v3 2/4] thunderbolt: property: reject dir_len < 4 to prevent size_t underflow Date: Sun, 3 May 2026 10:15:06 -0400 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: <20260415123221.225149-1-michael.bommarito@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On the non-root path, __tb_property_parse_dir() takes dir_len from entry->length (u16 widened to size_t). Two distinct OOB conditions follow when entry->length < 4: 1. The non-root path begins with kmemdup(&block[dir_offset], sizeof(*dir->uuid), ...) which always reads 4 dwords from dir_offset. tb_property_entry_valid() only enforces dir_offset + entry->length <=3D block_len, so a crafted entry with dir_offset close to the end of the property block and entry->length in 0..3 passes that gate but lets the UUID copy run off the block (e.g. dir_offset =3D 497, dir_len =3D 3 in a 500-dword block reads block[497..501]). 2. After the kmemdup, content_len =3D dir_len - 4 underflows size_t to ~SIZE_MAX, nentries becomes SIZE_MAX / 4, and the entry walk runs OOB on each iteration until an entry fails validation or the kernel oopses on an unmapped page. Reject dir_len < 4 on the non-root path *before* the UUID kmemdup, which closes both holes. Also move INIT_LIST_HEAD(&dir->properties) up to immediately after the dir allocation so the new error-return path (and the existing uuid-alloc failure path) calling tb_property_free_dir() sees a walkable list rather than the zero-initialized NULL next/prev that list_for_each_entry_safe() would oops on. Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito --- v2 -> v3 (material): - Move dir_len < 4 reject before the UUID kmemdup in the non-root branch. v2 ordering let dir_offset near end of block + dir_len in 0..3 OOB-read the kmemdup before the reject ran (dir_offset=3D497, dir_len=3D3, block_len=3D500 passes value+length<=3Dblock_len but kmemdup reads block[497..501]). - Fix Fixes: SHA (was e69b6c02b4c3; correct is cdae7c07e3e3). drivers/thunderbolt/property.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/thunderbolt/property.c b/drivers/thunderbolt/property.c index f5ee8f531300..90fa6f760963 100644 --- a/drivers/thunderbolt/property.c +++ b/drivers/thunderbolt/property.c @@ -173,11 +173,16 @@ static struct tb_property_dir *__tb_property_parse_di= r(const u32 *block, dir =3D kzalloc_obj(*dir); if (!dir) return NULL; + INIT_LIST_HEAD(&dir->properties); =20 if (is_root) { content_offset =3D dir_offset + 2; content_len =3D dir_len; } else { + if (dir_len < 4) { + tb_property_free_dir(dir); + return NULL; + } dir->uuid =3D kmemdup(&block[dir_offset], sizeof(*dir->uuid), GFP_KERNEL); if (!dir->uuid) { @@ -191,8 +196,6 @@ static struct tb_property_dir *__tb_property_parse_dir(= const u32 *block, entries =3D (const struct tb_property_entry *)&block[content_offset]; nentries =3D content_len / (sizeof(*entries) / 4); =20 - INIT_LIST_HEAD(&dir->properties); - for (i =3D 0; i < nentries; i++) { struct tb_property *property; =20 --=20 2.53.0 From nobody Sun Jun 14 03:53:12 2026 Received: from mail-qk1-f177.google.com (mail-qk1-f177.google.com [209.85.222.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 422133CCFDC for ; Sun, 3 May 2026 14:15:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817734; cv=none; b=b4eOzJRPZwXMDfgu3R61rUgo4sSWq+7Zt/rlPmLeFIgoKTK4hqgcBtwEE/pr5JhEEhn+073jIu73VMi0zXavrAmC5K9J97yUuEduth2GC2TeEUvOJ6UD2PC3/OYIGRUMoyX/mZfEp49s7PoFkcRUk9qhQ7vCdji/p25Q9S5DfhI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817734; c=relaxed/simple; bh=DJX8ceKuZncvVsVqGihXF8M5N6EDLWVTekpwhupNHa4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KMHsGgXH2E+yWYWPJKz+GHWWbbuGlaRPONJfpGZU9iCuF6dbPsq+r3kj/Ex2f+bsxJ2ANnWqt6Auqya1vkq21JhoBG2C7vLEddg2WL+oTCWJ8vIsm0ilxRNsoD7U8T1oPAER10N1o7VepQZyMNY5G4Ie2a2g+H7g/gzLAO22kAU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RqUGr8//; arc=none smtp.client-ip=209.85.222.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RqUGr8//" Received: by mail-qk1-f177.google.com with SMTP id af79cd13be357-8d7e7f48499so353176985a.1 for ; Sun, 03 May 2026 07:15:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777817732; x=1778422532; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4Dz71hQc8J8ElMRCoaWUAkz9HmQbH5aLVTYzizz+yMo=; b=RqUGr8//Wj3a9VELBdVmZpLUQflfTvDuQezU/yypkbdrse5QeNfQPDiNB0BSQJWRO+ 3AA0gYif/+bNPJy5y5VZPzJIdZzFTa5fSBBGrBxdA1J55Na70KCbAvCfsh/vaCPUAzh+ 9FhejfY1F32Fgq/iHABQwQTavdFF3l1TGvfWXXwVM7kH7WmVBw5c1etNdAESeYexziac h7YgUFafO2F8l0ditWikIYk5cZnAmpPH7UPyrP712Eucq2fBphytFaNJxmsTfI41WJOd I7wmFn5gFBSa1ZMXPztNI9RvKNxX00zMTLA0VbtBTRMmmhC7skymgBSvxeoGSs2xwBzr +2rA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777817732; x=1778422532; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=4Dz71hQc8J8ElMRCoaWUAkz9HmQbH5aLVTYzizz+yMo=; b=JnSqF9MPTxNIRIeBrXGg2LvFb9dg+AnJcSWX0tGCJRLTJCgrAigzj1IrxEZIc7YDJE 612AePLKRCkXuASxAkmNfTQAyfVb5Iz55ZLisUHu59tybMv3eI2LokU2LGdkI7fcNnz+ dn9USmRqKY2SrRkm/OZS4ygbOw2MTq8Cg1PlwB4V3647um+uGhFIjXzTJ6HYXf2w+RGR dE4VTKVo1LwEsAT1i4YA0uhJAdPdJFwTvXvY0yR9PFlojmtTGckTTq1wyvuK+GGxmCZ0 e2D+eH29HKQFAvJ/NuKgZryxpNdpbBtweWtSxlFQA3oIcrvwhrt/SpKrSX8yBS1kC78H Mbww== X-Forwarded-Encrypted: i=1; AFNElJ8X5FPMFZzHtsr/K04VFEu3Q9jrsmQXGCfMwlRJuH+Z2Xv2lkQj4ktohOPavgFwB23rvfKoNZlTHpQgUDE=@vger.kernel.org X-Gm-Message-State: AOJu0YzUxeyDTasod5LCjXxRPd53BO0JHFVKFe/pSypXunpW50Pl1dTJ B8U5Egb6a09PqlenErkaMU3kJrNDvrNQkRFpZzR+4OQgoMB6LwUX9rB/ X-Gm-Gg: AeBDieuDdaXQlWwn4a/EnolmJISq+HpyIuQgBT3XpOJRIsEwRtiVQa5UniYx1CgpTKS /q39nIIRNOUdar1Rn5uBwjwOWBN6w+sBIAi14mlmT2JP8kKxIoEvbiRaQYB9OZE1LFCPbq1Y1Dc D+zd8Yl8ahpLxyyIU2oT5qi7IImgKwyH93021N33rgkb0EakG4mNa1VIh3bxapOhNc9jAJzaktV zsDgBFTgee92rzadirmvKG/j6vxrd5R4uekiqGIeo6CiEb98aAVKbhLaZoFlmhebuuHaKdq4cfC 1szy0l3H/hPivxKKq3GZ6ImeZI8zTGWfwYMSd++5uf4BmfMtLEZknRxXzLgNzrj9GxgKDiLOaJK S6cPKWlouLdJ68hXtaEvIlsGN538ESWE3HH0bScTGw257a3Rs5XAepTY31hMIcp9rsi2nwBkdRD DeWGLGn7TODE/QRIWokPH3e+c+pwjexdbHsN7NpjWf7WkWbg0Vt/YLIafG67faDAjKCtaCxYj5s y4GXvcDKEG3UXCM X-Received: by 2002:a05:620a:4613:b0:8da:cfe6:c67c with SMTP id af79cd13be357-8fd17c4f15fmr981271585a.28.1777817732086; Sun, 03 May 2026 07:15:32 -0700 (PDT) Received: from server1 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8fc2938e0b9sm766261985a.9.2026.05.03.07.15.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 07:15:30 -0700 (PDT) From: Michael Bommarito To: Mika Westerberg , linux-usb@vger.kernel.org Cc: Andreas Noever , Yehezkel Bernat , Andy Shevchenko , Michael Jamet , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v3 3/4] thunderbolt: property: cap recursion depth in __tb_property_parse_dir() Date: Sun, 3 May 2026 10:15:07 -0400 Message-ID: X-Mailer: git-send-email 2.53.0 In-Reply-To: References: <20260415123221.225149-1-michael.bommarito@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A DIRECTORY entry's value field is used as the dir_offset for a recursive call into __tb_property_parse_dir() with no depth counter. A crafted peer that chains DIRECTORY entries into a back-reference loop drives the parser until the kernel stack is exhausted and the guard page fires. Any untrusted XDomain peer (cable, dock, in-line inspector, adjacent host) that reaches the PROPERTIES_REQUEST control-plane exchange can trigger this without authentication. Thread a depth counter through tb_property_parse() and __tb_property_parse_dir(), and reject blocks that exceed TB_PROPERTY_MAX_DEPTH =3D 8. That is comfortably larger than any observed legitimate XDomain layout. Operators who do not need XDomain host-to-host discovery can disable the path entirely with thunderbolt.xdomain=3D0 on the kernel command line. Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito --- v2 -> v3: - Fix Fixes: SHA (was e69b6c02b4c3; correct is cdae7c07e3e3). drivers/thunderbolt/property.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/thunderbolt/property.c b/drivers/thunderbolt/property.c index 90fa6f760963..8db56922011b 100644 --- a/drivers/thunderbolt/property.c +++ b/drivers/thunderbolt/property.c @@ -35,10 +35,11 @@ struct tb_property_dir_entry { }; =20 #define TB_PROPERTY_ROOTDIR_MAGIC 0x55584401 +#define TB_PROPERTY_MAX_DEPTH 8 =20 static struct tb_property_dir *__tb_property_parse_dir(const u32 *block, size_t block_len, unsigned int dir_offset, size_t dir_len, - bool is_root); + bool is_root, unsigned int depth); =20 static inline void parse_dwdata(void *dst, const void *src, size_t dwords) { @@ -97,7 +98,8 @@ tb_property_alloc(const char *key, enum tb_property_type = type) } =20 static struct tb_property *tb_property_parse(const u32 *block, size_t bloc= k_len, - const struct tb_property_entry *entry) + const struct tb_property_entry *entry, + unsigned int depth) { char key[TB_PROPERTY_KEY_SIZE + 1]; struct tb_property *property; @@ -118,7 +120,7 @@ static struct tb_property *tb_property_parse(const u32 = *block, size_t block_len, switch (property->type) { case TB_PROPERTY_TYPE_DIRECTORY: dir =3D __tb_property_parse_dir(block, block_len, entry->value, - entry->length, false); + entry->length, false, depth + 1); if (!dir) { kfree(property); return NULL; @@ -163,13 +165,17 @@ static struct tb_property *tb_property_parse(const u3= 2 *block, size_t block_len, } =20 static struct tb_property_dir *__tb_property_parse_dir(const u32 *block, - size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root) + size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root, + unsigned int depth) { const struct tb_property_entry *entries; size_t i, content_len, nentries; unsigned int content_offset; struct tb_property_dir *dir; =20 + if (depth > TB_PROPERTY_MAX_DEPTH) + return NULL; + dir =3D kzalloc_obj(*dir); if (!dir) return NULL; @@ -199,7 +205,8 @@ static struct tb_property_dir *__tb_property_parse_dir(= const u32 *block, for (i =3D 0; i < nentries; i++) { struct tb_property *property; =20 - property =3D tb_property_parse(block, block_len, &entries[i]); + property =3D tb_property_parse(block, block_len, &entries[i], + depth); if (!property) { tb_property_free_dir(dir); return NULL; @@ -238,7 +245,7 @@ struct tb_property_dir *tb_property_parse_dir(const u32= *block, return NULL; =20 return __tb_property_parse_dir(block, block_len, 0, rootdir->length, - true); + true, 0); } =20 /** --=20 2.53.0 From nobody Sun Jun 14 03:53:12 2026 Received: from mail-qk1-f182.google.com (mail-qk1-f182.google.com [209.85.222.182]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4C1D3CEBBA for ; Sun, 3 May 2026 14:15:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817737; cv=none; b=gxEcOd52HKdchzqdd2Z+Lciirg2q+S0J4vNi5SnyAOA00m7EpRtB3Ld3U4rEXcNpO/4j/A48GvdUQFKSJhTv9zfxwMjYdT7joIkxa/iVlgyflMv2R1EXtdV19JiIF8m605iNBE1IPYs7Bel8vi23q+t4e+QzU5q+0HqKDk/irtY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777817737; c=relaxed/simple; bh=4/h2g963/WH6kbfJPLMHWdhyI3Xrwf9EoPjbsxH/wb4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mCmW7/NAZa8mExhgNbf+XHrSKBC//OP1P61nLFCJXgv5wvVSlLqIAsfv9AHKHD8bldK970g1QOXRC8dkSbI6OoxDFRPYR+KEki3GNNz4kGIG4/XDZI3l0mpKtG2fleC4ZVZj4C2RH73dzmuw2UdIp2TJUHUzABNEN4s9pW4W5Hg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=e2qMPCZw; arc=none smtp.client-ip=209.85.222.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="e2qMPCZw" Received: by mail-qk1-f182.google.com with SMTP id af79cd13be357-8d736211595so224027185a.0 for ; Sun, 03 May 2026 07:15:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1777817735; x=1778422535; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cnlk5QlW8PilWssNRBG7k8CDN0LxAxtZ/pUfiIBMymg=; b=e2qMPCZw3AoXjSc6SMZNPc/19BQ7M6JHdXBAxYrhtTlHP4BOUiqqNycwyeDx831o8L HhngwUNu3+/6kVw7ebBodrU4y3Kh7Bbne8gp5+Qor6PaRuHkDosIYxRh4bVLPPxpPgaJ fax9yv6oCTni+KZxhlnDleDAFXJwcAbIXX7SilGlikWbBtuOh+LFB8x129w/YtteYu/C gu3Syk4u/sgfk7SN8PvQay//YkVEO6risxcv7eEcKRgZRIrPADk8QjBSUXxuksdItrX6 KvvWuJ05qNwJ/uFUwadZ/SbeN1e01IcimKhFr7XoQlNhWutci9kRWbiiDUBlgcHebFES SlLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777817735; x=1778422535; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=cnlk5QlW8PilWssNRBG7k8CDN0LxAxtZ/pUfiIBMymg=; b=Rn+RupSSmw35cMRMbEt4O2QXp459sVewSgIxFTIbmfpEMdXfeXFPmSLI6Vqj5E7gQT o0fze1zj5xVWs7xo+nwUWAcAFTomVmhHpBL4krslFVgLvY3U9R5r6EjUcF9vx9xFETao CCZn9lOJxpn06Ey3OXtLgehwIuP+mSeDBMG5PToQonzHEXrGzxt3unRHEuhi0XUrBTPI vOT4ytbt1tQydKiWhxv3igp3iuGB/UmQ+M9Ta6nBhjn34SOofBsRiSQemNv+HqlL6RD3 QE+dY8OhD6VZqL0BnoqEykMPh8Fou6TO6QsnSqvfyGuSWOGZFWrNETkwZMkTC4RsU+DI 4VLQ== X-Forwarded-Encrypted: i=1; AFNElJ/Fl8nRJn8Wc6iFUTA9ZnSe1sa+usJggwbVknEldRSQUs2r8pzJFWBNHOJoBB48beLwEGkHOh6LxuGI2bk=@vger.kernel.org X-Gm-Message-State: AOJu0YwbpO23523167fnfLA8oI2yiA1RpPpQWEnyUo4BaE73rT293rXf E/jC12zTvxotQXeAUZOJkn40p2zCjL6je3Ahh0drw/A3iA9QaaRiw9xC X-Gm-Gg: AeBDievxMKoXknBrvJL3VC9JyJof18gRImuK5ScLSLKdxdAlWz9KSrgR8wRtvoysqrh +F+4alFswkORKuVmO6wQRfRhndnilzKPnZTLSWrgdyqzpxZES52nfp9xGeVCkM9gRsbgoi35xzP gTDHwfiadVNNtV7QA54J0WBY+27zTaAohfvZogIc75+uVckIxW7odRfUvbBU7LImjBPCSO5nI+m Lb3kezxHJn2Piox+vAjaUCGB02rXa+BJx9mEzlnDMhAXfY8vbmk+0Tym579yC6kw5wQzn35gmYI dDKeo8ilWK72JpUyFhTGTJVAjd+hVaTvyETm06MIA0z9lscLg+5wspsnw6DPLmjqtYgpnqCkBvW sxC5b9aMzolh2FA5MHTeeoPOt7xD+kqF4Cpj24f+rGDp0R20TFqgBK2pZ61AlbJMbD42BoMGm98 7YpOJMmrKXiG7vpLgglCSS4zl4Qy+mNQPkHv+82Ll5KfULZ6MSiL8Zt5zDWgMilWa3i7ISnZ/Pi IFyP7IRz5ersk4s8hfSRBxMwSwlnjU= X-Received: by 2002:a05:620a:4109:b0:8ec:c4a7:f8fc with SMTP id af79cd13be357-8fd1863370emr991452685a.43.1777817734572; Sun, 03 May 2026 07:15:34 -0700 (PDT) Received: from server1 (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id af79cd13be357-8fc2938e0b9sm766261985a.9.2026.05.03.07.15.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2026 07:15:32 -0700 (PDT) From: Michael Bommarito To: Mika Westerberg , linux-usb@vger.kernel.org Cc: Andreas Noever , Yehezkel Bernat , Andy Shevchenko , Michael Jamet , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v3 4/4] thunderbolt: test: add KUnit regression tests for XDomain property parser Date: Sun, 3 May 2026 10:15:08 -0400 Message-ID: <5caddc2abbec9d4215dfc9041ab18f84eb7bbc58.1777817011.git.michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: <20260415123221.225149-1-michael.bommarito@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 =3D 0xffffff00 and entry->length =3D 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 so the non-root UUID kmemdup of 4 dwords from dir_offset reads past the block, and the downstream content_len =3D dir_len - 4 size_t underflow drives the entry walk OOB. Each test asserts tb_property_parse_dir() returns NULL on the crafted input. On a pre-fix kernel with CONFIG_KASAN=3Dy, u32_wrap trips a KASAN report inside __tb_property_parse_dir() (the parser reads ~16 GiB past the block) and recursion trips an Oops on RIP=3D0 via the stack-guard. dir_len_underflow returns NULL on pre-fix via the downstream content_len underflow path; the UUID kmemdup over-read happens silently because KASAN-Generic's slab redzones do not flag a 4-byte over-read into the kmalloc-chunk tail, so this case is the post-fix invariant pin rather than an active pre-fix detector. Post-fix all three pass cleanly. Run with: ./tools/testing/kunit/kunit.py run --arch=3Dx86_64 \ --kconfig_add CONFIG_PCI=3Dy --kconfig_add CONFIG_NVMEM=3Dy \ --kconfig_add CONFIG_USB4=3Dy --kconfig_add CONFIG_USB4_KUNIT_TEST=3Dy \ --kconfig_add CONFIG_KASAN=3Dy 'thunderbolt.tb_test_property_parse_*' Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito --- v2 -> v3: - De-duplicate the on-wire entry layout: define a single struct tb_test_property_entry shared across all three tests instead of re-declaring an anonymous struct in each. - Use TB_PROPERTY_TYPE_DATA / TB_PROPERTY_TYPE_DIRECTORY constants from instead of bare 0x64 / 0x44. - Convert all multi-line block comments to put the opening "/*" on its own line per the thunderbolt subsystem's coding style. - Lowercase 0xffffff00 in commit message + code + comments. - Tighten dir_len_underflow: use a 7-dword (28-byte) buffer so the non-root kmemdup over-read targets the kmalloc-32 tail rather than slab slop within a kmalloc-2048 chunk. KASAN- Generic still does not flag the 4-byte over-read here (slab redzones cover next-chunk metadata, not in-chunk tail), so the test remains a post-fix invariant pin; documented explicitly above. drivers/thunderbolt/test.c | 132 +++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c index 1f4318249c22..73de7292ee21 100644 --- a/drivers/thunderbolt/test.c +++ b/drivers/thunderbolt/test.c @@ -2852,7 +2852,139 @@ static void tb_test_property_copy(struct kunit *tes= t) tb_property_free_dir(src); } =20 +/* + * 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 mirrors struct tb_property_entry in + * property.c (private to that translation unit). + */ +struct tb_test_property_entry { + u32 key_hi, key_lo; + u16 length; + u8 reserved; + u8 type; + u32 value; +}; + +static void tb_test_property_parse_u32_wrap(struct kunit *test) +{ + u32 *block =3D kunit_kzalloc(test, 500 * sizeof(u32), GFP_KERNEL); + struct tb_property_dir *dir; + struct tb_test_property_entry *e; + + /* + * Root header: magic + length=3D6 (single entry body of 4 dwords + + * 2 slack, keeps walk within block[]). + */ + block[0] =3D 0x55584401; + block[1] =3D 6; + + /* + * Crafted DATA entry at block[2..5]: value =3D 0xffffff00 and + * length =3D 0x100 are u32/u16 such that the u32 sum 0x100000000 + * wraps to 0, passing the sum <=3D block_len guard even though + * the real offset is block + 0xffffff00 * 4 (~16 GiB past the + * block). The subsequent parse_dwdata() copies entry->length*4 + * =3D 1024 bytes from that wild address into a fresh kcalloc + * buffer. + */ + e =3D (void *)&block[2]; + e->key_hi =3D 0x61616161; + e->key_lo =3D 0x61616161; + e->length =3D 0x100; + e->type =3D TB_PROPERTY_TYPE_DATA; + e->value =3D 0xffffff00; + + dir =3D tb_property_parse_dir(block, 500); + KUNIT_EXPECT_NULL(test, dir); + tb_property_free_dir(dir); +} + +static void tb_test_property_parse_recursion(struct kunit *test) +{ + u32 *block =3D kunit_kzalloc(test, 500 * sizeof(u32), GFP_KERNEL); + struct tb_property_dir *dir; + struct tb_test_property_entry *e, *child_e; + + block[0] =3D 0x55584401; + block[1] =3D 4; /* rootdir length =3D one entry */ + + /* + * DIRECTORY entry pointing at dir_offset=3D2 with length=3D16. + * When parsed as non-root: content_offset =3D 6, content_len =3D 12, + * nentries =3D 3. The child's first entry at block[6] is also + * DIRECTORY pointing at 2, so the recursion oscillates between + * two dir_offsets until the kernel stack is exhausted. + */ + e =3D (void *)&block[2]; + e->key_hi =3D 0x61616161; + e->key_lo =3D 0x61616161; + e->length =3D 16; + e->type =3D TB_PROPERTY_TYPE_DIRECTORY; + e->value =3D 2; + + child_e =3D (void *)&block[6]; + child_e->key_hi =3D 0x62626262; + child_e->key_lo =3D 0x62626262; + child_e->length =3D 16; + child_e->type =3D TB_PROPERTY_TYPE_DIRECTORY; + child_e->value =3D 2; + + dir =3D tb_property_parse_dir(block, 500); + KUNIT_EXPECT_NULL(test, dir); + tb_property_free_dir(dir); +} + +static void tb_test_property_parse_dir_len_underflow(struct kunit *test) +{ + /* + * Request 28 bytes (7 dwords) so KASAN-Generic tags the + * 4 trailing bytes of the underlying kmalloc-32 chunk as a + * slab redzone. With block_len=3D7, dir_offset=3D4, dir_len=3D3, + * 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, ... bytes) puts the + * over-read into the slab cache tail where KASAN's generic + * shadow does not flag it, and the test reduces to a + * tautology because the downstream content_len =3D dir_len - 4 + * underflow also returns NULL. + */ + u32 *block =3D kunit_kzalloc(test, 7 * sizeof(u32), GFP_KERNEL); + struct tb_property_dir *dir; + struct tb_test_property_entry *e; + + block[0] =3D 0x55584401; + block[1] =3D 4; /* rootdir length =3D one entry */ + + /* + * DIRECTORY entry with length=3D3 pointing at dir_offset=3D4. + * tb_property_entry_valid() permits value+length=3D7 <=3D + * block_len=3D7. Non-root parse begins with a kmemdup of 4 + * dwords from dir_offset for the UUID; with the v2 ordering + * that kmemdup runs before the dir_len < 4 reject and reads + * past the buffer. With the v3 ordering the reject sits + * before the kmemdup and the read never happens. + */ + e =3D (void *)&block[2]; + e->key_hi =3D 0x61616161; + e->key_lo =3D 0x61616161; + e->length =3D 3; + e->type =3D TB_PROPERTY_TYPE_DIRECTORY; + e->value =3D 4; + + dir =3D tb_property_parse_dir(block, 7); + KUNIT_EXPECT_NULL(test, dir); + tb_property_free_dir(dir); +} + static struct kunit_case tb_test_cases[] =3D { + 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), --=20 2.53.0