From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.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 631C72D63FC for ; Fri, 28 Nov 2025 03:38:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764301128; cv=none; b=Z94LjYC1N4K6TKWIRGbzm0qoegTObotpiKrcShJrv+rnzfNkB4Fn79ko47YWz16n97jPf7T696jRVriBlZRpHGtQW5vJu9oGCf7oxiQf/NftUGEkZMgclVIvSL2sSekoe3yT+nCw88NzaiRIk2Ll1qLZ+TIB956pcbQtyfMqTvI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1764301128; c=relaxed/simple; bh=sMBKDRD+YrHinlsLvurDgItZTjpQeHNXx79vuRmCgYU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=B9mnsaewyMsnVloNsKxZopkKYocPPJKrbQEbXB8XgN9TAmTTkeiGGq9SFyhjS+CLfyd0/AkZbw8t/8jJxBwzlXaQ6cNkdomW2lvyF+w6k56VLYVsp9xHOv9wgqzHTb3fSOSkrLUwf8iQjgL+/1arLZI7JDDQ8sCTEQBL7Riu1uc= 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=XsE9pO7+; arc=none smtp.client-ip=209.85.214.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="XsE9pO7+" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-299d40b0845so22993305ad.3 for ; Thu, 27 Nov 2025 19:38:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1764301125; x=1764905925; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=ziPHSW1BGt5FHNc124Rg2eHBj/FnR6+g6Xe4TDQvAMs=; b=XsE9pO7+3hC4OUrS3lHJ1mcWQzciCp8FxN5yTW6fQ2zOmHGQ8M4oH8fuXsVJnvPpy+ l+jZczkVnHGCrcMtMK2riiEK51+JVoo/HJT9M2K9YLAX8FdOvYONfeAHTDB4UZI94FTj EGrPs4eFgprrDVautjaQJTiVvCtD3P8XZkKXpxkY40rjS71FniRPfzFuWyCu4e51M287 eDUXdYjQdY4ZTxQSwEivf465WFHBqFqRufrLYdK9W7jIALozHKVj51UopAJ+2zHrLQoa W8bUmBlY0BUQCMwSiIY3NVlwZFCqOGrQxyhwE5oKmdm2ySwoi6MBgkEDd15CGPAl8J7C U6+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1764301125; x=1764905925; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ziPHSW1BGt5FHNc124Rg2eHBj/FnR6+g6Xe4TDQvAMs=; b=UtSio63ACPW6+a234n0qFh+JTb9JY7LKZEEE6Zy/NJXF0m+uCQcKKB85DW7w8UNFhu +3VSvxvQM6hAkXmPxNlemnZ0Ba3K77/nGANt/mz5+aHpmd41ho9jx2l9sgQ0Z+S6B/Sq GXQGOedp2rg9Mp1uMKNSW300FsatCoKnXCykgwwPwWJM6Ct23pMHnVztCmLwKqEZgVAB ZiXxIg8YMj7AaFXsF3RqnEwHBP4coIhOqG7XN5WgJc9sJwL7tAOJLUD8aXTMw9wyG/pw fYwmRm704k4incaxlLEcKjOusQ/uDLAbLVh8kaLm0vqAVoFYXleka8SrPimK+Dr6trl0 o3Hg== X-Forwarded-Encrypted: i=1; AJvYcCWtDb+HqmTI6ePABdQigsnlmG+kAKpwNG3mkHR2VHl74d2BLzAC8hJ47I0ZBycnHiJO9rL7ncFXNWwurIo=@vger.kernel.org X-Gm-Message-State: AOJu0Ywoqove7u91icAmgL1VCHqd87UJ+z33RzQnYrgIEBTV7xxd5UIJ UArt1tKUN0Q9jmDC11/PzCHg3cZdYiiF0sJrH+gY5cl9QVR7UW2G1sqOnJLn/fAs X-Gm-Gg: ASbGncsl1WP2T69pTLhlMwH7W0AKI7mCZAawcGL6BF2/OX0cESWklrYpSSfgtLjvwLk CQhCjq4kNur9QRlOd4Ex4Z1COKWkS23rjbA1W7VO/KKHF/MuNZ2DUi8TIN8zmAscdJk2udFWZ5I zT8gzkwTSi0+j3qxwPrB7s+wtkPcUQJTiQ2x8GNFVJErRkI4pbC4rv0UWVd4qzYtGmFau08taL6 568aP4vDPq2ehh1eU9Z7YbEkB3ggyXjsjWEFOU6lG627eK7OD6TBgqEXJk7zkGJthYGf/zljXtY qFhd1IQNdEZa5f3+1U3H2Kx93jWtIA4s4u5Tz4rAyh+/j5wjKJPz7MvW9Vzjsi70WJCuj0ZNkM9 VTFSH8rw4DpiFDqcbUbfhro8l1wy47BCx/T2odxOzl+xquwYSUWjrB7pTzhgZPeXKJ0vrhuBULp 4VcvNP02M66E8r8dJWpfjqgEnfv/1R5dDahdGPQ+meQ6c= X-Google-Smtp-Source: AGHT+IFt9EDm0A4kR/jetSc5ONCPPaPv+xOssujZest1xVvCRUMsS+sNCTakUIo6Ju1tul/uNkazaw== X-Received: by 2002:a05:7022:62aa:b0:11b:c1ab:bdd4 with SMTP id a92af1059eb24-11cbba4ab67mr9193598c88.38.1764301125421; Thu, 27 Nov 2025 19:38:45 -0800 (PST) Received: from ParadiseLost.localdomain (lohr.com.br. [177.69.253.233]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-11dcb03cc7dsm13999469c88.5.2025.11.27.19.38.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 27 Nov 2025 19:38:44 -0800 (PST) From: "Rafael V. Volkmer" To: Kees Cook Cc: "Gustavo A . R . Silva" , linux-hardening@vger.kernel.org, linux-kernel@vger.kernel.org, "Rafael V. Volkmer" Subject: [PATCH 0/2] overflow: extend shift helpers and add size_shl() Date: Fri, 28 Nov 2025 00:38:28 -0300 Message-ID: <20251128033830.331426-1-rafael.v.volkmer@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Hello, while experimenting with check_shl_overflow() on an architecture with native __int128 support, I noticed that the helper always reports overflow as soon as the promoted type of @a/@d is wider than 64 bits, even when *@d is actually able to represent the shifted value. The current implementation always evaluates (@a << @s) through an unsigned long long accumulator: unsigned long long _a_full = _a; *_d = (_a_full << _to_shift); When @a is __int128, this truncates it to 64 bits before the shift and then checks for overflow against the truncated result. As a consequence, the helper cannot reason correctly about __int128 inputs. A minimal reproducer looks like this: __int128 a = (__int128)1 << 80; unsigned int s = 4; __int128 res = 0; bool overflow = check_shl_overflow(a, s, &res); On a toolchain and architecture that support __int128, this reports overflow even though __int128 can hold the full result of (1 << 84). This series introduces an internal evaluation type selector that widens the accumulator to unsigned __int128 when available and needed, and then builds a size_t-focused size_shl() helper on top of the existing size_* family. Patch 1 adds __shl_eval_type(), which chooses the accumulator type based on the promoted width of @a and *@d. On CONFIG_ARCH_SUPPORTS_INT128 systems it uses u128 whenever the expression is wider than 64 bits, otherwise it keeps the existing unsigned long long behaviour. This keeps code generation identical for all current 64-bit users, while allowing callers that use __int128 for intermediate arithmetic (e.g. 64x64->128 products or wide offset calculations) to benefit from a wider accumulator before eventually truncating back to a narrower destination type. Patch 2 adds size_shl(), a saturating left-shift helper for size_t that mirrors size_add(), size_sub() and size_mul(). It computes (value << shift) and returns SIZE_MAX whenever check_shl_overflow() reports an invalid or overflowing shift, which makes it easier to build higher-level size calculations that must treat any shift overflow as a hard upper bound. Testing ------- - built and boot-tested defconfig kernels on x86_64 and arm64, but with few drivers/modules enabled in kconfig, and - exercised check_shl_overflow() with 32-bit, 64-bit and __int128 inputs in a standalone userspace test. For convenience during review, a small userspace snippet mirroring the change is available on Compiler Explorer: https://godbolt.org/z/5dq413d73 ------- Feedback on the approach is very welcome. Thanks for your time and review. Best regards, Rafael V. Volkmer Rafael V. Volkmer (2): overflow: make check_shl_overflow() 128-bit aware overflow: add size_shl() helper for saturated left shifts include/linux/overflow.h | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) -- 2.43.0