In pursuit of gaining full kernel instrumentation for signed[1], unsigned[2], and pointer[3] arithmetic overflow, we need to replace the handful of instances in the kernel where we intentionally depend on arithmetic wrap-around. Introduce Coccinelle script for finding these and replacing them with the new add_would_overflow() helper, for this common code pattern:
if (VAR + OFFSET < VAR) ... Link: https://github.com/KSPP/linux/issues/26 [1] Link: https://github.com/KSPP/linux/issues/27 [2] Link: https://github.com/KSPP/linux/issues/344 [3] Cc: Julia Lawall <julia.law...@inria.fr> Cc: Nicolas Palix <nicolas.pa...@imag.fr> Cc: "Gustavo A. R. Silva" <gustavo...@kernel.org> Cc: Justin Stitt <justinst...@google.com> Cc: co...@inria.fr Signed-off-by: Kees Cook <keesc...@chromium.org> --- .../coccinelle/misc/add_would_overflow.cocci | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 scripts/coccinelle/misc/add_would_overflow.cocci diff --git a/scripts/coccinelle/misc/add_would_overflow.cocci b/scripts/coccinelle/misc/add_would_overflow.cocci new file mode 100644 index 000000000000..b9b67c9c3714 --- /dev/null +++ b/scripts/coccinelle/misc/add_would_overflow.cocci @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-only +/// +/// Replace intentional wrap-around addition with calls to +/// check_add_overflow() and add_would_overflow(), see +/// Documentation/process/deprecated.rst +/// +// +// Confidence: High +// Comments: +// Options: --no-includes --include-headers + +virtual context +virtual report +virtual org +virtual patch + +@report_wrap_sum depends on !patch@ +type RESULT; +RESULT VAR; +expression OFFSET; +@@ + + { + RESULT sum; + ... + ( +* VAR + OFFSET < VAR + ) + ... + ( + VAR + OFFSET + ) + ... + } + +@wrap_sum depends on patch@ +type RESULT; +RESULT VAR; +expression OFFSET; +@@ + + { ++ RESULT sum; + ... + ( +- VAR + OFFSET < VAR ++ check_add_overflow(VAR, OFFSET, &sum) + ) + ... + ( +- VAR + OFFSET ++ sum + ) + ... + } + +@report_wrap depends on !patch && !report_wrap_sum@ +identifier PTR; +expression OFFSET; +@@ + +* PTR + OFFSET < PTR + +@patch_wrap depends on patch && !wrap_sum@ +identifier PTR; +expression OFFSET; +@@ + +- PTR + OFFSET < PTR ++ add_would_overflow(PTR, OFFSET) -- 2.34.1