From nobody Tue Jun 16 02:34:53 2026 Received: from mail-qt1-f174.google.com (mail-qt1-f174.google.com [209.85.160.174]) (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 5FDDF26B75B for ; Wed, 15 Apr 2026 12:32:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256349; cv=none; b=nlttueuZof4oTn/a32dKJTM6IhpNs9FhINFhhKIaJPudiEaQ1cLaWmNpv8wuUqvrjTebqVqgn4E3nEOZHWl0pApJD7otYGMKHvsoAngt15wwVJZ8a1G1eATPnyCc5OgJKfq0ZhMq/e5E1fLpYhFIdOLQhFtiLWZID0eCcIinCN0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256349; c=relaxed/simple; bh=V5rhUICHKrtVS+VjsbYW9zZmMYRMee5pEQyn/IO+H4M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Re6NcfW1rELB4j2QQZlHi+2Oov4oILrf6UBJBbJTWhTkvJhCWUfwRkr8XLHuL4gkXOC1dV+zvKSjOiuwOzH1th0PogVqSEW4KTkcCM1ANpDhMXYK1f/YtgRtcN6291EigfyAjaAdLG29s5NQ9HX7CEBBIh0kIm84Bc9P8RfRAhQ= 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=IActRP8x; arc=none smtp.client-ip=209.85.160.174 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="IActRP8x" Received: by mail-qt1-f174.google.com with SMTP id d75a77b69052e-50d8e11b948so66698681cf.3 for ; Wed, 15 Apr 2026 05:32:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776256347; x=1776861147; 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=S4tBTeu6/viYuFA/jm9+9NVpLFwhjRRaKWPLY9i5P/o=; b=IActRP8xapeA8cJ3JS9dfgHRRssqS44VtHYGLuz6Hlb+3pkCkBG9ratwxAXBa1OPJ2 G+7+7qA9oZ7TvDqmCGnC/H+htSYWrNo5U7xQGaHAGQNmFp0Bdp13P08mna7v9FpjWifj gOAfdP9vrJoR/Fkvo9NZS4VOcsf6Uz9fbYuo6fhbNr3GFXxZEYF+PTKraG161LS+WUBv tadv/SxNfVate93ppjIlfJYfqkFVT1y/H+2ceqH9pu2hEY09sd/jHH2aQxMMEoF8ibCi L5LMS4WHZmvFZGoi/W5tlZwJk4S1EixWr+VWHUortmEpkBCTwyLjXQIhaKuNnE929M2l 73vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776256347; x=1776861147; 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=S4tBTeu6/viYuFA/jm9+9NVpLFwhjRRaKWPLY9i5P/o=; b=CWsoheidFS2HGyRJgQWTuvTnE4XSn0mZBgO0HheS8y6CzsjSFmuqTy6rrv88M9JScD Ue4+Yciire0cH3vjcz43Nx9flXvhGVtiKk4T7QtdDye+VRaiytU2NdLCS9wOpHoyJbry NAZWTl/EbrXqfsZ1uYlGkezNU1qUWHExlgLmZij8po44Y8lnk5sqhEHpElyw9kmPECBi y3yr1FhjPFkZb8AIzNLVY3HOeu7txf8w3GeTDjd77mbDKgjHN1J6dCU4zF68K/tgAXJY ECxVI76ObMqLvAEzPVI7+yZKWj8sVeWdeuo9Uq72/Xcwgh6q2EhQ3gw81T7kOtzt6/K8 RrbQ== X-Forwarded-Encrypted: i=1; AFNElJ/Jb7rsu1419UtSPPjwfLYsvr9gp1Ci8DnDzL/6V/57QP34OFycH2q8u3IM62e1cckH/Arn/yocmzrZUbY=@vger.kernel.org X-Gm-Message-State: AOJu0Yxf2o+Rr4MvrSIzGFTN3pJDcMgjAP1SUFI6UAFuwHQ1Mhofi6k3 MQSSbKwVobf6Cblvmpp7nI15OsECo4zBnehY5DNVN7nWGIOGoWvTxxSdBMxsyw== X-Gm-Gg: AeBDievnsBnMzZDGTohyW/Ga42AfZn3m1WR83SBnRoLNLWyIcJ0La4LAGUp1QD5sZ5k 2G9gvcF9Ywx1wEMUlyV2mObzewpBqPZIltYSc5VPs84z31Y2vFMhkJrSq0anSkujDBCjrGytuwl HDRgQX3YEEzajYS6hplIxSfRO9OYXAu8HgXJbRzjONvSKlcdN+p394QT3UTM4qAkR5ucEjc1cxG w2HXgB0ZeON13Db3mpKO96vGUetDADqihZw5yP4nqK9V78dw8pWxXHJ10rM4rWreAdBQzhPO9h4 l6L4nMX19DtLLpnVfqrEx+IgAgvg0MgWSceEUPIjX50WLdlzOJg1Qt58BbZzPnQWXNYUHgHADJo DC1SatKuJrnlrGTs5MJCpNIq/3H13unJCfFgPDc2qxuhlTR9/3oYJiCOtB3p6SlTZgYfV3sbwi2 NxTtDnah4jW1xINRGTDJRQ9Ya8H+FVXyOemtJbqTNSht2WamlAxLWfnDxVu5y3CbZjoZ4TQjcEk dS9ISREdn9EzDg13VBGBUkaSJIAokfFVCi0AFIDTO6tuVBskrnFjgietcJLZF/r X-Received: by 2002:a05:622a:6694:b0:50d:41fa:80fe with SMTP id d75a77b69052e-50dd5bd98c4mr217424231cf.53.1776256347106; Wed, 15 Apr 2026 05:32:27 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-50e1af9dc5fsm11747771cf.16.2026.04.15.05.32.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Apr 2026 05:32:26 -0700 (PDT) From: Michael Bommarito To: linux-usb@vger.kernel.org, Mika Westerberg Cc: Andreas Noever , Yehezkel Bernat , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v2 1/4] thunderbolt: property: reject u32 wrap in tb_property_entry_valid() Date: Wed, 15 Apr 2026 08:32:17 -0400 Message-ID: <20260415123221.225149-2-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260415123221.225149-1-michael.bommarito@gmail.com> References: <20260415032335.2826412-1-michael.bommarito@gmail.com> <20260415045246.GR3552@black.igk.intel.com> <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: e69b6c02b4c3 ("thunderbolt: Add functions for parsing and creating X= Domain property blocks") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito --- 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 Tue Jun 16 02:34:53 2026 Received: from mail-qt1-f181.google.com (mail-qt1-f181.google.com [209.85.160.181]) (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 870772EAB6F for ; Wed, 15 Apr 2026 12:32:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256351; cv=none; b=fzgfxCtuNJwP/YEDLrYZRnWxFjPKKvcmQtyUB6ythaN5iqaiO9T3w4fNdhanVfZ1gPPZ+ovQ/5TgQuRo7XZo2gGqTkVKqpg1EwtaPkYc6x6yjJjm7d538qGl8b0kUkNtIGfsEcuihrisMfaWJQRk/MBFUE61w7lqSvIlt9gsIZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256351; c=relaxed/simple; bh=G4Iv3OWeIHGXB+LraZ3MVrzNrWpsbA5Z8zV9UrKVmV4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YELD2AzhBNagO4o23z0+2dLhaYojUBJYeOWuDEBp2pm6aAtg2dhY79KVpjVmp4nac5ei9u/p5i1WK7bbKZcab0KdvYFiQXfiCq/NaRuRp20tqCn6CzXlOxDPk/ZDr/P4l7nhHpXZYvT4Po/U9Xi5FSWSyxjEqiS8JhiF8z4zxOE= 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=IRuL/Sls; arc=none smtp.client-ip=209.85.160.181 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="IRuL/Sls" Received: by mail-qt1-f181.google.com with SMTP id d75a77b69052e-50baafd6c4aso69443951cf.1 for ; Wed, 15 Apr 2026 05:32:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776256348; x=1776861148; 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=JXoMF+reUIolfhLax07DDnj0adinknHFiCZenjJxIWg=; b=IRuL/SlsPFU86CK8TE13g8EZvGyCAE5MSGSyrSKYp1vt9LZWr5MTC+1UrVdcQ/FI/8 EiDCdUUaauQplbDkpxoh9UUoB4k6l6Y8SwrRWABsuDzHLLGwl/n63U59ndqHPihelyfd WVk7svX3aVKjnyu/8Z+olnL/pJ+EAynjy3vgEgO0izRsNXQ4sTipkpfgzR2bHKEsqdjo kCw7EZZymg8mU5/oJIoqcxTyeHbwK3V6+CAm4zwUSffVYYLUfFzxrEvd7WEeMHYmiepN 9g98KkDEbySn/P7QOg5hE37WJtQyl3eSyDTv9Qs+z2Pl16jmIl/vjGyK1GshtTy9y8ys ggLw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776256348; x=1776861148; 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=JXoMF+reUIolfhLax07DDnj0adinknHFiCZenjJxIWg=; b=AD401Qvz4rg2u8q24Oi2a8wJYhMksG7V/YURaaiUfUV3981Y1SqRbybJwQWkGFfjLX IJ88aK48cuIs+hZT1Rwuln5OY0aFDeNB1dWbmW1itjlDjUZs59a+cGJIQD5o9ydI9d45 N7d+TAsAuS1eJNuP+88ZAB+X+C2ElLrdtRSQq1evl2kl1knTJuwS3c9YPclBLlD/LPAQ DYZAR5QmQLmOudCrh/NZzBY/Ew1SQzvpb6VmZIyBqO/Xaifu4zH1SRQd24hqXNWgKqSc xGZk2E9PyC4afqZoT3Iy1+5T1UTqIbGm6qFCvsCYF991ggRj6jY43oZ6KeFR26EkjU4O wEmA== X-Forwarded-Encrypted: i=1; AFNElJ+EVJjTXGv6N/tdR+IE99Kpw8zaJUMeDqnEDARIXq63dOBA9jvI7yv9E9zx3OVXHcG9C9JaCVm1hG9hjSI=@vger.kernel.org X-Gm-Message-State: AOJu0YytLgNHmzIJQgmCYw+ltN+b2Z8SVHkPJelhAr1RxmVba0LoIlhq 9RNsYhr4CS/HkosBshUM56x1rgJ/6gNPCJF0H7c6XYGotQ1N/6SLMrAO X-Gm-Gg: AeBDievxUrKo0aslTLDLlgxDS4zRG+u76npuTcgyRFOxEm+9EeCeLzmLemsxialjNMx AQKAsY29mUBw9iJ85ISlSlx2AYRqKY/4Ua/79E6rr/HrJJMJoV4blmSunlu8+Rs0Ft10ninyH8z W61+ByA2/INfGqbexbdEV+xwIttxA5Dl+HJXucyWv52py0L9SvEWkXZRsubIVlglZtaOXsHLp8C kUz/y0yczQeKP7JrJ0YGzcLzdUGjNpJDFITwv+8QvcnR6mJPRtiqaIJF1gXLprTCLQ5tn+5SlO5 fpspiroqEH3N5VLu1PnrgVBJDwjCNjlDP2rRqcsgvyOog/P71wHBBwRYurR9uZJW2l6ifgXNw+L NkTwtNaJK/pSOuz5l5fw3QjMko0TSyuC3lfisZw0Hg6CICsAIQAtT9dmKQwiftIXGaA73IqhGpS x5kC8cE3ZjsU5/fnDRdPgCTAYxsltrTGkbR1d1iCa6/dhJ8B8lOmWHjQPmMJVdTNm8AoGHDCYJM U/TKz1KBIU4m5BN2GUTRrHA0d+nhq2YKlTJbxzDi3/KrDhvdwqu3w== X-Received: by 2002:a05:622a:1a8e:b0:50d:7b0c:35e7 with SMTP id d75a77b69052e-50dd5c6cd3amr313880951cf.43.1776256348536; Wed, 15 Apr 2026 05:32:28 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-50e1af9dc5fsm11747771cf.16.2026.04.15.05.32.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Apr 2026 05:32:27 -0700 (PDT) From: Michael Bommarito To: linux-usb@vger.kernel.org, Mika Westerberg Cc: Andreas Noever , Yehezkel Bernat , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v2 2/4] thunderbolt: property: reject dir_len < 4 to prevent size_t underflow Date: Wed, 15 Apr 2026 08:32:18 -0400 Message-ID: <20260415123221.225149-3-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260415123221.225149-1-michael.bommarito@gmail.com> References: <20260415032335.2826412-1-michael.bommarito@gmail.com> <20260415045246.GR3552@black.igk.intel.com> <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) and computes content_len =3D dir_len - 4. If a crafted peer supplies entry->length < 4, the subtraction underflows size_t to ~SIZE_MAX, nentries becomes SIZE_MAX / 4, and the entry walk runs off the property block, reading OOB on each iteration until either an entry fails validation or the kernel oopses on an unmapped page. Reject dir_len < 4 explicitly before the subtraction. Also move INIT_LIST_HEAD(&dir->properties) up to immediately after the dir allocation so every error-return path that calls tb_property_free_dir() (the new dir_len reject and the existing uuid-alloc failure path) sees a walkable list rather than the zero-initialized NULL next/prev that list_for_each_entry_safe() would oops on. Fixes: e69b6c02b4c3 ("thunderbolt: Add functions for parsing and creating X= Domain property blocks") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito --- 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..274b555d27c8 100644 --- a/drivers/thunderbolt/property.c +++ b/drivers/thunderbolt/property.c @@ -173,6 +173,7 @@ static struct tb_property_dir *__tb_property_parse_dir(= 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; @@ -184,6 +185,10 @@ static struct tb_property_dir *__tb_property_parse_dir= (const u32 *block, tb_property_free_dir(dir); return NULL; } + if (dir_len < 4) { + tb_property_free_dir(dir); + return NULL; + } content_offset =3D dir_offset + 4; content_len =3D dir_len - 4; /* Length includes 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 Tue Jun 16 02:34:53 2026 Received: from mail-qt1-f176.google.com (mail-qt1-f176.google.com [209.85.160.176]) (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 F37CE2E228D for ; Wed, 15 Apr 2026 12:32:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256353; cv=none; b=AjJ13+XQpEoCb9b+8V3iJYwM5CZcRyIfxaVZ1z0ctMzsP+Xce+NjtLlkQdI6p5NO+shycivZn6z7grjY3HeJyzDB81SnXbEVC5yX2ED4zh7s4Dba3jgokVDAxLiXwcBlnrrVLQxgz4W3VAuQo7qKfmWOTaduF7uYtdWHn5U9HC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256353; c=relaxed/simple; bh=yy8Ncc37XYKb193wi7SYVyUlnpHGTC4Pmm6nqvvfk7o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sSm+Wnmzw5qYrCYttHx7mD6mFO5A3rkPKUjcNlUVgy5OWoR6dYoqjcKRfyrjqfkdDxsdnSS9ixLK/SieEDsqNMbqnv/OEbfhAhHVe8yT/RVnQ9zUYVXGen3nnwDNb0TTeWP1pODIK1Mgwka9oPWqTuq4K2Q1Yy+DWsKZyc92T8c= 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=ozgPSYWH; arc=none smtp.client-ip=209.85.160.176 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="ozgPSYWH" Received: by mail-qt1-f176.google.com with SMTP id d75a77b69052e-506a747448dso52603321cf.0 for ; Wed, 15 Apr 2026 05:32:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776256350; x=1776861150; 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=snQIRoJJuRpCmh2yyUJKgsvwSWDhZnmvhy2vz0AOQb4=; b=ozgPSYWHjnMWbbuIXyxSvs9/ztHJDmRvnYgkVAX/ONc2aBicbgde6HX6ywfRPJY5fs w+NMbG9C1N80aQM5ZrQjCH26mFhOjke67RdjqRdGshuLWKnQdHlj2Xa0l7nZMJRUP6Rm UNe9S8qcWb1B8B/wwVkulvqXN8RXhO17fwVjKYdGO92oZIDXRzV9XQo69WKt250rMxaR e0bslEUa7tmzx2etmYF8UJS++n5NE06MH/f6NdzYfFvVlqCbksEgmOhP84zTlX83d0nb qEB6MtbYUI2nebMmx8YFkIETtcHOjPzuQvAA5ugI9jDdS3rH3PrAmy9ItDDqQ2Cv3V5M QDTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776256350; x=1776861150; 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=snQIRoJJuRpCmh2yyUJKgsvwSWDhZnmvhy2vz0AOQb4=; b=QP/QMZztyhJ/DXwrETeaQPp3W13wyuOVAuGlqsRsfRCR4/jztpdNATq0JCmfWZl3c5 4s9dNEv6GpknlxOAIHdlh7JyTwoyoYU+Tiw3PCOHH6mLhWNEqUqupIiiLQLz1wMMVwMC aWa/fUpQ9ikuwKAi3Sp6+7UXP1LTJwOHeM9Uk1/pMcpksZCcA9dIy/1sBepBwHkO+Jzp Jw4FXpY5rH9z7e3oVXkWpJ33lioBzwP0ApOk8HftnC8rkKmUz2fyCD4KpdbZ8wbe4txA Csa7GR5AXMX3/iweKfhVQSvspMYRnRICSgjZVzU0dXhfLhFQVG4y+fcN3Fukly3+qFjO vDKQ== X-Forwarded-Encrypted: i=1; AFNElJ/QSvJqy5C9CE/LL9FN160FnQj3bXdad6QoZZVd6bWSoo7RmI9tL6VEBBcwtpbJ10nX+M4PA/OitcOxe1c=@vger.kernel.org X-Gm-Message-State: AOJu0Yyk98bf4YOQWu689Y0w6MFYa/M3BeXKxliq9Gi3PMDj6T4wmMqK lVqnT0Xr4faRvzO//rvqHlcKWvdif08+qmnQBwLp0wr8ubEJDopZjHuA X-Gm-Gg: AeBDietBiMCmEgQN4F05IqDBhRbziAnVCYV07tRAFZE7G6WbI5mXaNgpdPFSWq5NWvW z5omK8vM4flYwq4D+o2o51jh8ih/ZMXtxjjE1xHhk1Kw9W1yZa2CFZB6zhzPv4rJE1axMUO+l9m /IlJdkiXhHHnGDEy9WFqgqbl47XPgAuzBu4ELiHVY1EmM+rI/Y3BLZZ9WX0PkDE+zDmdsBkfKDX PI0GJl36oRxhU7V6Tqig/t7gnCyX/Mh7VAtt3fGP0rh09+JFetG3b7G1l2yPBNzIA/FDHFz0NmE s43wQrjVQcCmUOoQL0D/D3jNsseujHWATSja2kj7jA3nUljZXpMN7wKMhIzYwL8ACGOphjT9CT4 uMEHt1u8qx0IUJAJ8sQCoKkdcuzHPTDBaJkV8wBzOtoD9iZgY+fLLZg45d/3+DxwAmvKlIFoQiD MKKM1XTXztYaTaiR+IAFUcjVVvbT6Vw7GGCnqRnEqpmAqwOUr52I3usOZsqogJUXbosxjga7/TA WmiPbAe04d/1xXZya7T4DhUkwgKqqSPAHX1tGM58NgMH2u4S5X8gM0mKJO5W8bc X-Received: by 2002:a05:622a:4811:b0:50d:6b06:a44e with SMTP id d75a77b69052e-50dd5ad8901mr325245731cf.17.1776256349793; Wed, 15 Apr 2026 05:32:29 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-50e1af9dc5fsm11747771cf.16.2026.04.15.05.32.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Apr 2026 05:32:29 -0700 (PDT) From: Michael Bommarito To: linux-usb@vger.kernel.org, Mika Westerberg Cc: Andreas Noever , Yehezkel Bernat , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v2 3/4] thunderbolt: property: cap recursion depth in __tb_property_parse_dir() Date: Wed, 15 Apr 2026 08:32:19 -0400 Message-ID: <20260415123221.225149-4-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260415123221.225149-1-michael.bommarito@gmail.com> References: <20260415032335.2826412-1-michael.bommarito@gmail.com> <20260415045246.GR3552@black.igk.intel.com> <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: e69b6c02b4c3 ("thunderbolt: Add functions for parsing and creating X= Domain property blocks") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-4-6 Assisted-by: Codex:gpt-5-4 Signed-off-by: Michael Bommarito --- 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 274b555d27c8..99ee7089456c 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 Tue Jun 16 02:34:53 2026 Received: from mail-qt1-f177.google.com (mail-qt1-f177.google.com [209.85.160.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 433222F616A for ; Wed, 15 Apr 2026 12:32:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256354; cv=none; b=i4nACxyLBpOs5Z0EHkyMDkccOksqptWXnJscGohJ3P19CtZFqAFYVKyFaDo5DOnqjdU72IYuQsfaBALJYNy6gLy3mukhcu2p/yuIZNozEPOT0vFymQd/KLjFvLqZ+pOL2vZ+SdICDtXnPgB1mYjNG8OqU5QkaFYQLVVF/nWmftU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776256354; c=relaxed/simple; bh=1l1cR5VAlx5dYOZdHqtWbaulDQgqIiBgksHXnCKMkfs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fata2U2lSNkFIYrToQ2zUuwBKcJDTWxtb9j9f8bM34V/4Ztj14B08AgedxdOWIe8dgrnoqE9CUC4gUwYz7FJ63qxtDCNOkB5UqE69IQg3cSn4nh94B4FZ0IA85wshe9p5J4Ye+h/fbSP3vK/2M2Utpgc0OIBhiGUUbGT+6cG9FU= 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=pcqa7Pwj; arc=none smtp.client-ip=209.85.160.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="pcqa7Pwj" Received: by mail-qt1-f177.google.com with SMTP id d75a77b69052e-50b2b289925so55167231cf.2 for ; Wed, 15 Apr 2026 05:32:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1776256351; x=1776861151; 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=vbvHAqDnj9FXaNRW0EKEP6rCGAhHRS/crPKa3pni2fo=; b=pcqa7PwjdoDlpQQwtix7b4biwESJAexwOb5Eqlx8QHmWXx7r5dpfC9OCXJZhcJkylF Y/aRxJbmgYF80u7udoSOT+8r9rt6fLr3L3twcShTFL9EFJlTl7koLCVV2RKQHyYqWHO/ 3rzba7QskLYeryHW3WuiNHbLzs0yGyVuhMnNfnwe3ABg50UjEdf7miNDrk9vWMxbAwxe q2pPrMZa2GyT3QlbgVQCsiFXMe5p8Qc0IyFNxmta/HTI9iGaj5UP3HtXgECjnoQ88Hfs UPlVbQcY36x0TWjXL6KimKNGjGTw4SFejnyDIP9CZlszdRokEVzt0pig4ieCfa7d25EK nzgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776256351; x=1776861151; 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=vbvHAqDnj9FXaNRW0EKEP6rCGAhHRS/crPKa3pni2fo=; b=F54L4vFmXX+uf1M1PoyR8KU4ECQtxQ4HbnKmtrgoAIT11k9nymeZc5b44fkUEHR4aN ito/bR3YQUOXuIywDQYGAZSqExlKVRm/Ah1t94u6N2KUYbGWrNF5LF4Ai3qgyXQWMIra KuKj0FFK/AS+tRQSH0gbNxxf0+Oc866hMt0r2Ocd8d9t0VpeQ/6zUyMuCFdNXPxnjeuR MX5I3ubsV/s+WnUxHtLtejF0PtEh64I1JPP0EK3dKcGQpQ+sdFkhr6iqqYwtBR07C7ZZ znEid8Ze/9Xv5Sd8tw4kq3NALxLhBZedPswHR6c5y7l9SNPSCiG3xo715k3UEbuuQixh U2lg== X-Forwarded-Encrypted: i=1; AFNElJ9bs0TsK5fr5XzlSDIo6c2OfwIBTytx+6anm0/fsAz9CUqtkERVNs7IMb92wDYomn+6gp0siXBXjxIsxpk=@vger.kernel.org X-Gm-Message-State: AOJu0Yy2c8bTF7Bxp/y9na3aREaNa4euErQU08mZxHJ0AUzQ8rAxj7SM dcNyn1/O9NCSLPGAqvOxeYbXZp5F9L0zsrNRv3Q1Youiff1Zl0UnyyH8 X-Gm-Gg: AeBDieuBuYCYFN1pDcJvxzf7sWePyf1Y6sjv2AkRNMGV/VZ+Iq+dGHFD/OXkIF4s5yI xNaGfEBPIVKuAtxgLdJaMoemkSYOs3bIG6WKSCifxfvQoEtiQ1nDN9ZTDDA/8k1lNjFmmGhtlDQ fjiXiVqS8zpbBXH7lT1s11aWKPptQuSHS6pNNffvVWsHdUlJUMZh1ZdKfjcnOvo7BPap/IODBVw LnX6KohTriLJYrKGv0QSqy5QI/3+IWuBycR8b0mJMC+DhIJADjCecsmQc4hto4CIouJVsQEOjTw DWjE0yVIOnSHBfwSvGat8P6g5G/MeELdX6hOIYrst7WlMddfnPFCIRVng8ZDH6tx8RrTDuGYcAR 2Yqd19kJr4DxangCWv22beSSjJN6Y9oRSoxoH4DBT/7gh8Kc2yvLs92eqiLiisRxhIR0J7N4X1t 59YhLC+Lo8mDf8W4XHbzbtjHj4RYzfe1zDM7L8UhQ/w9qJIrfwIkm9bfaqMFVqeVxYt2RCJ5GF+ vyMIB56bTZgd3bJw8Eh77MyUqD5DmBsWxcAB8xOCbIu6PlkLjHfxDhazN0CgqiD X-Received: by 2002:ac8:7c41:0:b0:50d:7f91:6bd8 with SMTP id d75a77b69052e-50dd5aef77emr311172841cf.28.1776256351143; Wed, 15 Apr 2026 05:32:31 -0700 (PDT) Received: from server0.tail6e7dd.ts.net (c-68-48-65-54.hsd1.mi.comcast.net. [68.48.65.54]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-50e1af9dc5fsm11747771cf.16.2026.04.15.05.32.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 15 Apr 2026 05:32:30 -0700 (PDT) From: Michael Bommarito To: linux-usb@vger.kernel.org, Mika Westerberg Cc: Andreas Noever , Yehezkel Bernat , Greg Kroah-Hartman , linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v2 4/4] thunderbolt: test: add KUnit regression tests for XDomain property parser Date: Wed, 15 Apr 2026 08:32:20 -0400 Message-ID: <20260415123221.225149-5-michael.bommarito@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260415123221.225149-1-michael.bommarito@gmail.com> References: <20260415032335.2826412-1-michael.bommarito@gmail.com> <20260415045246.GR3552@black.igk.intel.com> <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 non-root content_len =3D dir_len - 4 wraps size_t; without the fix nentries is huge and the entry walk runs OOB. Each test asserts tb_property_parse_dir() returns NULL on the crafted input. With CONFIG_KASAN=3Dy, running these on the pre-fix kernel reproduces an oops inside __tb_property_parse_dir (KASAN shadow-memory fault for the u32_wrap case, stack-guard trip for recursion, OOB read past block for dir_len underflow). Post-fix they 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 --- drivers/thunderbolt/test.c | 127 +++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/drivers/thunderbolt/test.c b/drivers/thunderbolt/test.c index 1f4318249c22..22f4107fcb8d 100644 --- a/drivers/thunderbolt/test.c +++ b/drivers/thunderbolt/test.c @@ -2852,7 +2852,134 @@ 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. + */ +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 { + u32 key_hi, key_lo; + u16 length; + u8 reserved; + u8 type; + u32 value; + } *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() at property.c:132 + * 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 0x64; /* TB_PROPERTY_TYPE_DATA */ + e->value =3D 0xFFFFFF00; + + dir =3D tb_property_parse_dir(block, 500); + /* With the fix this returns NULL; without it, KASAN splats in + * be32_to_cpu_array() / memcpy reading block + value*4 out of + * bounds. Assert on the safe outcome: a NULL dir. */ + 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 entry { + u32 key_hi, key_lo; + u16 length; + u8 reserved; + u8 type; + u32 value; + } *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 0x44; /* 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 0x44; + child_e->value =3D 2; + + dir =3D tb_property_parse_dir(block, 500); + /* With the fix this returns NULL at TB_PROPERTY_MAX_DEPTH (8). + * Without it, the kernel stack-guard fires ~50-80 frames in + * and the kunit thread oopses. */ + KUNIT_EXPECT_NULL(test, dir); + tb_property_free_dir(dir); +} + +static void tb_test_property_parse_dir_len_underflow(struct kunit *test) +{ + u32 *block =3D kunit_kzalloc(test, 500 * sizeof(u32), GFP_KERNEL); + struct tb_property_dir *dir; + struct entry { + u32 key_hi, key_lo; + u16 length; + u8 reserved; + u8 type; + u32 value; + } *e; + + block[0] =3D 0x55584401; + block[1] =3D 4; + + /* DIRECTORY entry with length=3D3. When parsed as non-root, + * content_len =3D dir_len - 4 underflows size_t to ~SIZE_MAX, + * nentries =3D SIZE_MAX/4. The for-loop walks entries past the + * block, reading OOB on each iteration. + */ + e =3D (void *)&block[2]; + e->key_hi =3D 0x61616161; + e->key_lo =3D 0x61616161; + e->length =3D 3; + e->type =3D 0x44; + e->value =3D 6; + + dir =3D tb_property_parse_dir(block, 500); + /* With the fix: NULL. Without: KASAN splat on + * block[content_offset + i*4] for i > 124 (past the 500-dword + * block). */ + 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