From nobody Thu Apr 2 06:10:27 2026 Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (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 E94FE3BE17C for ; Mon, 30 Mar 2026 13:20:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774876813; cv=none; b=Ym2MkhA3WmFLGPPCshSmhjVlNaM2DImmKtmp9e04gjGY2vSuugCZcUcubkE5j6yJU+BWPDOGV5czxKQpOS0v5hc1L4Fyc2q4q1SvnzdGvdzdLmBEdYzHskeeAJFFDR3QZfkLX4dUF1n3NaHv5/3qImIqgQsr8wHU5zp6jC1V/XE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774876813; c=relaxed/simple; bh=3YWFDzWxZ3WGYfmZ0A23V87Rn40MxC8xYfA2yqnoHOc=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IK+4nxgvEoNFr7z+z0o7f1glTTtMLb847djdMFr4X1sm6Nik9Z4uDrOLjSVrvd3jiPb1Kc5Lxp/ChEp5JoPpUnyrhRcKN0FpXVhwelBMsynF/gnTkpXwnQYh1rzbLhQdhEGocM65U5Ts8iAF+5dp8TRYKAhPRKlEeydsfz8w9Xo= 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=ObT63NzR; arc=none smtp.client-ip=209.85.128.49 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="ObT63NzR" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-483487335c2so47714215e9.2 for ; Mon, 30 Mar 2026 06:20:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774876810; x=1775481610; 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=C/3iE861Wo3FM8pZvJTPy+1u03UK0/+dHCbLjC4fM40=; b=ObT63NzRn4ym+TPAV8+tlVNbEfQryecmWy7iel4zB/8RRQ//XlB7Ua9d+dHmjVMVjF 6gIAqXNTZwSZlXf0pv2cElZH4GTKFiRmx/qN5z3y2fLHq9D1a9yLu/Cc5GlTDduCWbWT SWsKysGDvZeiJN6NbQkaLYtdjxzm3yFrIcCuIKy+aUk5yWWBQEsVM0LVIHsD2hV3cs99 2GiWKsNfZ62qfSJpMEvXdXXaIYAOVPiifdncRhZmtINwmD2in6Si4hn+536nk6xJQPpi thTKQBMeWRcYyCWiBqN7GNnPLxIWBeirbPK+12fDReQeG170eoDr8/g6ueap505gXUEh 55mg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774876810; x=1775481610; 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=C/3iE861Wo3FM8pZvJTPy+1u03UK0/+dHCbLjC4fM40=; b=nvYWQDY8Sj/+Ns+BKJpj73LuokJAneDm3AbY3fAsqpysJGomDGi6l2LfKJdM11byLM ca01XbLMAQytgfeJue6ky/kJjjiX3cT8NFoLlsSJxpCOnTHEH+tapmS/Lm8zECLAjuEo 8jvV7hqbxpf+sxKIAWAYRoMPJtJdiC8JWO0Gt691YBHZcNtlI2OcowZZOFj/efJEQY3N E7/NwV6vfO6D1DER2KUxfkZKYXR0Qj9wpFzFX7QQ3uWh6gvJQ+kE2LpxSdnURCYy+dSX d9lNX6/VDQSfT4asM93qFD2V2mwcfwFCosOPZ/E53rE4f+tUNFxjgifTT1x5SPPDndFV jejg== X-Forwarded-Encrypted: i=1; AJvYcCWSp66oJLvnF1rtdLTuPzCUhWxTkYqcO1j6MrAHM6+y+Vd5I6jlUbmd3bd5fn3jaAH2eFRYg9JSsFU+hY8=@vger.kernel.org X-Gm-Message-State: AOJu0YyHd8dEuiVP7iWRkqtZn6PctBLBNay2i208sAr/feeGnPdvEKM4 UQ2b4bkeCBhsueVTYRx9oNCAfEjUsb4HWk4TYQA185Oh4wNi2k9nrBPQVjGgr50W X-Gm-Gg: ATEYQzw4J7AHdzZK0zYQqwPnOpEG6tgiphU2Fo7RS0K1vTUAzX9mupfSZwFUc+uYciu 7IgUsrU+jQ0jqpjsK4L9GeojTI/G/q8CDy5+40O9MpT4SnERvnkSdsz1JvhMAiqsnUOpWh6oZ57 8iysrejnBJ6WHiJ4oUD+FDqg541xh9j/OltkWhOlASBZN8HXA1mfrCEDfzzjVYy0z4SQMOQxb4z GR6tMP5GmZ1v47cJgyzqoS0rdla71kGKdOU0vyt5CwlRAcdkQO2+qHN1PoxAu+ucCtJvWitF5kv dDeeodKJ1YUT9xqpIONb7nzlq1h0ryWsbSLtHj80Y+OWb9J/y6W5kWXfqOGNDbL9XmYbOCYqyOF E47/xlovKjoHrfHwQmgFfaeYL/W079x4nGy7lj3NnKYKCEWlH899kqwC3AkwRA9o/dvvxaNOWp3 VN0wlqj0y0qKE/lBjrIZXpMLMUNbF9D91GNLd68jiR2GO2CQ5wBQS4sTcsJkjcgmEiatlln3Wlj 1eyI7Vps7ef4NEb6ek= X-Received: by 2002:a05:600c:4fc4:b0:485:3f72:3230 with SMTP id 5b1f17b1804b1-48727f3b3bamr213966315e9.15.1774876809890; Mon, 30 Mar 2026 06:20:09 -0700 (PDT) Received: from snowdrop.snailnet.com (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48725eb52e5sm81322315e9.7.2026.03.30.06.20.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Mar 2026 06:20:09 -0700 (PDT) From: david.laight.linux@gmail.com To: Kees Cook , linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org Cc: David Laight Subject: [PATCH next 1/3] fortify: replace __compiletime_lessthan() with statically_true() Date: Mon, 30 Mar 2026 14:20:01 +0100 Message-Id: <20260330132003.3379-2-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260330132003.3379-1-david.laight.linux@gmail.com> References: <20260330132003.3379-1-david.laight.linux@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" From: David Laight __compiletime_lessthan(a, b) is exactly the same as statically_true(a < b) Replace the former by the latter. Signed-off-by: David Laight --- include/linux/fortify-string.h | 47 +++++++++++++++------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 171982e53c9a..214d237214d5 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -154,11 +154,6 @@ extern char *__underlying_strncpy(char *p, const char = *q, __kernel_size_t size) #define POS0 __pass_object_size(0) #endif =20 -#define __compiletime_lessthan(bounds, length) ( \ - __builtin_constant_p((bounds) < (length)) && \ - (bounds) < (length) \ -) - /** * strncpy - Copy a string to memory with non-guaranteed NUL padding * @@ -196,7 +191,7 @@ char *strncpy(char * const POS p, const char *q, __kern= el_size_t size) { const size_t p_size =3D __member_size(p); =20 - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __write_overflow(); if (p_size < size) fortify_panic(FORTIFY_FUNC_strncpy, FORTIFY_WRITE, p_size, size, p); @@ -287,14 +282,14 @@ __FORTIFY_INLINE ssize_t sized_strscpy(char * const P= OS p, const char * const PO * If size can be known at compile time and is greater than * p_size, generate a compile time write overflow error. */ - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __write_overflow(); =20 /* Short-circuit for compile-time known-safe lengths. */ - if (__compiletime_lessthan(p_size, SIZE_MAX)) { + if (statically_true(p_size < SIZE_MAX)) { len =3D __compiletime_strlen(q); =20 - if (len < SIZE_MAX && __compiletime_lessthan(len, size)) { + if (len < SIZE_MAX && statically_true(len < size)) { __underlying_memcpy(p, q, len + 1); return len; } @@ -469,12 +464,12 @@ __FORTIFY_INLINE bool fortify_memset_chk(__kernel_siz= e_t size, */ =20 /* Error when size is larger than enclosing struct. */ - if (__compiletime_lessthan(p_size_field, p_size) && - __compiletime_lessthan(p_size, size)) + if (statically_true(p_size_field < p_size) && + statically_true(p_size < size)) __write_overflow(); =20 /* Warn when write size is larger than dest field. */ - if (__compiletime_lessthan(p_size_field, size)) + if (statically_true(p_size_field < size)) __write_overflow_field(p_size_field, size); } /* @@ -557,15 +552,15 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_siz= e_t size, */ =20 /* Error when size is larger than enclosing struct. */ - if (__compiletime_lessthan(p_size_field, p_size) && - __compiletime_lessthan(p_size, size)) + if (statically_true(p_size_field < p_size) && + statically_true(p_size < size)) __write_overflow(); - if (__compiletime_lessthan(q_size_field, q_size) && - __compiletime_lessthan(q_size, size)) + if (statically_true(q_size_field < q_size) && + statically_true(q_size < size)) __read_overflow2(); =20 /* Warn when write size argument larger than dest field. */ - if (__compiletime_lessthan(p_size_field, size)) + if (statically_true(p_size_field < size)) __write_overflow_field(p_size_field, size); /* * Warn for source field over-read when building with W=3D1 @@ -573,8 +568,8 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_= t size, * the same time. */ if ((IS_ENABLED(KBUILD_EXTRA_WARN1) || - __compiletime_lessthan(p_size_field, size)) && - __compiletime_lessthan(q_size_field, size)) + statically_true(p_size_field < size)) && + statically_true(q_size_field < size)) __read_overflow2_field(q_size_field, size); } /* @@ -699,7 +694,7 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int= c, __kernel_size_t size) { const size_t p_size =3D __struct_size(p); =20 - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __read_overflow(); if (p_size < size) fortify_panic(FORTIFY_FUNC_memscan, FORTIFY_READ, p_size, size, NULL); @@ -713,9 +708,9 @@ int memcmp(const void * const POS0 p, const void * cons= t POS0 q, __kernel_size_t const size_t q_size =3D __struct_size(q); =20 if (__builtin_constant_p(size)) { - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __read_overflow(); - if (__compiletime_lessthan(q_size, size)) + if (statically_true(q_size < size)) __read_overflow2(); } if (p_size < size) @@ -730,7 +725,7 @@ void *memchr(const void * const POS0 p, int c, __kernel= _size_t size) { const size_t p_size =3D __struct_size(p); =20 - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __read_overflow(); if (p_size < size) fortify_panic(FORTIFY_FUNC_memchr, FORTIFY_READ, p_size, size, NULL); @@ -742,7 +737,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const PO= S0 p, int c, size_t size) { const size_t p_size =3D __struct_size(p); =20 - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __read_overflow(); if (p_size < size) fortify_panic(FORTIFY_FUNC_memchr_inv, FORTIFY_READ, p_size, size, NULL); @@ -755,7 +750,7 @@ __FORTIFY_INLINE void *kmemdup_noprof(const void * cons= t POS0 p, size_t size, gf { const size_t p_size =3D __struct_size(p); =20 - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __read_overflow(); if (p_size < size) fortify_panic(FORTIFY_FUNC_kmemdup, FORTIFY_READ, p_size, size, @@ -793,7 +788,7 @@ char *strcpy(char * const POS p, const char * const POS= q) return __underlying_strcpy(p, q); size =3D strlen(q) + 1; /* Compile-time check for const size overflow. */ - if (__compiletime_lessthan(p_size, size)) + if (statically_true(p_size < size)) __write_overflow(); /* Run-time check for dynamic size overflow. */ if (p_size < size) --=20 2.39.5 From nobody Thu Apr 2 06:10:27 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 4F3643D16E9 for ; Mon, 30 Mar 2026 13:20:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774876813; cv=none; b=WZFqP4BOb35umWBj66h674k55JN3cGLDTYEjMt1622LzECeZIGRQxpE22LkjA/LmtGZXftzCHwB1meIVxWPmTEQSpNGQA5I47xPYgikLGLeTwRmEiUI5GuqRMzpT2lXkjCij5CCGnXrnRvGCqBQT+kCL5Pn/iARTzj1JjuMOhes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774876813; c=relaxed/simple; bh=HZW2oqrFDucg0/tmmpLC50psVTIubhNBRGZjkaePAI0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=nQuCyN1DVFmIqaJLLfqJgmZQmpiKLaUW5x9J/n2CUnnIQ5q66IlFhkBejvGpslt+USXiFO+u1nwNiCGEnl5cgkPCIdnEqT+drSFSNIJdzy4SdZraVBRhSYMHNleeo2Rw55LbD+dUk3VitufE3P6267Qvcjv3Khbin3tmminrGWo= 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=GdnnS/2x; arc=none smtp.client-ip=209.85.128.52 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="GdnnS/2x" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-486b9675d36so37729195e9.0 for ; Mon, 30 Mar 2026 06:20:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774876811; x=1775481611; 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=3WJtJ9/xLPusko++aTLmU08qrObcTNq16sGagCzREHs=; b=GdnnS/2x7M/gzkx8TdzaO6tcuA7ISCTZ9TKbEhQFYqtIN4AaqiXtX9cNSuA9UCJdMy ISQ136dV4UwrpoE5JyBh9Err4cwD6DQdXZ8J5Y5RGDesK6ryp0dXeS980Xm8wybxrHdF keGf13qEoapkuwFGkvTQJ79uElru548gVBQ8EOJElrmo31YzbGfY2RcQxE/u1L9iDP7x qsYCJ2PkyhaGzIQml7edja9N9pFJyQkH41h10H9tmMQc3VM5niK4gCR7mOl2DMdr7JGX l+KYZskbyyUTKhOsko3+EtqiEK9aYxyaQxM1V2zZNx+gSvibFn9/OUJl8gF1JTGPWq6P w/IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774876811; x=1775481611; 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=3WJtJ9/xLPusko++aTLmU08qrObcTNq16sGagCzREHs=; b=kzJLlMpPQMQsEG/nOOlLsc1DG3QoJoAvwljLpCffPRXBGNOQGqGUmwBe04Cs8NLv/H 1QcySNNIgjqXhHv79mC3t9OGFBLIQBoyiQJWr8PmSEaGCmKrWXqv3yJItGUC97/WP3Vp Cb1Pi/UdqARHv1ZrmJWLpRTWTB89dIpAxr9NGCVOpXV+2DhbaiKamcVrDjpCHaUpaMAl G+K7jFE8NX8Rn12STZpk+KCC+Vzvtl/gQelEY33qbGfZD4u5bidHFjX5wz/jRW3E1+vR Rjg8IFfkF2tf//yClu/ro2+/30EAvQI3JLkn+tgJlZgPhPgUcYhz4hRHIUh6rA+yO2g6 4ABQ== X-Forwarded-Encrypted: i=1; AJvYcCU7JEqnDgLZNOuQieDan9+wheLjpXUpedsTst/IEBUmoEMX5eOvRPegNipIhxeWvRCP4VdM4TIDswQWZhg=@vger.kernel.org X-Gm-Message-State: AOJu0YwWJ5T/gp+Sfap0Ng0+PHLyPZxdbbDDnUx1quDnQm9pxn5DRGxX L0uelD+Jq81I0izv77vRk1wO2nkoHP+VRGvz3Fo+CWM9TT3hXhHbdiWaG+kJ4Nm1 X-Gm-Gg: ATEYQzwirCzRuNVKM45STa+SxiEA+g5Fp6exzn8EURMHTsxpVdASNkVqhj+egU0x0Sf 7VEt+APE3hpXD2b0mHORzY3tNT5eM8yQAIPzlijUp5n7FMjcEeG3qCs/oI0ZJH5e3UDSmtWNW8s wTA39sgPOWLN0LAOSVYfUpTuMAEY6SJdVtFmQaowlmc22Xn3z3WX0nYH9htdIxJpNY1nFWEmdUg PcWhRD+2STce0Mn+TwNq8jhb5toQ9CXch0JVRMmEOf94seGTldoIwKQzA5IxQrKTrhYSwg9v4/n pCg6z6zUgEOlPQPlPlwU6x6w6mmRaYgfdiyyVwN+NusQ/01CrB6SDkjOe5n4/Ukq3ly+4yXAju5 ACQ8WagXWHOOycFJZjz8o4BckBlQCIPtYhIaCMb3TmMONupr4qZUNH3kalFqWNLjDpSInH2hvus KDRQeFzpACImu3jh2DKBHB+IAb2Nv00wQKaN6BrlGxjMacZXurygLxAyTWlibB/BDSpJWwCHYS1 qfCbjy7p4dDpFi6GVE= X-Received: by 2002:a05:600c:154c:b0:480:2521:4d92 with SMTP id 5b1f17b1804b1-48727ede0admr214729635e9.24.1774876810462; Mon, 30 Mar 2026 06:20:10 -0700 (PDT) Received: from snowdrop.snailnet.com (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48725eb52e5sm81322315e9.7.2026.03.30.06.20.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Mar 2026 06:20:10 -0700 (PDT) From: david.laight.linux@gmail.com To: Kees Cook , linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org Cc: David Laight Subject: [PATCH next 2/3] fortify: Optimise strnlen() Date: Mon, 30 Mar 2026 14:20:02 +0100 Message-Id: <20260330132003.3379-3-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260330132003.3379-1-david.laight.linux@gmail.com> References: <20260330132003.3379-1-david.laight.linux@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" From: David Laight If the string is constant there is no need to call __real_strlen() even when maxlen is a variable - just return the smaller value. If the size of the string variable is unknown fortify_panic() can't be called, change the condition so that the compiler can optimise it away. Change __compiletime_strlen(p) to return a 'non-constant' value for non-constant strings (the same as __builtin_strlen()). Simplify since it is only necessary to check that the size is constant and that the last character is '\0'. Explain why it is different from __builtin_strlen(). Update the kunit tests to match. Signed-off-by: David Laight --- include/linux/fortify-string.h | 44 +++++++++++++++++----------------- lib/tests/fortify_kunit.c | 8 +++---- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 214d237214d5..758afd7c5f8a 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -58,19 +58,22 @@ void __read_overflow2_field(size_t avail, size_t wanted= ) __compiletime_warning(" void __write_overflow(void) __compiletime_error("detected write beyond siz= e of object (1st parameter)"); void __write_overflow_field(size_t avail, size_t wanted) __compiletime_war= ning("detected write beyond size of field (1st parameter); maybe use struct= _group()?"); =20 -#define __compiletime_strlen(p) \ -({ \ - char *__p =3D (char *)(p); \ - size_t __ret =3D SIZE_MAX; \ - const size_t __p_size =3D __member_size(p); \ - if (__p_size !=3D SIZE_MAX && \ - __builtin_constant_p(*__p)) { \ - size_t __p_len =3D __p_size - 1; \ - if (__builtin_constant_p(__p[__p_len]) && \ - __p[__p_len] =3D=3D '\0') \ - __ret =3D __builtin_strlen(__p); \ - } \ - __ret; \ +/* + * __builtin_strlen() generates a compile-time error for 'const char foo[4= ] =3D "abcd";'. + * But that is a valid source for both strnlen() and strscpy() with a cons= tant + * length less than or equal to 4. + * __compiletime_strlen() returns a non-constant for such items. + * Beware of strings with embedded '\0', __builtin_strlen() can be much sm= aller + * than __member_size(); + * The return value must only be used when it is a constant. + */ +extern size_t __fortify_undefined; +#define __compiletime_strlen(p) \ +({ \ + char *__p =3D (char *)(p); \ + const size_t __p_size =3D __member_size(p); \ + __p_size =3D=3D SIZE_MAX || !statically_true(__p[__p_size - 1] =3D=3D '\0= ') ? \ + __fortify_undefined : __builtin_strlen(__p); \ }) =20 #if defined(__SANITIZE_ADDRESS__) @@ -215,16 +218,13 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char *= const POS p, __kernel_size const size_t p_len =3D __compiletime_strlen(p); size_t ret; =20 - /* We can take compile-time actions when maxlen is const. */ - if (__builtin_constant_p(maxlen) && p_len !=3D SIZE_MAX) { - /* If p is const, we can use its compile-time-known len. */ - if (maxlen >=3D p_size) - return p_len; - } + /* If p is const, we can use its compile-time-known len. */ + if (__builtin_constant_p(p_len)) + return p_len < maxlen ? p_len : maxlen; =20 /* Do not check characters beyond the end of p. */ - ret =3D __real_strnlen(p, maxlen < p_size ? maxlen : p_size); - if (p_size <=3D ret && maxlen !=3D ret) + ret =3D __real_strnlen(p, p_size < maxlen ? p_size : maxlen); + if (ret =3D=3D p_size && p_size < maxlen) fortify_panic(FORTIFY_FUNC_strnlen, FORTIFY_READ, p_size, ret + 1, ret); return ret; } @@ -289,7 +289,7 @@ __FORTIFY_INLINE ssize_t sized_strscpy(char * const POS= p, const char * const PO if (statically_true(p_size < SIZE_MAX)) { len =3D __compiletime_strlen(q); =20 - if (len < SIZE_MAX && statically_true(len < size)) { + if (statically_true(len < size)) { __underlying_memcpy(p, q, len + 1); return len; } diff --git a/lib/tests/fortify_kunit.c b/lib/tests/fortify_kunit.c index fc9c76f026d6..9b3b7201c02d 100644 --- a/lib/tests/fortify_kunit.c +++ b/lib/tests/fortify_kunit.c @@ -102,11 +102,11 @@ static void fortify_test_known_sizes(struct kunit *te= st) KUNIT_EXPECT_EQ(test, __compiletime_strlen(unchanging_12), 12); =20 KUNIT_EXPECT_FALSE(test, __is_constexpr(__builtin_strlen(array_unknown))); - KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_unknown), SIZE_MAX); + KUNIT_EXPECT_FALSE(test, __is_constexpr(__compiletime_strlen(array_unknow= n))); =20 /* Externally defined and dynamically sized string pointer: */ KUNIT_EXPECT_FALSE(test, __is_constexpr(__builtin_strlen(test->name))); - KUNIT_EXPECT_EQ(test, __compiletime_strlen(test->name), SIZE_MAX); + KUNIT_EXPECT_FALSE(test, __is_constexpr(__compiletime_strlen(test->name))= ); } =20 /* This is volatile so the optimizer can't perform DCE below. */ @@ -128,12 +128,12 @@ static noinline size_t want_minus_one(int pick) str =3D "1"; break; } - return __compiletime_strlen(str); + return __builtin_constant_p(__compiletime_strlen(str)); } =20 static void fortify_test_control_flow_split(struct kunit *test) { - KUNIT_EXPECT_EQ(test, want_minus_one(pick), SIZE_MAX); + KUNIT_EXPECT_FALSE(test, want_minus_one(pick)); } =20 #define KUNIT_EXPECT_BOS(test, p, expected, name) \ --=20 2.39.5 From nobody Thu Apr 2 06:10:27 2026 Received: from mail-wm1-f47.google.com (mail-wm1-f47.google.com [209.85.128.47]) (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 AAB8A3D3CE3 for ; Mon, 30 Mar 2026 13:20:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774876814; cv=none; b=ubog7cFKqdm6GgZ3En8NZwfXWJUxmFbRAc6Fes19KFKftdJMlV+Yvf9ImUb+wi8tUvre2Q/nP4jO0tFK4Tf+jyVVqW/8T2faModNWY2EYzufGDLox95tyyzkE0qWvIWClU78x9nXeEKzuqA8uWKHCAPRipyexicMne5c4F55Gl8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774876814; c=relaxed/simple; bh=Apu7QMg5t9X4XqrrbiaHMr1fwOGa5UsX6I+AkCFq82s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rFfgtx73LWB1ArgaWgjKy9u14UhZzLCiQSvnqb0s7udRp37oL7sl1NlVCFUeKyj5jydatJgrfxk6V5ioyCzIpauqqxObWUNcGfykIcYBSMpfUKMzjZTm8qjCD2HOeOKjwfWdzibAy1NfWdxZcSvViWNfDqB/MvyahgHNkBU7QCw= 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=iu08MTWV; arc=none smtp.client-ip=209.85.128.47 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="iu08MTWV" Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-48538c5956bso44543405e9.0 for ; Mon, 30 Mar 2026 06:20:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774876811; x=1775481611; 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=WAjBJkYCqeFogUSVOqhybn+Qkp+h53Wf7afwElb+C9U=; b=iu08MTWVyQBXil+stpw+Uc+GBUJA0R0ERNFTJaaTpCyKaQlmZMq092fYT58Jzp8e2p Q18/BSrMjxx2mfOlwc52tuJSJ5vp3MNJo5OwKfQCjKA6CTXkuOqQKxCn7chURrIKn1Qv 1EjiDWlaG+WvYocIdUZio+Y+5+of/9NwSKrnUbdUD0ZNhlTfCqw+fkKSNW/NHw7p94Eb I8TzqP3g+Hox/iDuIE2EmnYGqn1ABpnp2uvuROc6mzh+9cQl36OW4mMkZlg7r9XA0wd2 6qKUGzY0sbKIYFgpzjYJj2BvKki1qrdxcEAbxUFuh12jtKwkIsowrYemNY+m1CB9TqPu ZRag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774876811; x=1775481611; 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=WAjBJkYCqeFogUSVOqhybn+Qkp+h53Wf7afwElb+C9U=; b=bPTn06euJwjOGeEgk2ihiMuwdAyyKSAxfYQiGSq6aBmiAu3MKKc8kJTvwKkhLJWGKO QQl31c8TlFk82Ds8wXq9jbcZ4tgsbiC29hExsKCO6NNl7vKHx8exKbdP8otKAt/gyaF+ 6am47osxxqIh7x4zfgZM/QlOrSwMmnPN0TO5O+Xhu/DnyXN8nQpn9IpWsaPxk1xbG4/d efwCdduUAhwoSIhLgfPlG8BTtYKekYMYdz5z29aa6IbKnifdZCdHtJq7ZeXvpjpT0bYw Fiq+ymxrcqEWCdvLItfY4IF/64CGU4rYsP/5D6il+MXkl8FoObWs/vlLd/zDTGBU351q kQwQ== X-Forwarded-Encrypted: i=1; AJvYcCWDtZHODMUs6O8peksZI1XYr65YCNHpxA3iUFW/S76lX+AN3I365xXL/PkWgOfU5QKswYaNfvFC0fyU6dE=@vger.kernel.org X-Gm-Message-State: AOJu0Yz5uUhMpL9MlPlW7P795KQkahKw0zpwHj5vw8/OMORU7Hj5QhJ4 hbx614PeuV1kZg2XPzAh+/RdN//BdAO6JF5potFxqLS9Q5OgfDhaEp26 X-Gm-Gg: ATEYQzxQru2nErq+FteFkbLDUazPQskUrfo5dsRjNcDH55D91DoimDTO4j64MkCNnXp lvg2QViOv5P7onGZzPp7zxomXDfYVJ42Rsgs0CdGyhPjaHaR80b52vD36XzvicDPVwYlIPI3Md/ VC2hxtZzAbpeh6g+hWIYcReIkqFYvBHvVmyvf4NeLIZJJ2iLbu6lf2HWFz+33ohtZ5NqF//t8/X 1NyNUnHXKi+gj6qix22QdvpZj2IG3Rc/DL4DW6jfmDXqvgG5NQEjn8z6U2NyNaEMI6EXJqb7HzT rr2VdFZLJ6uOTwKVPUDJG7Mpyk0bhy5EF6Fc+gqNUXYIFVwkgF90rd2JHdOts7OnwzRHK7gaPrE PbCTn9ytcwpWV0+c4KdngCX1HUleobgv7/T5U3Jan+99vz1GbsYo8FQa/rh+E+zdHv3eqX1+C/p rnMqnEfwmbUacD7tzvNm0qgm1f5ypBvpItHGJLVIjI1Z/RTw4SmF3nD2dMZciOxnvXtOCkidcBx HT2QvzB X-Received: by 2002:a05:600c:4e0b:b0:485:fbd2:f72 with SMTP id 5b1f17b1804b1-487290a9254mr185295365e9.1.1774876810909; Mon, 30 Mar 2026 06:20:10 -0700 (PDT) Received: from snowdrop.snailnet.com (82-69-66-36.dsl.in-addr.zen.co.uk. [82.69.66.36]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48725eb52e5sm81322315e9.7.2026.03.30.06.20.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Mar 2026 06:20:10 -0700 (PDT) From: david.laight.linux@gmail.com To: Kees Cook , linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org Cc: David Laight Subject: [PATCH next 3/3] fortify: Simplify strlen() logic Date: Mon, 30 Mar 2026 14:20:03 +0100 Message-Id: <20260330132003.3379-4-david.laight.linux@gmail.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260330132003.3379-1-david.laight.linux@gmail.com> References: <20260330132003.3379-1-david.laight.linux@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" From: David Laight The __builtin_choose_expr() doesn't gain you anything, replace with a simple ?: operator. Then __is_constexpr() can then be replaced with __builtin_constant_p(). This still works for static initialisers - the expression can contain a function call - provided it isn't actually called. Calling the strnlen() wrapper just add a lot more logic to read through. Replace with a call to __real_strnlen(). However the compiler can decide that __builtin_constant_p(__builtin_strlen(= p)) is false, but split as ret =3D __builtin_strlen(p); __builtin_constant_p(re= t) and it suddenly becomes true. So an additional check is needed before calling __real_strnlen(). Signed-off-by: David Laight --- include/linux/fortify-string.h | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h index 758afd7c5f8a..6cd670492270 100644 --- a/include/linux/fortify-string.h +++ b/include/linux/fortify-string.h @@ -230,9 +230,8 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * c= onst POS p, __kernel_size } =20 /* - * Defined after fortified strnlen to reuse it. However, it must still be - * possible for strlen() to be used on compile-time strings for use in - * static initializers (i.e. as a constant expression). + * strlen() of a compile-time string needs to be a constant expression + * so it can be used, for example, as a static initializer. */ /** * strlen - Return count of characters in a NUL-terminated string @@ -247,9 +246,9 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * c= onst POS p, __kernel_size * Returns number of characters in @p (NOT including the final NUL). * */ -#define strlen(p) \ - __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \ - __builtin_strlen(p), __fortify_strlen(p)) +#define strlen(p) \ + (__builtin_constant_p(__builtin_strlen(p)) ? \ + __builtin_strlen(p) : __fortify_strlen(p)) __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1) __kernel_size_t __fortify_strlen(const char * const POS p) { @@ -259,7 +258,14 @@ __kernel_size_t __fortify_strlen(const char * const PO= S p) /* Give up if we don't know how large p is. */ if (p_size =3D=3D SIZE_MAX) return __underlying_strlen(p); - ret =3D strnlen(p, p_size); + /* + * 'ret' can be constant here even though the __builtin_constant_p(__buil= tin_strlen(p)) + * in the #define wrapper is false. + */ + ret =3D __builtin_strlen(p); + if (__builtin_constant_p(ret)) + return ret; + ret =3D __real_strnlen(p, p_size); if (p_size <=3D ret) fortify_panic(FORTIFY_FUNC_strlen, FORTIFY_READ, p_size, ret + 1, ret); return ret; --=20 2.39.5