linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around
@ 2024-01-23  0:26 Kees Cook
  2024-01-23  0:26 ` [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition Kees Cook
                   ` (83 more replies)
  0 siblings, 84 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

Hi,

In our continuing effort to eliminate root causes of flaws in the kernel,
this series is the start to providing a way to have sensible coverage
for catching unexpected arithmetic wrap-around.

A quick word on language: while discussing[1] the finer details of
the C standard's view on arithmetic, I was disabused of using the term
"overflow" when what I really mean is "wrap-around". When describing
security vulnerabilities, "overflow" is the common term and often used
interchangeably with "wrap-around". Strictly speaking, though, "overflow"
applies only to signed[2] and pointer[3] types, and "wrap-around" is for
unsigned[4]. An arithmetic "overflow" is considered undefined behavior,
which has caused our builds pain in the past, since "impossible"
conditions might get elided by the compiler. As a result, we build
with -fno-strict-overflow which coverts all "overflow" conditions into
"wrap-around" (i.e. 2s complement), regardless of type.

All this is to say I am discussing arithmetic wrap-around, which is
the condition where the value exceeds a type's maximum value (or goes
below its minimum value) and wraps around. I'm not interested in the
narrow definition of "undefined behavior" -- we need to stamp out the
_unexpected_ behavior, where the kernel operates on a pathological value
that wrapped around without the code author's intent.

As always, this is about being able disambiguate the intent of arithmetic
in the kernel. We intentionally use wrapping arithmetic in all kinds of
places, but we need to be able to annotate it as such going forward so
the compiler can distinguish when it needs to perform instrumentation
(when such instrumentation is enabled).

Getting back to my earlier mention of -fno-strict-overflow, the bulk of
the series is refactoring for a common code pattern in the kernel where
to test for potentially overflowing addition, the addition is performed,
and wrap-around is tested for. This is what originally[5] caused us to
enable -fno-strict-overflow:

	var + offset < var

For these cases we can use either check_add_overflow() or
add_would_overflow(). These helpers will not trip the wrap-around
instrumentation, and do not depend on the whims of the compiler options.
(Note that I have no intention of removing -fno-strict-overflow any
time soon, if ever. As with all these kinds of changes, we need to
evolve our support for it, and we can't introduce undefined behavior
into the kernel.)

This series is mainly 3 parts:

 - documentation, a coccinelle script, and new/improved helpers
 - (re)introduction of the overflow sanitizers
 - refactoring the "please wrap around to see if I wrapped around" tests

While this work is underway in the kernel, there will be complementary
work happening in GCC and Clang to expand the existing sanitizers
to behave correctly with -fno-strict-overflow. In the meantime, the
sanitizers are excluded from CONFIG_COMPILE_TEST.

-Kees

[1] https://gcc.gnu.org/pipermail/gcc-patches/2023-September/630578.html
[2] https://github.com/KSPP/linux/issues/26
[3] https://github.com/KSPP/linux/issues/344
[4] https://github.com/KSPP/linux/issues/27
[5] https://bugzilla.kernel.org/show_bug.cgi?id=12597

Kees Cook (82):
  overflow: Expand check_add_overflow() for pointer addition
  overflow: Introduce add_would_overflow()
  overflow: Introduce add_wrap()
  docs: deprecated.rst: deprecate open-coded arithmetic wrap-around
  cocci: Refactor open-coded arithmetic wrap-around
  overflow: Reintroduce signed and unsigned overflow sanitizers
  overflow: Introduce CONFIG_UBSAN_POINTER_WRAP
  iov_iter: Avoid wrap-around instrumentation in
    copy_compat_iovec_from_user
  select: Avoid wrap-around instrumentation in do_sys_poll()
  locking/atomic/x86: Silence intentional wrapping addition
  arm64: atomics: lse: Silence intentional wrapping addition
  ipv4: Silence intentional wrapping addition
  btrfs: Refactor intentional wrap-around calculation
  smb: client: Refactor intentional wrap-around calculation
  dma-buf: Refactor intentional wrap-around calculation
  drm/nouveau/mmu: Refactor intentional wrap-around calculation
  drm/vc4: Refactor intentional wrap-around calculation
  ext4: Refactor intentional wrap-around calculation
  fs: Refactor intentional wrap-around calculation
  fpga: dfl: Refactor intentional wrap-around calculation
  drivers/fsi: Refactor intentional wrap-around calculation
  x86/sgx: Refactor intentional wrap-around calculation
  KVM: Refactor intentional wrap-around calculation
  KVM: arm64: vgic: Refactor intentional wrap-around calculation
  KVM: SVM: Refactor intentional wrap-around calculation
  buildid: Refactor intentional wrap-around calculation
  m68k: Refactor intentional wrap-around calculation
  niu: Refactor intentional wrap-around calculation
  rds: Refactor intentional wrap-around calculation
  s390/kexec_file: Refactor intentional wrap-around calculation
  ARC: dw2 unwind: Refactor intentional wrap-around calculation
  vringh: Refactor intentional wrap-around calculation
  mm/vmalloc: Refactor intentional wrap-around calculation
  ipc: Refactor intentional wrap-around calculation
  ACPI: custom_method: Refactor intentional wrap-around test
  agp: Refactor intentional wrap-around test
  aio: Refactor intentional wrap-around test
  arm: 3117/1: Refactor intentional wrap-around test
  crypto: Refactor intentional wrap-around test
  arm64: stacktrace: Refactor intentional wrap-around test
  wil6210: Refactor intentional wrap-around test
  bcachefs: Refactor intentional wrap-around test
  bpf: Refactor intentional wrap-around test
  btrfs: Refactor intentional wrap-around test
  cifs: Refactor intentional wrap-around test
  crypto: Refactor intentional wrap-around test
  dm verity: Refactor intentional wrap-around test
  drm/nouveau/mmu: Refactor intentional wrap-around test
  drm/i915: Refactor intentional wrap-around test
  drm/vc4: Refactor intentional wrap-around test
  ext4: Refactor intentional wrap-around test
  f2fs: Refactor intentional wrap-around test
  fs: Refactor intentional wrap-around test
  hpfs: Refactor intentional wrap-around test
  kasan: Refactor intentional wrap-around test
  usercopy: Refactor intentional wrap-around test
  KVM: arm64: vgic-v3: Refactor intentional wrap-around test
  s390/mm: Refactor intentional wrap-around test
  lib/scatterlist: Refactor intentional wrap-around test
  powerpc: Refactor intentional wrap-around test
  scsi: mpt3sas: Refactor intentional wrap-around test
  mwifiex: pcie: Refactor intentional wrap-around test
  mm: Refactor intentional wrap-around test
  netfilter: Refactor intentional wrap-around test
  nios2: Refactor intentional wrap-around test
  fs/ntfs3: Refactor intentional wrap-around test
  ocfs2: Refactor intentional wrap-around test
  PCI: Refactor intentional wrap-around test
  perf tools: Refactor intentional wrap-around test
  remoteproc: Refactor intentional wrap-around test
  s390/mm: Refactor intentional wrap-around test
  scsi: sd_zbc: Refactor intentional wrap-around test
  sh: Refactor intentional wrap-around test
  ARC: dw2 unwind: Refactor intentional wrap-around test
  timekeeping: Refactor intentional wrap-around test
  udf: Refactor intentional wrap-around test
  virtio: Refactor intentional wrap-around test
  mm/vmalloc: Refactor intentional wrap-around test
  staging: vme_user: Refactor intentional wrap-around test
  xen-netback: Refactor intentional wrap-around test
  lib: zstd: Refactor intentional wrap-around test
  mqueue: Refactor intentional wrap-around test

 Documentation/process/deprecated.rst          | 36 ++++++++
 arch/arc/kernel/unwind.c                      |  7 +-
 arch/arm/nwfpe/softfloat.c                    |  2 +-
 arch/arm64/include/asm/atomic_lse.h           |  8 +-
 arch/arm64/include/asm/stacktrace/common.h    |  2 +-
 arch/arm64/kvm/vgic/vgic-kvm-device.c         |  6 +-
 arch/arm64/kvm/vgic/vgic-mmio-v3.c            |  2 +-
 arch/arm64/kvm/vgic/vgic-v2.c                 | 10 ++-
 arch/m68k/kernel/sys_m68k.c                   |  5 +-
 arch/nios2/kernel/sys_nios2.c                 |  2 +-
 arch/powerpc/platforms/powernv/opal-prd.c     |  2 +-
 arch/powerpc/xmon/xmon.c                      |  2 +-
 arch/s390/include/asm/stacktrace.h            |  6 +-
 arch/s390/kernel/machine_kexec_file.c         |  5 +-
 arch/s390/mm/gmap.c                           |  4 +-
 arch/s390/mm/vmem.c                           |  2 +-
 arch/sh/kernel/sys_sh.c                       |  2 +-
 arch/x86/include/asm/atomic.h                 |  2 +-
 arch/x86/kernel/cpu/sgx/ioctl.c               |  6 +-
 arch/x86/kvm/svm/sev.c                        |  5 +-
 crypto/adiantum.c                             |  2 +-
 drivers/acpi/custom_method.c                  |  2 +-
 drivers/char/agp/generic.c                    |  2 +-
 drivers/crypto/amcc/crypto4xx_alg.c           |  2 +-
 drivers/crypto/axis/artpec6_crypto.c          |  2 +-
 drivers/dma-buf/dma-buf.c                     |  7 +-
 drivers/fpga/dfl.c                            |  5 +-
 drivers/fsi/fsi-core.c                        |  6 +-
 drivers/gpu/drm/i915/i915_vma.c               |  2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c |  8 +-
 drivers/gpu/drm/vc4/vc4_validate.c            |  7 +-
 drivers/md/dm-switch.c                        |  2 +-
 drivers/md/dm-verity-target.c                 |  2 +-
 drivers/md/dm-writecache.c                    |  2 +-
 drivers/net/ethernet/sun/niu.c                |  5 +-
 drivers/net/wireless/ath/wil6210/wmi.c        |  2 +-
 drivers/net/wireless/marvell/mwifiex/pcie.c   |  6 +-
 drivers/net/xen-netback/hash.c                |  2 +-
 drivers/pci/pci.c                             |  2 +-
 drivers/remoteproc/pru_rproc.c                |  2 +-
 drivers/remoteproc/remoteproc_elf_loader.c    |  2 +-
 drivers/remoteproc/remoteproc_virtio.c        |  4 +-
 drivers/scsi/mpt3sas/mpt3sas_ctl.c            |  2 +-
 drivers/scsi/sd_zbc.c                         |  2 +-
 drivers/staging/vme_user/vme.c                |  2 +-
 drivers/vhost/vringh.c                        |  8 +-
 drivers/virtio/virtio_pci_modern_dev.c        |  4 +-
 fs/aio.c                                      |  2 +-
 fs/bcachefs/bkey.c                            |  4 +-
 fs/bcachefs/fs.c                              |  2 +-
 fs/bcachefs/quota.c                           |  2 +-
 fs/bcachefs/util.c                            |  2 +-
 fs/btrfs/extent_map.c                         |  6 +-
 fs/btrfs/extent_map.h                         |  6 +-
 fs/btrfs/ordered-data.c                       |  2 +-
 fs/ext4/block_validity.c                      |  2 +-
 fs/ext4/extents.c                             |  5 +-
 fs/ext4/resize.c                              |  2 +-
 fs/f2fs/file.c                                |  2 +-
 fs/f2fs/verity.c                              |  2 +-
 fs/hpfs/alloc.c                               |  2 +-
 fs/ntfs3/record.c                             |  4 +-
 fs/ocfs2/resize.c                             |  2 +-
 fs/read_write.c                               |  8 +-
 fs/remap_range.c                              |  2 +-
 fs/select.c                                   | 13 +--
 fs/smb/client/readdir.c                       |  5 +-
 fs/smb/client/smb2pdu.c                       |  4 +-
 fs/udf/balloc.c                               |  4 +-
 include/linux/compiler_types.h                | 29 +++++-
 include/linux/overflow.h                      | 76 +++++++++++++++-
 ipc/mqueue.c                                  |  2 +-
 ipc/shm.c                                     |  6 +-
 kernel/bpf/verifier.c                         | 12 +--
 kernel/time/timekeeping.c                     |  2 +-
 lib/Kconfig.ubsan                             | 27 ++++++
 lib/buildid.c                                 |  6 +-
 lib/iov_iter.c                                |  5 +-
 lib/overflow_kunit.c                          | 77 ++++++++++++++--
 lib/scatterlist.c                             |  2 +-
 lib/test_ubsan.c                              | 82 +++++++++++++++++
 lib/ubsan.c                                   | 89 +++++++++++++++++++
 lib/ubsan.h                                   |  5 ++
 lib/zstd/decompress/zstd_decompress.c         |  4 +-
 mm/kasan/generic.c                            |  2 +-
 mm/kasan/sw_tags.c                            |  2 +-
 mm/memory.c                                   |  4 +-
 mm/mmap.c                                     |  2 +-
 mm/mremap.c                                   |  2 +-
 mm/nommu.c                                    |  4 +-
 mm/usercopy.c                                 |  2 +-
 mm/util.c                                     |  2 +-
 mm/vmalloc.c                                  |  7 +-
 net/ipv4/route.c                              |  8 +-
 net/netfilter/xt_u32.c                        |  4 +-
 net/rds/info.c                                |  6 +-
 scripts/Makefile.ubsan                        |  3 +
 .../coccinelle/misc/add_would_overflow.cocci  | 70 +++++++++++++++
 tools/perf/util/dso.c                         |  2 +-
 tools/perf/util/unwind-libdw.c                |  2 +-
 tools/perf/util/unwind-libunwind-local.c      |  2 +-
 virt/kvm/coalesced_mmio.c                     |  6 +-
 102 files changed, 680 insertions(+), 167 deletions(-)
 create mode 100644 scripts/coccinelle/misc/add_would_overflow.cocci

-- 
2.34.1


^ permalink raw reply	[flat|nested] 163+ messages in thread

* [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-26 22:52   ` Justin Stitt
  2024-01-23  0:26 ` [PATCH 02/82] overflow: Introduce add_would_overflow() Kees Cook
                   ` (82 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Gustavo A. R. Silva, Andrew Morton, Nathan Chancellor,
	Nick Desaulniers, Bill Wendling, Justin Stitt, llvm,
	linux-kernel

The check_add_overflow() helper is mostly a wrapper around
__builtin_add_overflow(), but GCC and Clang refuse to operate on pointer
arguments that would normally be allowed if the addition were open-coded.

For example, we have many places where pointer overflow is tested:

	struct foo *ptr;
	...
	/* Check for overflow */
	if (ptr + count < ptr) ...

And in order to avoid running into the overflow sanitizers in the
future, we need to rewrite these "intended" overflow checks:

	if (check_add_overflow(ptr, count, &result)) ...

Frustratingly the argument type validation for __builtin_add_overflow()
is done before evaluating __builtin_choose_expr(), so for arguments to
be valid simultaneously for sizeof(*p) (when p may not be a pointer),
and __builtin_add_overflow(a, ...) (when a may be a pointer), we must
introduce wrappers that always produce a specific type (but they are
only used in the places where the bogus arguments will be ignored).

To test whether a variable is a pointer or not, introduce the __is_ptr()
helper, which uses __builtin_classify_type() to find arrays and pointers
(via the new __is_ptr_or_array() helper), and then decays arrays into
pointers (via the new __decay() helper), to distinguish pointers from
arrays.

Additionally update the unit tests to cover pointer addition.

Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Bill Wendling <morbo@google.com>
Cc: Justin Stitt <justinstitt@google.com>
Cc: llvm@lists.linux.dev
Cc: linux-hardening@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 include/linux/compiler_types.h | 10 +++++
 include/linux/overflow.h       | 44 ++++++++++++++++++-
 lib/overflow_kunit.c           | 77 ++++++++++++++++++++++++++++++----
 3 files changed, 121 insertions(+), 10 deletions(-)

diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 6f1ca49306d2..d27b58fddfaa 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -375,6 +375,16 @@ struct ftrace_likely_data {
 /* Are two types/vars the same type (ignoring qualifiers)? */
 #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
 
+/* Is variable addressable? */
+#define __is_ptr_or_array(p)	(__builtin_classify_type(p) == 5)
+
+/* Return an array decayed to a pointer. */
+#define __decay(p)		\
+	(&*__builtin_choose_expr(__is_ptr_or_array(p), p, NULL))
+
+/* Report if variable is a pointer type. */
+#define __is_ptr(p)		__same_type(p, __decay(p))
+
 /*
  * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
  *			       non-scalar types unchanged.
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 7b5cf4a5cd19..099f2e559aa8 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -51,6 +51,45 @@ static inline bool __must_check __must_check_overflow(bool overflow)
 	return unlikely(overflow);
 }
 
+/* Always produce an integral variable expression. */
+#define __filter_integral(x)		\
+	__builtin_choose_expr(!__is_ptr(x), (x), 0)
+
+/* Always produce a pointer value. */
+#define __filter_ptr(x)			\
+	__builtin_choose_expr(__is_ptr(x), (x), NULL)
+
+/* Always produce a pointer to an integral value. */
+#define __filter_ptrint(x)		\
+	__builtin_choose_expr(!__is_ptr(*(x)), x, &(int){ 0 })
+
+/**
+ * __check_ptr_add_overflow() - Calculate pointer addition with overflow checking
+ * @a: pointer addend
+ * @b: numeric addend
+ * @d: pointer to store sum
+ *
+ * Returns 0 on success.
+ *
+ * Do not use this function directly, use check_add_overflow() instead.
+ *
+ * *@d holds the results of the attempted addition, but is not considered
+ * "safe for use" on a non-zero return value, which indicates that the
+ * sum has overflowed or been truncated.
+ */
+#define __check_ptr_add_overflow(a, b, d)		\
+	({						\
+		typeof(a) __a = (a);			\
+		typeof(b) __b = (b);			\
+		size_t __bytes;				\
+		bool __overflow;			\
+							\
+		/* we want to perform the wrap-around, but retain the result */ \
+		__overflow = __builtin_mul_overflow(sizeof(*(__a)), __b, &__bytes); \
+		__builtin_add_overflow((unsigned long)(__a), __bytes, (unsigned long *)(d)) || \
+		__overflow;				\
+	})
+
 /**
  * check_add_overflow() - Calculate addition with overflow checking
  * @a: first addend
@@ -64,7 +103,10 @@ static inline bool __must_check __must_check_overflow(bool overflow)
  * sum has overflowed or been truncated.
  */
 #define check_add_overflow(a, b, d)	\
-	__must_check_overflow(__builtin_add_overflow(a, b, d))
+	__must_check_overflow(__builtin_choose_expr(__is_ptr(a),	\
+		__check_ptr_add_overflow(__filter_ptr(a), b, d),	\
+		__builtin_add_overflow(__filter_integral(a), b,		\
+				       __filter_ptrint(d))))
 
 /**
  * check_sub_overflow() - Calculate subtraction with overflow checking
diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c
index c527f6b75789..2d106e880956 100644
--- a/lib/overflow_kunit.c
+++ b/lib/overflow_kunit.c
@@ -45,13 +45,18 @@
 # define SKIP_64_ON_32(t)	do { } while (0)
 #endif
 
-#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t)			\
-	static const struct test_ ## t1 ## _ ## t2 ## __ ## t {	\
+#define DEFINE_TEST_ARRAY_NAMED_TYPED(n1, n2, n, t1, t2, t)	\
+	static const struct test_ ## n1 ## _ ## n2 ## __ ## n {	\
 		t1 a;						\
 		t2 b;						\
-		t sum, diff, prod;				\
+		t sum;						\
+		t diff;						\
+		t prod;						\
 		bool s_of, d_of, p_of;				\
-	} t1 ## _ ## t2 ## __ ## t ## _tests[]
+	} n1 ## _ ## n2 ## __ ## n ## _tests[]
+
+#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t)			\
+	DEFINE_TEST_ARRAY_NAMED_TYPED(t1, t2, t, t1, t2, t)
 
 #define DEFINE_TEST_ARRAY(t)	DEFINE_TEST_ARRAY_TYPED(t, t, t)
 
@@ -251,8 +256,10 @@ DEFINE_TEST_ARRAY(s64) = {
 };
 
 #define check_one_op(t, fmt, op, sym, a, b, r, of) do {			\
-	int _a_orig = a, _a_bump = a + 1;				\
-	int _b_orig = b, _b_bump = b + 1;				\
+	typeof(a + 0) _a_orig = a;					\
+	typeof(a + 0) _a_bump = a + 1;					\
+	typeof(b + 0) _b_orig = b;					\
+	typeof(b + 0) _b_bump = b + 1;					\
 	bool _of;							\
 	t _r;								\
 									\
@@ -260,13 +267,13 @@ DEFINE_TEST_ARRAY(s64) = {
 	KUNIT_EXPECT_EQ_MSG(test, _of, of,				\
 		"expected "fmt" "sym" "fmt" to%s overflow (type %s)\n",	\
 		a, b, of ? "" : " not", #t);				\
-	KUNIT_EXPECT_EQ_MSG(test, _r, r,				\
+	KUNIT_EXPECT_TRUE_MSG(test, _r == r,				\
 		"expected "fmt" "sym" "fmt" == "fmt", got "fmt" (type %s)\n", \
 		a, b, r, _r, #t);					\
 	/* Check for internal macro side-effects. */			\
 	_of = check_ ## op ## _overflow(_a_orig++, _b_orig++, &_r);	\
-	KUNIT_EXPECT_EQ_MSG(test, _a_orig, _a_bump, "Unexpected " #op " macro side-effect!\n"); \
-	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump, "Unexpected " #op " macro side-effect!\n"); \
+	KUNIT_EXPECT_TRUE_MSG(test, _a_orig == _a_bump, "Unexpected " #op " macro side-effect!\n"); \
+	KUNIT_EXPECT_TRUE_MSG(test, _b_orig == _b_bump, "Unexpected " #op " macro side-effect!\n"); \
 } while (0)
 
 #define DEFINE_TEST_FUNC_TYPED(n, t, fmt)				\
@@ -333,6 +340,55 @@ DEFINE_TEST_ARRAY_TYPED(int, int, u8) = {
 };
 DEFINE_TEST_FUNC_TYPED(int_int__u8, u8, "%d");
 
+#define DEFINE_TEST_PTR_FUNC_TYPED(n, t, fmt)				\
+static void do_ptr_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
+{									\
+	/* we're only doing single-direction sums, no product or division */ \
+	check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of);\
+}									\
+									\
+static void n ## _overflow_test(struct kunit *test) {			\
+	unsigned i;							\
+									\
+	for (i = 0; i < ARRAY_SIZE(n ## _tests); ++i)			\
+		do_ptr_test_ ## n(test, &n ## _tests[i]);		\
+	kunit_info(test, "%zu %s arithmetic tests finished\n",		\
+		ARRAY_SIZE(n ## _tests), #n);				\
+}
+
+DEFINE_TEST_ARRAY_NAMED_TYPED(void, int, void, void *, int, void *) = {
+	{NULL, 0, NULL, NULL, NULL, false, false, false},
+	{(void *)0x30, 0x10, (void *)0x40, NULL, NULL, false, false, false},
+	{(void *)ULONG_MAX, 0, (void *)ULONG_MAX, NULL, NULL, false, false, false},
+	{(void *)ULONG_MAX, 1, NULL, NULL, NULL, true, false, false},
+	{(void *)ULONG_MAX, INT_MAX, (void *)(INT_MAX - 1), NULL, NULL, true, false, false},
+};
+DEFINE_TEST_PTR_FUNC_TYPED(void_int__void, void *, "%lx");
+
+struct _sized {
+	int a;
+	char b;
+};
+
+DEFINE_TEST_ARRAY_NAMED_TYPED(sized, int, sized, struct _sized *, int, struct _sized *) = {
+	{NULL, 0, NULL, NULL, NULL, false, false, false},
+	{NULL, 1, (struct _sized *)(sizeof(struct _sized)), NULL, NULL, false, false, false},
+	{NULL, 0x10, (struct _sized *)(sizeof(struct _sized) * 0x10), NULL, NULL, false, false, false},
+	{(void *)(ULONG_MAX - sizeof(struct _sized)), 1, (struct _sized *)ULONG_MAX, NULL, NULL, false, false, false},
+	{(void *)(ULONG_MAX - sizeof(struct _sized) + 1), 1, NULL, NULL, NULL, true, false, false},
+	{(void *)(ULONG_MAX - sizeof(struct _sized) + 1), 2, (struct _sized *)(sizeof(struct _sized)), NULL, NULL, true, false, false},
+	{(void *)(ULONG_MAX - sizeof(struct _sized) + 1), 3, (struct _sized *)(sizeof(struct _sized) * 2), NULL, NULL, true, false, false},
+};
+DEFINE_TEST_PTR_FUNC_TYPED(sized_int__sized, struct _sized *, "%lx");
+
+DEFINE_TEST_ARRAY_NAMED_TYPED(sized, size_t, sized, struct _sized *, size_t, struct _sized *) = {
+	{NULL, 0, NULL, NULL, NULL, false, false, false},
+	{NULL, 1, (struct _sized *)(sizeof(struct _sized)), NULL, NULL, false, false, false},
+	{NULL, 0x10, (struct _sized *)(sizeof(struct _sized) * 0x10), NULL, NULL, false, false, false},
+	{NULL, SIZE_MAX - 10, (struct _sized *)18446744073709551528UL, NULL, NULL, true, false, false},
+};
+DEFINE_TEST_PTR_FUNC_TYPED(sized_size_t__sized, struct _sized *, "%zu");
+
 /* Args are: value, shift, type, expected result, overflow expected */
 #define TEST_ONE_SHIFT(a, s, t, expect, of)	do {			\
 	typeof(a) __a = (a);						\
@@ -1122,6 +1178,9 @@ static struct kunit_case overflow_test_cases[] = {
 	KUNIT_CASE(s32_s32__s32_overflow_test),
 	KUNIT_CASE(u64_u64__u64_overflow_test),
 	KUNIT_CASE(s64_s64__s64_overflow_test),
+	KUNIT_CASE(void_int__void_overflow_test),
+	KUNIT_CASE(sized_int__sized_overflow_test),
+	KUNIT_CASE(sized_size_t__sized_overflow_test),
 	KUNIT_CASE(u32_u32__int_overflow_test),
 	KUNIT_CASE(u32_u32__u8_overflow_test),
 	KUNIT_CASE(u8_u8__int_overflow_test),
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 02/82] overflow: Introduce add_would_overflow()
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
  2024-01-23  0:26 ` [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  8:03   ` Rasmus Villemoes
  2024-01-23  0:26 ` [PATCH 03/82] overflow: Introduce add_wrap() Kees Cook
                   ` (81 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

For instances where only the overflow needs to be checked (and the sum
isn't used), provide the new helper add_would_overflow(), which is
a wrapper for check_add_overflow().

Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-hardening@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 include/linux/overflow.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 099f2e559aa8..ac088f73e0fd 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -108,6 +108,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
 		__builtin_add_overflow(__filter_integral(a), b,		\
 				       __filter_ptrint(d))))
 
+/**
+ * add_would_overflow() - Check if an addition would overflow
+ * @a: first addend
+ * @b: second addend
+ *
+ * Returns true if the sum would overflow.
+ *
+ * To keep a copy of the sum when the addition doesn't overflow, use
+ * check_add_overflow() instead.
+ */
+#define add_would_overflow(a, b)			\
+	__must_check_overflow(({			\
+		size_t __result;			\
+		check_add_overflow(a, b, &__result);\
+	}))
+
 /**
  * check_sub_overflow() - Calculate subtraction with overflow checking
  * @a: minuend; value to subtract from
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 03/82] overflow: Introduce add_wrap()
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
  2024-01-23  0:26 ` [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition Kees Cook
  2024-01-23  0:26 ` [PATCH 02/82] overflow: Introduce add_would_overflow() Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  8:14   ` Rasmus Villemoes
  2024-01-23  9:22   ` Mark Rutland
  2024-01-23  0:26 ` [PATCH 04/82] docs: deprecated.rst: deprecate open-coded arithmetic wrap-around Kees Cook
                   ` (80 subsequent siblings)
  83 siblings, 2 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

Provide a helper that will perform wrapping addition without tripping
the arithmetic wrap-around sanitizers.

Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: linux-hardening@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 include/linux/overflow.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index ac088f73e0fd..30779905a77a 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -124,6 +124,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
 		check_add_overflow(a, b, &__result);\
 	}))
 
+/**
+ * add_wrap() - Intentionally perform a wrapping addition
+ * @a: first addend
+ * @b: second addend
+ *
+ * Return the potentially wrapped-around addition without
+ * tripping any overflow sanitizers that may be enabled.
+ */
+#define add_wrap(a, b)					\
+	({						\
+		typeof(a) __sum;			\
+		if (check_add_overflow(a, b, &__sum))	\
+			/* do nothing */;		\
+		__sum;					\
+	})
+
 /**
  * check_sub_overflow() - Calculate subtraction with overflow checking
  * @a: minuend; value to subtract from
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 04/82] docs: deprecated.rst: deprecate open-coded arithmetic wrap-around
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (2 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 03/82] overflow: Introduce add_wrap() Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 05/82] cocci: Refactor " Kees Cook
                   ` (79 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Jonathan Corbet, Gustavo A. R. Silva, Justin Stitt,
	workflows, linux-doc, Bill Wendling, linux-kernel

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. Document this goal and provide an example for
the most common code pattern, checking for simple overflow:

	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: Jonathan Corbet <corbet@lwn.net>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Justin Stitt <justinstitt@google.com>
Cc: workflows@vger.kernel.org
Cc: linux-doc@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 Documentation/process/deprecated.rst | 32 ++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index 1f7f3e6c9cda..270f3af13b86 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -109,6 +109,38 @@ For more details, also see array3_size() and flex_array_size(),
 as well as the related check_mul_overflow(), check_add_overflow(),
 check_sub_overflow(), and check_shl_overflow() family of functions.
 
+open-coded intentional arithmetic wrap-around
+---------------------------------------------
+Depending on arithmetic wrap-around without annotations means the
+kernel cannot distinguish between intentional wrap-around and accidental
+wrap-around (when using things like the overflow sanitizers).
+
+For example, where an addition is intended to wrap around::
+
+	magic = counter + rotation;
+
+please use the add_wrap() helper::
+
+	magic = add_wrap(counter, rotation);
+
+Another common code pattern in the kernel open coded testing for overflow
+by performing an overflow and looking for wrap-around::
+
+	if (var + offset < var) ...
+
+Instead, use either check_add_overflow() (when you want to use the
+resulting sum when it doesn't overflow) or add_would_overflow()::
+
+	if (add_would_overflow(var, offset)) ...
+
+In rare cases where helpers aren't available (e.g. in early boot code,
+etc) but overflow instrumentation still needs to be avoided, it can be
+replaced with a type max subtraction test instead::
+
+	int var;
+	...
+	if (INT_MAX - var < offset) ...
+
 simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
 ----------------------------------------------------------------------
 The simple_strtol(), simple_strtoll(),
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 05/82] cocci: Refactor open-coded arithmetic wrap-around
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (3 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 04/82] docs: deprecated.rst: deprecate open-coded arithmetic wrap-around Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers Kees Cook
                   ` (78 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Julia Lawall, Nicolas Palix, Gustavo A. R. Silva,
	Justin Stitt, cocci, Bill Wendling, linux-kernel

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.Lawall@inria.fr>
Cc: Nicolas Palix <nicolas.palix@imag.fr>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Justin Stitt <justinstitt@google.com>
Cc: cocci@inria.fr
Signed-off-by: Kees Cook <keescook@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


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (4 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 05/82] cocci: Refactor " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  2:24   ` Miguel Ojeda
  2024-01-23  0:26 ` [PATCH 07/82] overflow: Introduce CONFIG_UBSAN_POINTER_WRAP Kees Cook
                   ` (77 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Justin Stitt, Miguel Ojeda, Nathan Chancellor,
	Nick Desaulniers, Peter Zijlstra, Marco Elver, Hao Luo,
	Przemek Kitszel, Gustavo A. R. Silva, Bill Wendling,
	linux-kernel

Effectively revert commit 6aaa31aeb9cf ("ubsan: remove overflow
checks"), to allow the kernel to be built with the "*-overflow"
sanitizers again. This gives developers a chance to experiment[1][2][3]
with the instrumentation again, while dealing with the impact of
-fno-strict-oveflow.

Notably, the naming of the options is adjusted to use the name "WRAP"
instead of "OVERFLOW". In the strictest sense, arithmetic "overflow"
happens when a result exceeds the storage of the type, and is considered
by the C standard and compilers to be undefined behavior for signed
and pointer types (without -fno-strict-overflow). Unsigned arithmetic
overflow is defined as always wrapping around.

Because the kernel is built with -fno-strict-overflow, signed and pointer
arithmetic is defined to always wrap around instead of "overflowing"
(which would either be elided due to being undefined behavior or would
wrap around, which led to very weird bugs in the kernel).

So, the config options are added back as CONFIG_UBSAN_SIGNED_WRAP and
CONFIG_UBSAN_UNSIGNED_WRAP. Since the kernel has several places that
explicitly depend on wrap-around behavior (e.g. counters, atomics, etc),
also introduce the __signed_wrap and __unsigned_wrap function attributes
for annotating functions where wrapping is expected and should not
be caught. This will allow us to distinguish in the kernel between
intentional and unintentional cases of arithmetic wrap-around.

Additionally keep these disabled under CONFIG_COMPILE_TEST for now.

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: Justin Stitt <justinstitt@google.com>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Marco Elver <elver@google.com>
Cc: Hao Luo <haoluo@google.com>
Cc: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 Documentation/process/deprecated.rst |  4 ++
 include/linux/compiler_types.h       | 14 +++++-
 lib/Kconfig.ubsan                    | 19 ++++++++
 lib/test_ubsan.c                     | 49 ++++++++++++++++++++
 lib/ubsan.c                          | 68 ++++++++++++++++++++++++++++
 lib/ubsan.h                          |  4 ++
 scripts/Makefile.ubsan               |  2 +
 7 files changed, 159 insertions(+), 1 deletion(-)

diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index 270f3af13b86..aebd7c6cd2fc 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -141,6 +141,10 @@ replaced with a type max subtraction test instead::
 	...
 	if (INT_MAX - var < offset) ...
 
+For inline helpers that are performing wrapping arithmetic, the entire
+function can be annotated as intentionally wrapping by adding the
+`__signed_wrap` or `__unsigned_wrap` function attribute.
+
 simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
 ----------------------------------------------------------------------
 The simple_strtol(), simple_strtoll(),
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index d27b58fddfaa..d24f43fc79c6 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -282,11 +282,23 @@ struct ftrace_likely_data {
 #define __no_sanitize_or_inline __always_inline
 #endif
 
+/* Allow wrapping arithmetic within an annotated function. */
+#ifdef CONFIG_UBSAN_SIGNED_WRAP
+# define __signed_wrap __attribute__((no_sanitize("signed-integer-overflow")))
+#else
+# define __signed_wrap
+#endif
+#ifdef CONFIG_UBSAN_UNSIGNED_WRAP
+# define __unsigned_wrap __attribute__((no_sanitize("unsigned-integer-overflow")))
+#else
+# define __unsigned_wrap
+#endif
+
 /* Section for code which can't be instrumented at all */
 #define __noinstr_section(section)					\
 	noinline notrace __attribute((__section__(section)))		\
 	__no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage \
-	__no_sanitize_memory
+	__no_sanitize_memory __signed_wrap __unsigned_wrap
 
 #define noinstr __noinstr_section(".noinstr.text")
 
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index 59e21bfec188..a7003e5bd2a1 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -116,6 +116,25 @@ config UBSAN_UNREACHABLE
 	  This option enables -fsanitize=unreachable which checks for control
 	  flow reaching an expected-to-be-unreachable position.
 
+config UBSAN_SIGNED_WRAP
+	bool "Perform checking for signed arithmetic wrap-around"
+	default UBSAN
+	depends on !COMPILE_TEST
+	depends on $(cc-option,-fsanitize=signed-integer-overflow)
+	help
+	  This option enables -fsanitize=signed-integer-overflow which checks
+	  for wrap-around of any arithmetic operations with signed integers.
+
+config UBSAN_UNSIGNED_WRAP
+	bool "Perform checking for unsigned arithmetic wrap-around"
+	depends on $(cc-option,-fsanitize=unsigned-integer-overflow)
+	depends on !X86_32 # avoid excessive stack usage on x86-32/clang
+	depends on !COMPILE_TEST
+	help
+	  This option enables -fsanitize=unsigned-integer-overflow which checks
+	  for wrap-around of any arithmetic operations with unsigned integers. This
+	  currently causes x86 to fail to boot.
+
 config UBSAN_BOOL
 	bool "Perform checking for non-boolean values used as boolean"
 	default UBSAN
diff --git a/lib/test_ubsan.c b/lib/test_ubsan.c
index 2062be1f2e80..84d8092d6c32 100644
--- a/lib/test_ubsan.c
+++ b/lib/test_ubsan.c
@@ -11,6 +11,51 @@ typedef void(*test_ubsan_fp)(void);
 			#config, IS_ENABLED(config) ? "y" : "n");	\
 	} while (0)
 
+static void test_ubsan_add_overflow(void)
+{
+	volatile int val = INT_MAX;
+	volatile unsigned int uval = UINT_MAX;
+
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
+	val += 2;
+
+	UBSAN_TEST(CONFIG_UBSAN_UNSIGNED_WRAP);
+	uval += 2;
+}
+
+static void test_ubsan_sub_overflow(void)
+{
+	volatile int val = INT_MIN;
+	volatile unsigned int uval = 0;
+	volatile int val2 = 2;
+
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
+	val -= val2;
+
+	UBSAN_TEST(CONFIG_UBSAN_UNSIGNED_WRAP);
+	uval -= val2;
+}
+
+static void test_ubsan_mul_overflow(void)
+{
+	volatile int val = INT_MAX / 2;
+	volatile unsigned int uval = UINT_MAX / 2;
+
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
+	val *= 3;
+
+	UBSAN_TEST(CONFIG_UBSAN_UNSIGNED_WRAP);
+	uval *= 3;
+}
+
+static void test_ubsan_negate_overflow(void)
+{
+	volatile int val = INT_MIN;
+
+	UBSAN_TEST(CONFIG_UBSAN_SIGNED_WRAP);
+	val = -val;
+}
+
 static void test_ubsan_divrem_overflow(void)
 {
 	volatile int val = 16;
@@ -90,6 +135,10 @@ static void test_ubsan_misaligned_access(void)
 }
 
 static const test_ubsan_fp test_ubsan_array[] = {
+	test_ubsan_add_overflow,
+	test_ubsan_sub_overflow,
+	test_ubsan_mul_overflow,
+	test_ubsan_negate_overflow,
 	test_ubsan_shift_out_of_bounds,
 	test_ubsan_out_of_bounds,
 	test_ubsan_load_invalid_value,
diff --git a/lib/ubsan.c b/lib/ubsan.c
index df4f8d1354bb..5fc107f61934 100644
--- a/lib/ubsan.c
+++ b/lib/ubsan.c
@@ -222,6 +222,74 @@ static void ubsan_epilogue(void)
 	check_panic_on_warn("UBSAN");
 }
 
+static void handle_overflow(struct overflow_data *data, void *lhs,
+			void *rhs, char op)
+{
+
+	struct type_descriptor *type = data->type;
+	char lhs_val_str[VALUE_LENGTH];
+	char rhs_val_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, type_is_signed(type) ?
+			"signed-integer-overflow" :
+			"unsigned-integer-overflow");
+
+	val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
+	val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
+	pr_err("%s %c %s cannot be represented in type %s\n",
+		lhs_val_str,
+		op,
+		rhs_val_str,
+		type->type_name);
+
+	ubsan_epilogue();
+}
+
+void __ubsan_handle_add_overflow(void *data,
+				void *lhs, void *rhs)
+{
+
+	handle_overflow(data, lhs, rhs, '+');
+}
+EXPORT_SYMBOL(__ubsan_handle_add_overflow);
+
+void __ubsan_handle_sub_overflow(void *data,
+				void *lhs, void *rhs)
+{
+	handle_overflow(data, lhs, rhs, '-');
+}
+EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
+
+void __ubsan_handle_mul_overflow(void *data,
+				void *lhs, void *rhs)
+{
+	handle_overflow(data, lhs, rhs, '*');
+}
+EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
+
+void __ubsan_handle_negate_overflow(void *_data, void *old_val)
+{
+	struct overflow_data *data = _data;
+	char old_val_str[VALUE_LENGTH];
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, "negation-overflow");
+
+	val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
+
+	pr_err("negation of %s cannot be represented in type %s:\n",
+		old_val_str, data->type->type_name);
+
+	ubsan_epilogue();
+}
+EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
+
+
 void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
 {
 	struct overflow_data *data = _data;
diff --git a/lib/ubsan.h b/lib/ubsan.h
index 5d99ab81913b..0abbbac8700d 100644
--- a/lib/ubsan.h
+++ b/lib/ubsan.h
@@ -124,6 +124,10 @@ typedef s64 s_max;
 typedef u64 u_max;
 #endif
 
+void __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs);
+void __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs);
+void __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs);
+void __ubsan_handle_negate_overflow(void *_data, void *old_val);
 void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs);
 void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr);
 void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr);
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index 4749865c1b2c..de4fc0ae448a 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -8,6 +8,8 @@ ubsan-cflags-$(CONFIG_UBSAN_LOCAL_BOUNDS)	+= -fsanitize=local-bounds
 ubsan-cflags-$(CONFIG_UBSAN_SHIFT)		+= -fsanitize=shift
 ubsan-cflags-$(CONFIG_UBSAN_DIV_ZERO)		+= -fsanitize=integer-divide-by-zero
 ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE)	+= -fsanitize=unreachable
+ubsan-cflags-$(CONFIG_UBSAN_SIGNED_WRAP)	+= -fsanitize=signed-integer-overflow
+ubsan-cflags-$(CONFIG_UBSAN_UNSIGNED_WRAP)	+= -fsanitize=unsigned-integer-overflow
 ubsan-cflags-$(CONFIG_UBSAN_BOOL)		+= -fsanitize=bool
 ubsan-cflags-$(CONFIG_UBSAN_ENUM)		+= -fsanitize=enum
 ubsan-cflags-$(CONFIG_UBSAN_TRAP)		+= -fsanitize-undefined-trap-on-error
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 07/82] overflow: Introduce CONFIG_UBSAN_POINTER_WRAP
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (5 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 08/82] iov_iter: Avoid wrap-around instrumentation in copy_compat_iovec_from_user Kees Cook
                   ` (76 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Andrew Morton, Masahiro Yamada, Nathan Chancellor,
	Nicolas Schier, linux-kbuild, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

Gain coverage for pointer wrap-around checking. Adds support for
-fsanitize=pointer-overflow, and introduces the __pointer_wrap function
attribute to match the signed and unsigned attributes. Also like the
others, it is currently disabled under CONFIG_COMPILE_TEST.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nicolas Schier <nicolas@fjasle.eu>
Cc: linux-kbuild@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 Documentation/process/deprecated.rst |  2 +-
 include/linux/compiler_types.h       |  7 +++++-
 lib/Kconfig.ubsan                    |  8 +++++++
 lib/test_ubsan.c                     | 33 ++++++++++++++++++++++++++++
 lib/ubsan.c                          | 21 ++++++++++++++++++
 lib/ubsan.h                          |  1 +
 scripts/Makefile.ubsan               |  1 +
 7 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index aebd7c6cd2fc..15e77cbd4259 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -143,7 +143,7 @@ replaced with a type max subtraction test instead::
 
 For inline helpers that are performing wrapping arithmetic, the entire
 function can be annotated as intentionally wrapping by adding the
-`__signed_wrap` or `__unsigned_wrap` function attribute.
+`__signed_wrap`, `__unsigned_wrap`, or `__pointer_wrap` function attribute.
 
 simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
 ----------------------------------------------------------------------
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index d24f43fc79c6..84cfd9d55453 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -293,12 +293,17 @@ struct ftrace_likely_data {
 #else
 # define __unsigned_wrap
 #endif
+#ifdef CONFIG_UBSAN_POINTER_WRAP
+# define __pointer_wrap __attribute__((no_sanitize("pointer-overflow")))
+#else
+# define __pointer_wrap
+#endif
 
 /* Section for code which can't be instrumented at all */
 #define __noinstr_section(section)					\
 	noinline notrace __attribute((__section__(section)))		\
 	__no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage \
-	__no_sanitize_memory __signed_wrap __unsigned_wrap
+	__no_sanitize_memory __signed_wrap __unsigned_wrap __pointer_wrap
 
 #define noinstr __noinstr_section(".noinstr.text")
 
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan
index a7003e5bd2a1..04222a6d7fd9 100644
--- a/lib/Kconfig.ubsan
+++ b/lib/Kconfig.ubsan
@@ -135,6 +135,14 @@ config UBSAN_UNSIGNED_WRAP
 	  for wrap-around of any arithmetic operations with unsigned integers. This
 	  currently causes x86 to fail to boot.
 
+config UBSAN_POINTER_WRAP
+	bool "Perform checking for pointer arithmetic wrap-around"
+	depends on !COMPILE_TEST
+	depends on $(cc-option,-fsanitize=pointer-overflow)
+	help
+	  This option enables -fsanitize=pointer-overflow which checks
+	  for wrap-around of any arithmetic operations with pointers.
+
 config UBSAN_BOOL
 	bool "Perform checking for non-boolean values used as boolean"
 	default UBSAN
diff --git a/lib/test_ubsan.c b/lib/test_ubsan.c
index 84d8092d6c32..1cc049b3ef34 100644
--- a/lib/test_ubsan.c
+++ b/lib/test_ubsan.c
@@ -56,6 +56,36 @@ static void test_ubsan_negate_overflow(void)
 	val = -val;
 }
 
+static void test_ubsan_pointer_overflow_add(void)
+{
+	volatile void *top = (void *)ULONG_MAX;
+
+	UBSAN_TEST(CONFIG_UBSAN_POINTER_WRAP);
+	top += 2;
+}
+
+static void test_ubsan_pointer_overflow_sub(void)
+{
+	volatile void *bottom = (void *)1;
+
+	UBSAN_TEST(CONFIG_UBSAN_POINTER_WRAP);
+	bottom -= 3;
+}
+
+struct ptr_wrap {
+	int a;
+	int b;
+};
+
+static void test_ubsan_pointer_overflow_mul(void)
+{
+	volatile struct ptr_wrap *half = (void *)(ULONG_MAX - 128);
+	volatile int bump = 128;
+
+	UBSAN_TEST(CONFIG_UBSAN_POINTER_WRAP);
+	half += bump;
+}
+
 static void test_ubsan_divrem_overflow(void)
 {
 	volatile int val = 16;
@@ -139,6 +169,9 @@ static const test_ubsan_fp test_ubsan_array[] = {
 	test_ubsan_sub_overflow,
 	test_ubsan_mul_overflow,
 	test_ubsan_negate_overflow,
+	test_ubsan_pointer_overflow_add,
+	test_ubsan_pointer_overflow_sub,
+	test_ubsan_pointer_overflow_mul,
 	test_ubsan_shift_out_of_bounds,
 	test_ubsan_out_of_bounds,
 	test_ubsan_load_invalid_value,
diff --git a/lib/ubsan.c b/lib/ubsan.c
index 5fc107f61934..d49580ff6aea 100644
--- a/lib/ubsan.c
+++ b/lib/ubsan.c
@@ -289,6 +289,27 @@ void __ubsan_handle_negate_overflow(void *_data, void *old_val)
 }
 EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
 
+void __ubsan_handle_pointer_overflow(void *_data, void *lhs, void *rhs)
+{
+	struct overflow_data *data = _data;
+	unsigned long before = (unsigned long)lhs;
+	unsigned long after  = (unsigned long)rhs;
+
+	if (suppress_report(&data->location))
+		return;
+
+	ubsan_prologue(&data->location, "pointer-overflow");
+
+	if (after == 0)
+		pr_err("overflow wrapped to NULL\n");
+	else if (after < before)
+		pr_err("overflow wrap-around\n");
+	else
+		pr_err("underflow wrap-around\n");
+
+	ubsan_epilogue();
+}
+EXPORT_SYMBOL(__ubsan_handle_pointer_overflow);
 
 void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
 {
diff --git a/lib/ubsan.h b/lib/ubsan.h
index 0abbbac8700d..5dd27923b78b 100644
--- a/lib/ubsan.h
+++ b/lib/ubsan.h
@@ -128,6 +128,7 @@ void __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs);
 void __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs);
 void __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs);
 void __ubsan_handle_negate_overflow(void *_data, void *old_val);
+void __ubsan_handle_pointer_overflow(void *_data, void *lhs, void *rhs);
 void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs);
 void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr);
 void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr);
diff --git a/scripts/Makefile.ubsan b/scripts/Makefile.ubsan
index de4fc0ae448a..37e8c31dc655 100644
--- a/scripts/Makefile.ubsan
+++ b/scripts/Makefile.ubsan
@@ -10,6 +10,7 @@ ubsan-cflags-$(CONFIG_UBSAN_DIV_ZERO)		+= -fsanitize=integer-divide-by-zero
 ubsan-cflags-$(CONFIG_UBSAN_UNREACHABLE)	+= -fsanitize=unreachable
 ubsan-cflags-$(CONFIG_UBSAN_SIGNED_WRAP)	+= -fsanitize=signed-integer-overflow
 ubsan-cflags-$(CONFIG_UBSAN_UNSIGNED_WRAP)	+= -fsanitize=unsigned-integer-overflow
+ubsan-cflags-$(CONFIG_UBSAN_POINTER_WRAP)	+= -fsanitize=pointer-overflow
 ubsan-cflags-$(CONFIG_UBSAN_BOOL)		+= -fsanitize=bool
 ubsan-cflags-$(CONFIG_UBSAN_ENUM)		+= -fsanitize=enum
 ubsan-cflags-$(CONFIG_UBSAN_TRAP)		+= -fsanitize-undefined-trap-on-error
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 08/82] iov_iter: Avoid wrap-around instrumentation in copy_compat_iovec_from_user
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (6 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 07/82] overflow: Introduce CONFIG_UBSAN_POINTER_WRAP Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 09/82] select: Avoid wrap-around instrumentation in do_sys_poll() Kees Cook
                   ` (75 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Alexander Viro, Andrew Morton, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

The loop counter "i" in copy_compat_iovec_from_user() is an int, but
because the nr_segs argument is unsigned long, the signed overflow
sanitizer got worried "i" could wrap around. Instead of making "i" an
unsigned long (which may enlarge the type size), switch both nr_segs
and i to u32. There is no truncation with nr_segs since its is never
larger than UIO_MAXIOV anyway. This keeps sanitizer instrumentation[1]
out of a UACCESS path:

vmlinux.o: warning: objtool: copy_compat_iovec_from_user+0xa9: call to __ubsan_handle_add_overflow() with UACCESS enabled

Link: https://github.com/KSPP/linux/issues/26 [1]
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/iov_iter.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index e0aa6b440ca5..d797a43dca91 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1166,11 +1166,12 @@ const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags)
 EXPORT_SYMBOL(dup_iter);
 
 static __noclone int copy_compat_iovec_from_user(struct iovec *iov,
-		const struct iovec __user *uvec, unsigned long nr_segs)
+		const struct iovec __user *uvec, u32 nr_segs)
 {
 	const struct compat_iovec __user *uiov =
 		(const struct compat_iovec __user *)uvec;
-	int ret = -EFAULT, i;
+	int ret = -EFAULT;
+	u32 i;
 
 	if (!user_access_begin(uiov, nr_segs * sizeof(*uiov)))
 		return -EFAULT;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 09/82] select: Avoid wrap-around instrumentation in do_sys_poll()
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (7 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 08/82] iov_iter: Avoid wrap-around instrumentation in copy_compat_iovec_from_user Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23 18:00   ` Jan Kara
  2024-01-23  0:26 ` [PATCH 10/82] locking/atomic/x86: Silence intentional wrapping addition Kees Cook
                   ` (74 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara,
	linux-fsdevel, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

The mix of int, unsigned int, and unsigned long used by struct
poll_list::len, todo, len, and j meant that the signed overflow
sanitizer got worried it needed to instrument several places where
arithmetic happens between these variables. Since all of the variables
are always positive and bounded by unsigned int, use a single type in
all places. Additionally expand the zero-test into an explicit range
check before updating "todo".

This keeps sanitizer instrumentation[1] out of a UACCESS path:

vmlinux.o: warning: objtool: do_sys_poll+0x285: call to __ubsan_handle_sub_overflow() with UACCESS enabled

Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/select.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/select.c b/fs/select.c
index 0ee55af1a55c..11a3b1312abe 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -839,7 +839,7 @@ SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
 
 struct poll_list {
 	struct poll_list *next;
-	int len;
+	unsigned int len;
 	struct pollfd entries[];
 };
 
@@ -975,14 +975,15 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
 		struct timespec64 *end_time)
 {
 	struct poll_wqueues table;
-	int err = -EFAULT, fdcount, len;
+	int err = -EFAULT, fdcount;
 	/* Allocate small arguments on the stack to save memory and be
 	   faster - use long to make sure the buffer is aligned properly
 	   on 64 bit archs to avoid unaligned access */
 	long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
 	struct poll_list *const head = (struct poll_list *)stack_pps;
  	struct poll_list *walk = head;
- 	unsigned long todo = nfds;
+	unsigned int todo = nfds;
+	unsigned int len;
 
 	if (nfds > rlimit(RLIMIT_NOFILE))
 		return -EINVAL;
@@ -998,9 +999,9 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
 					sizeof(struct pollfd) * walk->len))
 			goto out_fds;
 
-		todo -= walk->len;
-		if (!todo)
+		if (walk->len >= todo)
 			break;
+		todo -= walk->len;
 
 		len = min(todo, POLLFD_PER_PAGE);
 		walk = walk->next = kmalloc(struct_size(walk, entries, len),
@@ -1020,7 +1021,7 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
 
 	for (walk = head; walk; walk = walk->next) {
 		struct pollfd *fds = walk->entries;
-		int j;
+		unsigned int j;
 
 		for (j = walk->len; j; fds++, ufds++, j--)
 			unsafe_put_user(fds->revents, &ufds->revents, Efault);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 10/82] locking/atomic/x86: Silence intentional wrapping addition
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (8 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 09/82] select: Avoid wrap-around instrumentation in do_sys_poll() Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  9:27   ` Mark Rutland
  2024-01-23  0:26 ` [PATCH 11/82] arm64: atomics: lse: " Kees Cook
                   ` (73 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

Annotate atomic_add_return() to avoid signed overflow instrumentation.
It is expected to wrap around.

Cc: Will Deacon <will@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/x86/include/asm/atomic.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index 55a55ec04350..4120cdd87da8 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -80,7 +80,7 @@ static __always_inline bool arch_atomic_add_negative(int i, atomic_t *v)
 }
 #define arch_atomic_add_negative arch_atomic_add_negative
 
-static __always_inline int arch_atomic_add_return(int i, atomic_t *v)
+static __always_inline __signed_wrap int arch_atomic_add_return(int i, atomic_t *v)
 {
 	return i + xadd(&v->counter, i);
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 11/82] arm64: atomics: lse: Silence intentional wrapping addition
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (9 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 10/82] locking/atomic/x86: Silence intentional wrapping addition Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  9:53   ` Mark Rutland
  2024-01-23  0:26 ` [PATCH 12/82] ipv4: " Kees Cook
                   ` (72 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Will Deacon, Peter Zijlstra, Boqun Feng, Mark Rutland,
	Catalin Marinas, linux-arm-kernel, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

Annotate atomic_add_return() and atomic_sub_return() to avoid signed
overflow instrumentation. They are expected to wrap around.

Cc: Will Deacon <will@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm64/include/asm/atomic_lse.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index 87f568a94e55..30572458d702 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -79,13 +79,13 @@ ATOMIC_FETCH_OP_SUB(        )
 #undef ATOMIC_FETCH_OP_SUB
 
 #define ATOMIC_OP_ADD_SUB_RETURN(name)					\
-static __always_inline int						\
+static __always_inline __signed_wrap int				\
 __lse_atomic_add_return##name(int i, atomic_t *v)			\
 {									\
 	return __lse_atomic_fetch_add##name(i, v) + i;			\
 }									\
 									\
-static __always_inline int						\
+static __always_inline __signed_wrap int				\
 __lse_atomic_sub_return##name(int i, atomic_t *v)			\
 {									\
 	return __lse_atomic_fetch_sub(i, v) - i;			\
@@ -186,13 +186,13 @@ ATOMIC64_FETCH_OP_SUB(        )
 #undef ATOMIC64_FETCH_OP_SUB
 
 #define ATOMIC64_OP_ADD_SUB_RETURN(name)				\
-static __always_inline long						\
+static __always_inline __signed_wrap long				\
 __lse_atomic64_add_return##name(s64 i, atomic64_t *v)			\
 {									\
 	return __lse_atomic64_fetch_add##name(i, v) + i;		\
 }									\
 									\
-static __always_inline long						\
+static __always_inline __signed_wrap long				\
 __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)			\
 {									\
 	return __lse_atomic64_fetch_sub##name(i, v) - i;		\
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 12/82] ipv4: Silence intentional wrapping addition
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (10 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 11/82] arm64: atomics: lse: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 13/82] btrfs: Refactor intentional wrap-around calculation Kees Cook
                   ` (71 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Jakub Kicinski, David S. Miller, David Ahern,
	Eric Dumazet, Paolo Abeni, netdev, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

The overflow sanitizer quickly noticed what appears to have been an old
sore spot involving intended wrap around:

[   22.192362] ------------[ cut here ]------------
[   22.193329] UBSAN: signed-integer-overflow in ../arch/x86/include/asm/atomic.h:85:11
[   22.194844] 1469769800 + 1671667352 cannot be represented in type 'int'
[   22.195975] CPU: 2 PID: 2260 Comm: nmbd Not tainted 6.7.0 #1
[   22.196927] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015
[   22.198231] Call Trace:
[   22.198641]  <TASK>
[   22.198641]  dump_stack_lvl+0x64/0x80
[   22.199533]  handle_overflow+0x152/0x1a0
[   22.200382]  __ip_select_ident+0xe3/0x100

Explicitly perform a wrapping addition to solve for the needed
-fno-strict-overflow behavior but still allow the sanitizers to operate
correctly.

To see the (unchanged) assembly results more clearly, see:
https://godbolt.org/z/EhYhz6zTT

Cc: Jakub Kicinski <kuba@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: David Ahern <dsahern@kernel.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 net/ipv4/route.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 16615d107cf0..c52e85b06fe7 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -473,11 +473,11 @@ static u32 ip_idents_reserve(u32 hash, int segs)
 	if (old != now && cmpxchg(p_tstamp, old, now) == old)
 		delta = get_random_u32_below(now - old);
 
-	/* If UBSAN reports an error there, please make sure your compiler
-	 * supports -fno-strict-overflow before reporting it that was a bug
-	 * in UBSAN, and it has been fixed in GCC-8.
+	/* If UBSAN reports an error there, please make sure your arch's
+	 * atomic_add_return() implementation has been annotated with
+	 * __signed_wrap.
 	 */
-	return atomic_add_return(segs + delta, p_id) - segs;
+	return atomic_add_return(add_wrap(segs, delta), p_id) - segs;
 }
 
 void __ip_select_ident(struct net *net, struct iphdr *iph, int segs)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 13/82] btrfs: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (11 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 12/82] ipv4: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  1:45   ` David Sterba
  2024-01-23  0:26 ` [PATCH 14/82] smb: client: " Kees Cook
                   ` (70 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Chris Mason, Josef Bacik, David Sterba, linux-btrfs,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizer in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Chris Mason <clm@fb.com>
Cc: Josef Bacik <josef@toxicpanda.com>
Cc: David Sterba <dsterba@suse.com>
Cc: linux-btrfs@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/btrfs/extent_map.c | 6 ++++--
 fs/btrfs/extent_map.h | 6 ++++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index b61099bf97a8..29a649507857 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -73,9 +73,11 @@ void free_extent_map(struct extent_map *em)
 /* Do the math around the end of an extent, handling wrapping. */
 static u64 range_end(u64 start, u64 len)
 {
-	if (start + len < start)
+	u64 sum;
+
+	if (check_add_overflow(start, len, &sum))
 		return (u64)-1;
-	return start + len;
+	return sum;
 }
 
 static int tree_insert(struct rb_root_cached *root, struct extent_map *em)
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index e380fc08bbe4..3c4a6b977662 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -108,9 +108,11 @@ static inline int extent_map_in_tree(const struct extent_map *em)
 
 static inline u64 extent_map_end(const struct extent_map *em)
 {
-	if (em->start + em->len < em->start)
+	u64 sum;
+
+	if (check_add_overflow(em->start, em->len, &sum))
 		return (u64)-1;
-	return em->start + em->len;
+	return sum;
 }
 
 void extent_map_tree_init(struct extent_map_tree *tree);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 14/82] smb: client: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (12 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 13/82] btrfs: Refactor intentional wrap-around calculation Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 15/82] dma-buf: " Kees Cook
                   ` (69 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Steve French, Paulo Alcantara, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, linux-cifs, samba-technical,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded pointer wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizer in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Steve French <sfrench@samba.org>
Cc: Paulo Alcantara <pc@manguebit.com>
Cc: Ronnie Sahlberg <lsahlber@redhat.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/smb/client/readdir.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
index 94255401b38d..7715297359ab 100644
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -467,12 +467,13 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
 				pfData->FileNameLength;
 	} else {
 		u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset);
+		char *sum;
 
-		if (old_entry + next_offset < old_entry) {
+		if (check_add_overflow(old_entry, next_offset, &sum)) {
 			cifs_dbg(VFS, "Invalid offset %u\n", next_offset);
 			return NULL;
 		}
-		new_entry = old_entry + next_offset;
+		new_entry = sum;
 	}
 	cifs_dbg(FYI, "new entry %p old entry %p\n", new_entry, old_entry);
 	/* validate that new_entry is not past end of SMB */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 15/82] dma-buf: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (13 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 14/82] smb: client: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 16/82] drm/nouveau/mmu: " Kees Cook
                   ` (68 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Sumit Semwal, Christian König, linux-media,
	dri-devel, linaro-mm-sig, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Christian König <christian.koenig@amd.com>
Cc: "Christian König" <christian.koenig@amd.com>
Cc: linux-media@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/dma-buf/dma-buf.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 8fe5aa67b167..3743c63a9b59 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1458,6 +1458,8 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, DMA_BUF);
 int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
 		 unsigned long pgoff)
 {
+	unsigned long sum;
+
 	if (WARN_ON(!dmabuf || !vma))
 		return -EINVAL;
 
@@ -1466,12 +1468,11 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
 		return -EINVAL;
 
 	/* check for offset overflow */
-	if (pgoff + vma_pages(vma) < pgoff)
+	if (check_add_overflow(pgoff, vma_pages(vma), &sum))
 		return -EOVERFLOW;
 
 	/* check for overflowing the buffer's size */
-	if (pgoff + vma_pages(vma) >
-	    dmabuf->size >> PAGE_SHIFT)
+	if (sum > dmabuf->size >> PAGE_SHIFT)
 		return -EINVAL;
 
 	/* readjust the vma */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 16/82] drm/nouveau/mmu: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (14 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 15/82] dma-buf: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 17/82] drm/vc4: " Kees Cook
                   ` (67 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Karol Herbst, Lyude Paul, Danilo Krummrich,
	David Airlie, Daniel Vetter, Ben Skeggs, Dave Airlie,
	Julia Lawall, Jiang Jian, dri-devel, nouveau,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Karol Herbst <kherbst@redhat.com>
Cc: Lyude Paul <lyude@redhat.com>
Cc: Danilo Krummrich <dakr@redhat.com>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Julia Lawall <Julia.Lawall@inria.fr>
Cc: Jiang Jian <jiangjian@cdjrlc.com>
Cc: dri-devel@lists.freedesktop.org
Cc: nouveau@lists.freedesktop.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index 9c97800fe037..6ca1a82ccbc1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -1149,13 +1149,15 @@ nvkm_vmm_ctor(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu,
 	vmm->root = RB_ROOT;
 
 	if (managed) {
+		u64 sum;
+
 		/* Address-space will be managed by the client for the most
 		 * part, except for a specified area where NVKM allocations
 		 * are allowed to be placed.
 		 */
 		vmm->start = 0;
 		vmm->limit = 1ULL << bits;
-		if (addr + size < addr || addr + size > vmm->limit)
+		if (check_add_overflow(addr, size, &sum) || sum > vmm->limit)
 			return -EINVAL;
 
 		/* Client-managed area before the NVKM-managed area. */
@@ -1174,7 +1176,7 @@ nvkm_vmm_ctor(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu,
 		}
 
 		/* Client-managed area after the NVKM-managed area. */
-		addr = addr + size;
+		addr = sum;
 		size = vmm->limit - addr;
 		if (size && (ret = nvkm_vmm_ctor_managed(vmm, addr, size)))
 			return ret;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 17/82] drm/vc4: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (15 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 16/82] drm/nouveau/mmu: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 18/82] ext4: " Kees Cook
                   ` (66 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Maxime Ripard, Maarten Lankhorst, Thomas Zimmermann,
	David Airlie, Daniel Vetter, dri-devel, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/gpu/drm/vc4/vc4_validate.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 7dff3ca5af6b..9affba9c58b3 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -305,6 +305,7 @@ validate_gl_array_primitive(VALIDATE_ARGS)
 	uint32_t length = *(uint32_t *)(untrusted + 1);
 	uint32_t base_index = *(uint32_t *)(untrusted + 5);
 	uint32_t max_index;
+	uint32_t sum;
 	struct vc4_shader_state *shader_state;
 
 	/* Check overflow condition */
@@ -314,11 +315,11 @@ validate_gl_array_primitive(VALIDATE_ARGS)
 	}
 	shader_state = &exec->shader_state[exec->shader_state_count - 1];
 
-	if (length + base_index < length) {
+	if (check_add_overflow(length, base_index, &sum)) {
 		DRM_DEBUG("primitive vertex count overflow\n");
 		return -EINVAL;
 	}
-	max_index = length + base_index - 1;
+	max_index = sum - 1;
 
 	if (max_index > shader_state->max_index)
 		shader_state->max_index = max_index;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 18/82] ext4: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (16 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 17/82] drm/vc4: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 19/82] fs: " Kees Cook
                   ` (65 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Theodore Ts'o, Andreas Dilger, linux-ext4,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: linux-ext4@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/ext4/extents.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 01299b55a567..aa30b2c75959 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1920,6 +1920,7 @@ static unsigned int ext4_ext_check_overlap(struct ext4_sb_info *sbi,
 					   struct ext4_extent *newext,
 					   struct ext4_ext_path *path)
 {
+	ext4_lblk_t sum;
 	ext4_lblk_t b1, b2;
 	unsigned int depth, len1;
 	unsigned int ret = 0;
@@ -1943,14 +1944,14 @@ static unsigned int ext4_ext_check_overlap(struct ext4_sb_info *sbi,
 	}
 
 	/* check for wrap through zero on extent logical start block*/
-	if (b1 + len1 < b1) {
+	if (check_add_overflow(b1, len1, &sum)) {
 		len1 = EXT_MAX_BLOCKS - b1;
 		newext->ee_len = cpu_to_le16(len1);
 		ret = 1;
 	}
 
 	/* check for overlap */
-	if (b1 + len1 > b2) {
+	if (sum > b2) {
 		newext->ee_len = cpu_to_le16(b2 - b1);
 		ret = 1;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 19/82] fs: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (17 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 18/82] ext4: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23 18:01   ` Jan Kara
  2024-01-23  0:26 ` [PATCH 20/82] fpga: dfl: " Kees Cook
                   ` (64 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara,
	linux-fsdevel, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/read_write.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/read_write.c b/fs/read_write.c
index d4c036e82b6c..e24b94a8937d 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -1417,6 +1417,7 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
 	struct inode *inode_out = file_inode(file_out);
 	uint64_t count = *req_count;
 	loff_t size_in;
+	loff_t sum_in, sum_out;
 	int ret;
 
 	ret = generic_file_rw_checks(file_in, file_out);
@@ -1451,7 +1452,8 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
 		return -ETXTBSY;
 
 	/* Ensure offsets don't wrap. */
-	if (pos_in + count < pos_in || pos_out + count < pos_out)
+	if (check_add_overflow(pos_in, count, &sum_in) ||
+	    check_add_overflow(pos_out, count, &sum_out))
 		return -EOVERFLOW;
 
 	/* Shorten the copy to EOF */
@@ -1467,8 +1469,8 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
 
 	/* Don't allow overlapped copying within the same file. */
 	if (inode_in == inode_out &&
-	    pos_out + count > pos_in &&
-	    pos_out < pos_in + count)
+	    sum_out > pos_in &&
+	    pos_out < sum_in)
 		return -EINVAL;
 
 	*req_count = count;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 20/82] fpga: dfl: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (18 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 19/82] fs: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 21/82] drivers/fsi: " Kees Cook
                   ` (63 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Wu Hao, Tom Rix, Moritz Fischer, Xu Yilun, linux-fpga,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Wu Hao <hao.wu@intel.com>
Cc: Tom Rix <trix@redhat.com>
Cc: Moritz Fischer <mdf@kernel.org>
Cc: Xu Yilun <yilun.xu@intel.com>
Cc: linux-fpga@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/fpga/dfl.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
index e6d12fbab653..7d10780e3a98 100644
--- a/drivers/fpga/dfl.c
+++ b/drivers/fpga/dfl.c
@@ -1939,15 +1939,16 @@ static int do_set_irq_trigger(struct dfl_feature *feature, unsigned int idx,
 int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start,
 			      unsigned int count, int32_t *fds)
 {
+	unsigned int sum;
 	unsigned int i;
 	int ret = 0;
 
 	/* overflow */
-	if (unlikely(start + count < start))
+	if (unlikely(check_add_overflow(start, count, &sum)))
 		return -EINVAL;
 
 	/* exceeds nr_irqs */
-	if (start + count > feature->nr_irqs)
+	if (sum > feature->nr_irqs)
 		return -EINVAL;
 
 	for (i = 0; i < count; i++) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 21/82] drivers/fsi: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (19 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 20/82] fpga: dfl: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  0:26 ` [PATCH 22/82] x86/sgx: " Kees Cook
                   ` (62 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Jeremy Kerr, Joel Stanley, Alistar Popple,
	Eddie James, linux-fsi, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Jeremy Kerr <jk@ozlabs.org>
Cc: Joel Stanley <joel@jms.id.au>
Cc: Alistar Popple <alistair@popple.id.au>
Cc: Eddie James <eajames@linux.ibm.com>
Cc: linux-fsi@lists.ozlabs.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/fsi/fsi-core.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index 097d5a780264..46b24d0aadc6 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -381,10 +381,12 @@ EXPORT_SYMBOL_GPL(fsi_slave_write);
 int fsi_slave_claim_range(struct fsi_slave *slave,
 			  uint32_t addr, uint32_t size)
 {
-	if (addr + size < addr)
+	uint32_t sum;
+
+	if (check_add_overflow(addr, size, &sum))
 		return -EINVAL;
 
-	if (addr + size > slave->size)
+	if (sum > slave->size)
 		return -EINVAL;
 
 	/* todo: check for overlapping claims */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 22/82] x86/sgx: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (20 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 21/82] drivers/fsi: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23  9:15   ` Jarkko Sakkinen
  2024-01-23  0:26 ` [PATCH 23/82] KVM: " Kees Cook
                   ` (61 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Jarkko Sakkinen, Dave Hansen, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, x86, H. Peter Anvin, linux-sgx,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: linux-sgx@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/x86/kernel/cpu/sgx/ioctl.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
index b65ab214bdf5..4b8f6c9f8ef5 100644
--- a/arch/x86/kernel/cpu/sgx/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
@@ -350,16 +350,18 @@ static int sgx_validate_offset_length(struct sgx_encl *encl,
 				      unsigned long offset,
 				      unsigned long length)
 {
+	unsigned long sum;
+
 	if (!IS_ALIGNED(offset, PAGE_SIZE))
 		return -EINVAL;
 
 	if (!length || !IS_ALIGNED(length, PAGE_SIZE))
 		return -EINVAL;
 
-	if (offset + length < offset)
+	if (check_add_overflow(offset, length, &sum))
 		return -EINVAL;
 
-	if (offset + length - PAGE_SIZE >= encl->size)
+	if (sum - PAGE_SIZE >= encl->size)
 		return -EINVAL;
 
 	return 0;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 23/82] KVM: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (21 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 22/82] x86/sgx: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-24 16:25   ` Sean Christopherson
  2024-01-23  0:26 ` [PATCH 24/82] KVM: arm64: vgic: " Kees Cook
                   ` (60 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Paolo Bonzini, kvm, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notable, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed, unsigned, or
pointer types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/27 [2]
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 virt/kvm/coalesced_mmio.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
index 1b90acb6e3fe..0a3b706fbf4c 100644
--- a/virt/kvm/coalesced_mmio.c
+++ b/virt/kvm/coalesced_mmio.c
@@ -25,17 +25,19 @@ static inline struct kvm_coalesced_mmio_dev *to_mmio(struct kvm_io_device *dev)
 static int coalesced_mmio_in_range(struct kvm_coalesced_mmio_dev *dev,
 				   gpa_t addr, int len)
 {
+	gpa_t sum;
+
 	/* is it in a batchable area ?
 	 * (addr,len) is fully included in
 	 * (zone->addr, zone->size)
 	 */
 	if (len < 0)
 		return 0;
-	if (addr + len < addr)
+	if (check_add_overflow(addr, len, &sum))
 		return 0;
 	if (addr < dev->zone.addr)
 		return 0;
-	if (addr + len > dev->zone.addr + dev->zone.size)
+	if (sum > dev->zone.addr + dev->zone.size)
 		return 0;
 	return 1;
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 24/82] KVM: arm64: vgic: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (22 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 23/82] KVM: " Kees Cook
@ 2024-01-23  0:26 ` Kees Cook
  2024-01-23 10:49   ` Marc Zyngier
  2024-01-23  0:27 ` [PATCH 25/82] KVM: SVM: " Kees Cook
                   ` (59 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:26 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Reiji Watanabe, Eric Auger, Ricardo Koller,
	Raghavendra Rao Ananta, Quentin Perret, Jean-Philippe Brucker,
	linux-arm-kernel, kvmarm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: James Morse <james.morse@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Zenghui Yu <yuzenghui@huawei.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Reiji Watanabe <reijiw@google.com>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: Ricardo Koller <ricarkol@google.com>
Cc: Raghavendra Rao Ananta <rananta@google.com>
Cc: Quentin Perret <qperret@google.com>
Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org
Cc: kvmarm@lists.linux.dev
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm64/kvm/vgic/vgic-kvm-device.c |  6 ++++--
 arch/arm64/kvm/vgic/vgic-v2.c         | 10 ++++++----
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
index f48b8dab8b3d..0eec5344d203 100644
--- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
+++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
@@ -18,17 +18,19 @@ int vgic_check_iorange(struct kvm *kvm, phys_addr_t ioaddr,
 		       phys_addr_t addr, phys_addr_t alignment,
 		       phys_addr_t size)
 {
+	phys_addr_t sum;
+
 	if (!IS_VGIC_ADDR_UNDEF(ioaddr))
 		return -EEXIST;
 
 	if (!IS_ALIGNED(addr, alignment) || !IS_ALIGNED(size, alignment))
 		return -EINVAL;
 
-	if (addr + size < addr)
+	if (check_add_overflow(addr, size, &sum))
 		return -EINVAL;
 
 	if (addr & ~kvm_phys_mask(&kvm->arch.mmu) ||
-	    (addr + size) > kvm_phys_size(&kvm->arch.mmu))
+	    sum > kvm_phys_size(&kvm->arch.mmu))
 		return -E2BIG;
 
 	return 0;
diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
index 7e9cdb78f7ce..c8d1e965d3b7 100644
--- a/arch/arm64/kvm/vgic/vgic-v2.c
+++ b/arch/arm64/kvm/vgic/vgic-v2.c
@@ -273,14 +273,16 @@ void vgic_v2_enable(struct kvm_vcpu *vcpu)
 /* check for overlapping regions and for regions crossing the end of memory */
 static bool vgic_v2_check_base(gpa_t dist_base, gpa_t cpu_base)
 {
-	if (dist_base + KVM_VGIC_V2_DIST_SIZE < dist_base)
+	gpa_t dist_sum, cpu_sum;
+
+	if (check_add_overflow(dist_base, KVM_VGIC_V2_DIST_SIZE, &dist_sum))
 		return false;
-	if (cpu_base + KVM_VGIC_V2_CPU_SIZE < cpu_base)
+	if (check_add_overflow(cpu_base, KVM_VGIC_V2_CPU_SIZE, &cpu_sum))
 		return false;
 
-	if (dist_base + KVM_VGIC_V2_DIST_SIZE <= cpu_base)
+	if (dist_sum <= cpu_base)
 		return true;
-	if (cpu_base + KVM_VGIC_V2_CPU_SIZE <= dist_base)
+	if (cpu_sum <= dist_base)
 		return true;
 
 	return false;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 25/82] KVM: SVM: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (23 preceding siblings ...)
  2024-01-23  0:26 ` [PATCH 24/82] KVM: arm64: vgic: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-24 16:15   ` Sean Christopherson
  2024-01-23  0:27 ` [PATCH 26/82] buildid: " Kees Cook
                   ` (58 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Sean Christopherson, Paolo Bonzini, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
	kvm, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Sean Christopherson <seanjc@google.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: kvm@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/x86/kvm/svm/sev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index f760106c31f8..12a6a2b1ac81 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -400,16 +400,17 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
 	unsigned long locked, lock_limit;
 	struct page **pages;
 	unsigned long first, last;
+	unsigned long sum;
 	int ret;
 
 	lockdep_assert_held(&kvm->lock);
 
-	if (ulen == 0 || uaddr + ulen < uaddr)
+	if (ulen == 0 || check_add_overflow(uaddr, ulen, &sum))
 		return ERR_PTR(-EINVAL);
 
 	/* Calculate number of pages. */
 	first = (uaddr & PAGE_MASK) >> PAGE_SHIFT;
-	last = ((uaddr + ulen - 1) & PAGE_MASK) >> PAGE_SHIFT;
+	last = ((sum - 1) & PAGE_MASK) >> PAGE_SHIFT;
 	npages = (last - first + 1);
 
 	locked = sev->pages_locked + npages;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 26/82] buildid: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (24 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 25/82] KVM: SVM: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 27/82] m68k: " Kees Cook
                   ` (57 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Andrew Morton, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded pointer wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/buildid.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/buildid.c b/lib/buildid.c
index e3a7acdeef0e..d0a310cb9b57 100644
--- a/lib/buildid.c
+++ b/lib/buildid.c
@@ -54,12 +54,14 @@ static inline int parse_build_id(const void *page_addr,
 				 const void *note_start,
 				 Elf32_Word note_size)
 {
+	const void *sum;
+
 	/* check for overflow */
-	if (note_start < page_addr || note_start + note_size < note_start)
+	if (note_start < page_addr || check_add_overflow(note_start, note_size, &sum))
 		return -EINVAL;
 
 	/* only supports note that fits in the first page */
-	if (note_start + note_size > page_addr + PAGE_SIZE)
+	if (sum > page_addr + PAGE_SIZE)
 		return -EINVAL;
 
 	return parse_build_id_buf(build_id, size, note_start, note_size);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 27/82] m68k: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (25 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 26/82] buildid: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  2:29   ` Liam R. Howlett
  2024-01-23  8:13   ` Geert Uytterhoeven
  2024-01-23  0:27 ` [PATCH 28/82] niu: " Kees Cook
                   ` (56 subsequent siblings)
  83 siblings, 2 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Geert Uytterhoeven, Andrew Morton, Arnd Bergmann,
	Liam Howlett, Matthew Wilcox (Oracle),
	Hugh Dickins, linux-m68k, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: Hugh Dickins <hughd@google.com>
Cc: linux-m68k@lists.linux-m68k.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/m68k/kernel/sys_m68k.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 1af5e6082467..b2b9248f2566 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -391,10 +391,11 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
 
 		mmap_read_lock(current->mm);
 	} else {
+		unsigned long sum;
 		struct vm_area_struct *vma;
 
 		/* Check for overflow.  */
-		if (addr + len < addr)
+		if (check_add_overflow(addr, len, &sum))
 			goto out;
 
 		/*
@@ -403,7 +404,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
 		 */
 		mmap_read_lock(current->mm);
 		vma = vma_lookup(current->mm, addr);
-		if (!vma || addr + len > vma->vm_end)
+		if (!vma || sum > vma->vm_end)
 			goto out_unlock;
 	}
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 28/82] niu: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (26 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 27/82] m68k: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 29/82] rds: " Kees Cook
                   ` (55 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Du Cheng, netdev, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Cc: Du Cheng <ducheng2@gmail.com>
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/net/ethernet/sun/niu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 21431f43e4c2..a4de07c6e618 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -6877,15 +6877,16 @@ static int niu_get_eeprom(struct net_device *dev,
 {
 	struct niu *np = netdev_priv(dev);
 	u32 offset, len, val;
+	u32 sum;
 
 	offset = eeprom->offset;
 	len = eeprom->len;
 
-	if (offset + len < offset)
+	if (check_add_overflow(offset, len, &sum))
 		return -EINVAL;
 	if (offset >= np->eeprom_len)
 		return -EINVAL;
-	if (offset + len > np->eeprom_len)
+	if (sum > np->eeprom_len)
 		len = eeprom->len = np->eeprom_len - offset;
 
 	if (offset & 3) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 29/82] rds: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (27 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 28/82] niu: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 30/82] s390/kexec_file: " Kees Cook
                   ` (54 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Santosh Shilimkar, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, netdev, linux-rdma, rds-devel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: netdev@vger.kernel.org
Cc: linux-rdma@vger.kernel.org
Cc: rds-devel@oss.oracle.com
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 net/rds/info.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/rds/info.c b/net/rds/info.c
index b6b46a8214a0..87b35d07ce04 100644
--- a/net/rds/info.c
+++ b/net/rds/info.c
@@ -163,6 +163,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
 	unsigned long nr_pages = 0;
 	unsigned long start;
 	rds_info_func func;
+	unsigned long sum;
 	struct page **pages = NULL;
 	int ret;
 	int len;
@@ -175,7 +176,8 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
 
 	/* check for all kinds of wrapping and the like */
 	start = (unsigned long)optval;
-	if (len < 0 || len > INT_MAX - PAGE_SIZE + 1 || start + len < start) {
+	if (len < 0 || len > INT_MAX - PAGE_SIZE + 1 ||
+	    check_add_overflow(start, len, &sum)) {
 		ret = -EINVAL;
 		goto out;
 	}
@@ -184,7 +186,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
 	if (len == 0)
 		goto call_func;
 
-	nr_pages = (PAGE_ALIGN(start + len) - (start & PAGE_MASK))
+	nr_pages = (PAGE_ALIGN(sum) - (start & PAGE_MASK))
 			>> PAGE_SHIFT;
 
 	pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 30/82] s390/kexec_file: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (28 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 29/82] rds: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-31 14:22   ` Alexander Gordeev
  2024-01-23  0:27 ` [PATCH 31/82] ARC: dw2 unwind: " Kees Cook
                   ` (53 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Nico Boehr, Philipp Rudo,
	Baoquan He, Tao Liu, Alexander Egorenkov, linux-s390,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Nico Boehr <nrb@linux.ibm.com>
Cc: Philipp Rudo <prudo@redhat.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Tao Liu <ltao@redhat.com>
Cc: Alexander Egorenkov <egorenar@linux.ibm.com>
Cc: linux-s390@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/s390/include/asm/stacktrace.h    | 6 ++++--
 arch/s390/kernel/machine_kexec_file.c | 5 +++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/arch/s390/include/asm/stacktrace.h b/arch/s390/include/asm/stacktrace.h
index 31ec4f545e03..3ce08d32a8ad 100644
--- a/arch/s390/include/asm/stacktrace.h
+++ b/arch/s390/include/asm/stacktrace.h
@@ -34,11 +34,13 @@ int get_stack_info(unsigned long sp, struct task_struct *task,
 static inline bool on_stack(struct stack_info *info,
 			    unsigned long addr, size_t len)
 {
+	unsigned long sum;
+
 	if (info->type == STACK_TYPE_UNKNOWN)
 		return false;
-	if (addr + len < addr)
+	if (check_add_overflow(addr, len, &sum))
 		return false;
-	return addr >= info->begin && addr + len <= info->end;
+	return addr >= info->begin && sum <= info->end;
 }
 
 /*
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
index 8d207b82d9fe..e5e925423061 100644
--- a/arch/s390/kernel/machine_kexec_file.c
+++ b/arch/s390/kernel/machine_kexec_file.c
@@ -238,6 +238,7 @@ void *kexec_file_add_components(struct kimage *image,
 	unsigned long max_command_line_size = LEGACY_COMMAND_LINE_SIZE;
 	struct s390_load_data data = {0};
 	unsigned long minsize;
+	unsigned long sum;
 	int ret;
 
 	data.report = ipl_report_init(&ipl_block);
@@ -256,10 +257,10 @@ void *kexec_file_add_components(struct kimage *image,
 	if (data.parm->max_command_line_size)
 		max_command_line_size = data.parm->max_command_line_size;
 
-	if (minsize + max_command_line_size < minsize)
+	if (check_add_overflow(minsize, max_command_line_size, &sum))
 		goto out;
 
-	if (image->kernel_buf_len < minsize + max_command_line_size)
+	if (image->kernel_buf_len < sum)
 		goto out;
 
 	if (image->cmdline_buf_len >= max_command_line_size)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 31/82] ARC: dw2 unwind: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (29 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 30/82] s390/kexec_file: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 32/82] vringh: " Kees Cook
                   ` (52 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Vineet Gupta, Luis Chamberlain, Song Liu, Yihao Han,
	Thomas Gleixner, dean.yang_cp, Jinchao Wang, linux-snps-arc,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded pointer wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which
removes the redundant open-coded addition). This paves the way to enabling
the unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Vineet Gupta <vgupta@kernel.org>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: Song Liu <song@kernel.org>
Cc: Yihao Han <hanyihao@vivo.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: "dean.yang_cp" <yangdianqing@yulong.com>
Cc: Jinchao Wang <wjc@cdjrlc.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arc/kernel/unwind.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 9270d0a713c3..8924fa2a8f29 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -612,6 +612,7 @@ static signed fde_pointer_type(const u32 *cie)
 		const char *aug;
 		const u8 *end = (const u8 *)(cie + 1) + *cie;
 		uleb128_t len;
+		const u8 *sum;
 
 		/* check if augmentation size is first (and thus present) */
 		if (*ptr != 'z')
@@ -630,10 +631,10 @@ static signed fde_pointer_type(const u32 *cie)
 		version <= 1 ? (void) ++ptr : (void)get_uleb128(&ptr, end);
 		len = get_uleb128(&ptr, end);	/* augmentation length */
 
-		if (ptr + len < ptr || ptr + len > end)
+		if (check_add_overflow(ptr, len, &sum) || sum > end)
 			return -1;
 
-		end = ptr + len;
+		end = sum;
 		while (*++aug) {
 			if (ptr >= end)
 				return -1;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 32/82] vringh: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (30 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 31/82] ARC: dw2 unwind: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-26 19:31   ` Eugenio Perez Martin
  2024-01-23  0:27 ` [PATCH 33/82] mm/vmalloc: " Kees Cook
                   ` (51 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Michael S. Tsirkin, Jason Wang, kvm, virtualization,
	netdev, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: kvm@vger.kernel.org
Cc: virtualization@lists.linux.dev
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/vhost/vringh.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index 7b8fd977f71c..07442f0a52bd 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -145,6 +145,8 @@ static inline bool range_check(struct vringh *vrh, u64 addr, size_t *len,
 			       bool (*getrange)(struct vringh *,
 						u64, struct vringh_range *))
 {
+	u64 sum;
+
 	if (addr < range->start || addr > range->end_incl) {
 		if (!getrange(vrh, addr, range))
 			return false;
@@ -152,20 +154,20 @@ static inline bool range_check(struct vringh *vrh, u64 addr, size_t *len,
 	BUG_ON(addr < range->start || addr > range->end_incl);
 
 	/* To end of memory? */
-	if (unlikely(addr + *len == 0)) {
+	if (unlikely(U64_MAX - addr == *len)) {
 		if (range->end_incl == -1ULL)
 			return true;
 		goto truncate;
 	}
 
 	/* Otherwise, don't wrap. */
-	if (addr + *len < addr) {
+	if (check_add_overflow(addr, *len, &sum)) {
 		vringh_bad("Wrapping descriptor %zu@0x%llx",
 			   *len, (unsigned long long)addr);
 		return false;
 	}
 
-	if (unlikely(addr + *len - 1 > range->end_incl))
+	if (unlikely(sum - 1 > range->end_incl))
 		goto truncate;
 	return true;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 33/82] mm/vmalloc: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (31 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 32/82] vringh: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-30 18:55   ` Lorenzo Stoakes
  2024-01-23  0:27 ` [PATCH 34/82] ipc: " Kees Cook
                   ` (50 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Andrew Morton, Uladzislau Rezki, Christoph Hellwig,
	Lorenzo Stoakes, linux-mm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Uladzislau Rezki <urezki@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Lorenzo Stoakes <lstoakes@gmail.com>
Cc: linux-mm@kvack.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 mm/vmalloc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d12a17fc0c17..7932ac99e9d3 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1223,6 +1223,7 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
 	unsigned long align, unsigned long vstart)
 {
 	unsigned long nva_start_addr;
+	unsigned long sum;
 
 	if (va->va_start > vstart)
 		nva_start_addr = ALIGN(va->va_start, align);
@@ -1230,11 +1231,11 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
 		nva_start_addr = ALIGN(vstart, align);
 
 	/* Can be overflowed due to big size or alignment. */
-	if (nva_start_addr + size < nva_start_addr ||
+	if (check_add_overflow(nva_start_addr, size, &sum) ||
 			nva_start_addr < vstart)
 		return false;
 
-	return (nva_start_addr + size <= va->va_end);
+	return (sum <= va->va_end);
 }
 
 /*
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 34/82] ipc: Refactor intentional wrap-around calculation
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (32 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 33/82] mm/vmalloc: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  1:07   ` Linus Torvalds
  2024-01-23  0:27 ` [PATCH 35/82] ACPI: custom_method: Refactor intentional wrap-around test Kees Cook
                   ` (49 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Linus Torvalds, Andrew Morton, Liam R. Howlett,
	Mark Brown, Mike Kravetz, Vasily Averin, Alexander Mikhalitsyn,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded unsigned wrap-around addition test to use
check_add_overflow(), retaining the result for later usage (which removes
the redundant open-coded addition). This paves the way to enabling the
unsigned wrap-around sanitizer[2] in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Liam R. Howlett" <Liam.Howlett@oracle.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: Vasily Averin <vasily.averin@linux.dev>
Cc: Alexander Mikhalitsyn <alexander@mihalicyn.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 ipc/shm.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/ipc/shm.c b/ipc/shm.c
index a89f001a8bf0..227a1610628a 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1650,11 +1650,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
 	}
 
 	if (addr && !(shmflg & SHM_REMAP)) {
+		unsigned long sum;
+
 		err = -EINVAL;
-		if (addr + size < addr)
+		if (check_add_overflow(addr, size, &sum))
 			goto invalid;
 
-		if (find_vma_intersection(current->mm, addr, addr + size))
+		if (find_vma_intersection(current->mm, addr, sum))
 			goto invalid;
 	}
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 35/82] ACPI: custom_method: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (33 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 34/82] ipc: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-24 19:52   ` Rafael J. Wysocki
  2024-01-23  0:27 ` [PATCH 36/82] agp: " Kees Cook
                   ` (48 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Rafael J. Wysocki, Len Brown, linux-acpi,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Len Brown <lenb@kernel.org>
Cc: linux-acpi@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/acpi/custom_method.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
index d39a9b474727..0789317f4a1a 100644
--- a/drivers/acpi/custom_method.c
+++ b/drivers/acpi/custom_method.c
@@ -54,7 +54,7 @@ static ssize_t cm_write(struct file *file, const char __user *user_buf,
 
 	if ((*ppos > max_size) ||
 	    (*ppos + count > max_size) ||
-	    (*ppos + count < count) ||
+	    (add_would_overflow(count, *ppos)) ||
 	    (count > uncopied_bytes)) {
 		kfree(buf);
 		buf = NULL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 36/82] agp: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (34 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 35/82] ACPI: custom_method: Refactor intentional wrap-around test Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 37/82] aio: " Kees Cook
                   ` (47 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Greg Kroah-Hartman, David Airlie, dri-devel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: David Airlie <airlied@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/char/agp/generic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 3ffbb1c80c5c..fc2d07654154 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -228,7 +228,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,
 
 	cur_memory = atomic_read(&bridge->current_memory_agp);
 	if ((cur_memory + page_count > bridge->max_memory_agp) ||
-	    (cur_memory + page_count < page_count))
+	    (add_would_overflow(page_count, cur_memory)))
 		return NULL;
 
 	if (type >= AGP_USER_TYPES) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 37/82] aio: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (35 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 36/82] agp: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23 15:30   ` Christian Brauner
  2024-01-23 18:03   ` Jan Kara
  2024-01-23  0:27 ` [PATCH 38/82] arm: 3117/1: " Kees Cook
                   ` (46 subsequent siblings)
  83 siblings, 2 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Benjamin LaHaise, Alexander Viro, Christian Brauner,
	Jan Kara, linux-aio, linux-fsdevel, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Benjamin LaHaise <bcrl@kvack.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-aio@kvack.org
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/aio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/aio.c b/fs/aio.c
index bb2ff48991f3..edd19be3f4b1 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -796,7 +796,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
 	/* limit the number of system wide aios */
 	spin_lock(&aio_nr_lock);
 	if (aio_nr + ctx->max_reqs > aio_max_nr ||
-	    aio_nr + ctx->max_reqs < aio_nr) {
+	    add_would_overflow(aio_nr, ctx->max_reqs)) {
 		spin_unlock(&aio_nr_lock);
 		err = -EAGAIN;
 		goto err_ctx;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 38/82] arm: 3117/1: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (36 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 37/82] aio: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  9:56   ` Mark Rutland
  2024-01-23  0:27 ` [PATCH 39/82] crypto: " Kees Cook
                   ` (45 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Russell King, linux-arm-kernel, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Russell King <linux@armlinux.org.uk>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm/nwfpe/softfloat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
index ffa6b438786b..0635b1eda1d3 100644
--- a/arch/arm/nwfpe/softfloat.c
+++ b/arch/arm/nwfpe/softfloat.c
@@ -603,7 +603,7 @@ static floatx80
     roundBits = zSig0 & roundMask;
     if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
         if (    ( 0x7FFE < zExp )
-             || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
+             || ( ( zExp == 0x7FFE ) && (add_would_overflow(zSig0, roundIncrement)) )
            ) {
             goto overflow;
         }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 39/82] crypto: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (37 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 38/82] arm: 3117/1: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 40/82] arm64: stacktrace: " Kees Cook
                   ` (44 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Jesper Nilsson, Lars Persson, Herbert Xu,
	David S. Miller, linux-arm-kernel, linux-crypto,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Jesper Nilsson <jesper.nilsson@axis.com>
Cc: Lars Persson <lars.persson@axis.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-arm-kernel@axis.com
Cc: linux-crypto@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/crypto/axis/artpec6_crypto.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/axis/artpec6_crypto.c b/drivers/crypto/axis/artpec6_crypto.c
index dbc1d483f2af..cbec539f0e20 100644
--- a/drivers/crypto/axis/artpec6_crypto.c
+++ b/drivers/crypto/axis/artpec6_crypto.c
@@ -1190,7 +1190,7 @@ artpec6_crypto_ctr_crypt(struct skcipher_request *req, bool encrypt)
 	 * the whole IV is a counter.  So fallback if the counter is going to
 	 * overlow.
 	 */
-	if (counter + nblks < counter) {
+	if (add_would_overflow(counter, nblks)) {
 		int ret;
 
 		pr_debug("counter %x will overflow (nblks %u), falling back\n",
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 40/82] arm64: stacktrace: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (38 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 39/82] crypto: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  9:58   ` Mark Rutland
  2024-01-23  0:27 ` [PATCH 41/82] wil6210: " Kees Cook
                   ` (43 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Catalin Marinas, Will Deacon, Kalesh Singh,
	Fuad Tabba, Mark Brown, Madhavan T. Venkataraman, Marc Zyngier,
	Mark Rutland, linux-arm-kernel, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Kalesh Singh <kaleshsingh@google.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm64/include/asm/stacktrace/common.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/stacktrace/common.h b/arch/arm64/include/asm/stacktrace/common.h
index f63dc654e545..6e0cb84961f8 100644
--- a/arch/arm64/include/asm/stacktrace/common.h
+++ b/arch/arm64/include/asm/stacktrace/common.h
@@ -49,7 +49,7 @@ static inline bool stackinfo_on_stack(const struct stack_info *info,
 	if (!info->low)
 		return false;
 
-	if (sp < info->low || sp + size < sp || sp + size > info->high)
+	if (sp < info->low || add_would_overflow(sp, size) || sp + size > info->high)
 		return false;
 
 	return true;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 41/82] wil6210: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (39 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 40/82] arm64: stacktrace: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  6:36   ` Kalle Valo
  2024-01-23 11:50   ` Kalle Valo
  2024-01-23  0:27 ` [PATCH 42/82] bcachefs: " Kees Cook
                   ` (42 subsequent siblings)
  83 siblings, 2 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Kalle Valo, Johannes Berg, Max Chen, Yang Shen,
	linux-wireless, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Kalle Valo <kvalo@kernel.org>
Cc: Johannes Berg <johannes.berg@intel.com>
Cc: Max Chen <mxchen@codeaurora.org>
Cc: Yang Shen <shenyang39@huawei.com>
Cc: linux-wireless@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/net/wireless/ath/wil6210/wmi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 6fdb77d4c59e..3b3c991f77e9 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -286,7 +286,7 @@ void __iomem *wmi_buffer_block(struct wil6210_priv *wil, __le32 ptr_, u32 size)
 	off = HOSTADDR(ptr);
 	if (off > wil->bar_size - 4)
 		return NULL;
-	if (size && ((off + size > wil->bar_size) || (off + size < off)))
+	if (size && ((off + size > wil->bar_size) || (add_would_overflow(off, size))))
 		return NULL;
 
 	return wil->csr + off;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 42/82] bcachefs: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (40 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 41/82] wil6210: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  6:36   ` Kent Overstreet
  2024-01-23  0:27 ` [PATCH 43/82] bpf: " Kees Cook
                   ` (41 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Kent Overstreet, Brian Foster, linux-bcachefs,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Kent Overstreet <kent.overstreet@linux.dev>
Cc: Brian Foster <bfoster@redhat.com>
Cc: linux-bcachefs@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/bcachefs/bkey.c  | 4 ++--
 fs/bcachefs/fs.c    | 2 +-
 fs/bcachefs/quota.c | 2 +-
 fs/bcachefs/util.c  | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/fs/bcachefs/bkey.c b/fs/bcachefs/bkey.c
index 76e79a15ba08..c68f1cfd579e 100644
--- a/fs/bcachefs/bkey.c
+++ b/fs/bcachefs/bkey.c
@@ -448,7 +448,7 @@ static bool bkey_format_has_too_big_fields(const struct bkey_format *f)
 			: 0;
 		u64 field_offset = le64_to_cpu(f->field_offset[i]);
 
-		if (packed_max + field_offset < packed_max ||
+		if (add_would_overflow(packed_max, field_offset) ||
 		    packed_max + field_offset > unpacked_max)
 			return true;
 	}
@@ -664,7 +664,7 @@ int bch2_bkey_format_invalid(struct bch_fs *c,
 				: 0;
 			u64 field_offset = le64_to_cpu(f->field_offset[i]);
 
-			if (packed_max + field_offset < packed_max ||
+			if (add_would_overflow(packed_max, field_offset) ||
 			    packed_max + field_offset > unpacked_max) {
 				prt_printf(err, "field %u too large: %llu + %llu > %llu",
 					   i, packed_max, field_offset, unpacked_max);
diff --git a/fs/bcachefs/fs.c b/fs/bcachefs/fs.c
index ec419b8e2c43..00a606171656 100644
--- a/fs/bcachefs/fs.c
+++ b/fs/bcachefs/fs.c
@@ -901,7 +901,7 @@ static int bch2_fiemap(struct inode *vinode, struct fiemap_extent_info *info,
 	if (ret)
 		return ret;
 
-	if (start + len < start)
+	if (add_would_overflow(start, len))
 		return -EINVAL;
 
 	start >>= 9;
diff --git a/fs/bcachefs/quota.c b/fs/bcachefs/quota.c
index e68b34eab90a..1738b1fc1c75 100644
--- a/fs/bcachefs/quota.c
+++ b/fs/bcachefs/quota.c
@@ -392,7 +392,7 @@ static void __bch2_quota_transfer(struct bch_memquota *src_q,
 				  enum quota_counters counter, s64 v)
 {
 	BUG_ON(v > src_q->c[counter].v);
-	BUG_ON(v + dst_q->c[counter].v < v);
+	BUG_ON(add_would_overflow(v, dst_q->c[counter].v));
 
 	src_q->c[counter].v -= v;
 	dst_q->c[counter].v += v;
diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c
index a135136adeee..2200c81edbd2 100644
--- a/fs/bcachefs/util.c
+++ b/fs/bcachefs/util.c
@@ -148,7 +148,7 @@ static int __bch2_strtou64_h(const char *cp, u64 *res)
 		return -ERANGE;
 
 	f_n = div_u64(f_n * b, f_d);
-	if (v + f_n < v)
+	if (add_would_overflow(v, f_n))
 		return -ERANGE;
 	v += f_n;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 43/82] bpf: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (41 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 42/82] bcachefs: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  4:00   ` Yonghong Song
  2024-01-23  0:27 ` [PATCH 44/82] btrfs: " Kees Cook
                   ` (40 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, Yonghong Song,
	KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: Song Liu <song@kernel.org>
Cc: Yonghong Song <yonghong.song@linux.dev>
Cc: KP Singh <kpsingh@kernel.org>
Cc: Stanislav Fomichev <sdf@google.com>
Cc: Hao Luo <haoluo@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: bpf@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 kernel/bpf/verifier.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 65f598694d55..21e3f30c8757 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12901,8 +12901,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
 			dst_reg->smin_value = smin_ptr + smin_val;
 			dst_reg->smax_value = smax_ptr + smax_val;
 		}
-		if (umin_ptr + umin_val < umin_ptr ||
-		    umax_ptr + umax_val < umax_ptr) {
+		if (add_would_overflow(umin_ptr, umin_val) ||
+		    add_would_overflow(umax_ptr, umax_val)) {
 			dst_reg->umin_value = 0;
 			dst_reg->umax_value = U64_MAX;
 		} else {
@@ -13023,8 +13023,8 @@ static void scalar32_min_max_add(struct bpf_reg_state *dst_reg,
 		dst_reg->s32_min_value += smin_val;
 		dst_reg->s32_max_value += smax_val;
 	}
-	if (dst_reg->u32_min_value + umin_val < umin_val ||
-	    dst_reg->u32_max_value + umax_val < umax_val) {
+	if (add_would_overflow(umin_val, dst_reg->u32_min_value) ||
+	    add_would_overflow(umax_val, dst_reg->u32_max_value)) {
 		dst_reg->u32_min_value = 0;
 		dst_reg->u32_max_value = U32_MAX;
 	} else {
@@ -13049,8 +13049,8 @@ static void scalar_min_max_add(struct bpf_reg_state *dst_reg,
 		dst_reg->smin_value += smin_val;
 		dst_reg->smax_value += smax_val;
 	}
-	if (dst_reg->umin_value + umin_val < umin_val ||
-	    dst_reg->umax_value + umax_val < umax_val) {
+	if (add_would_overflow(umin_val, dst_reg->umin_value) ||
+	    add_would_overflow(umax_val, dst_reg->umax_value)) {
 		dst_reg->umin_value = 0;
 		dst_reg->umax_value = U64_MAX;
 	} else {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 44/82] btrfs: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (42 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 43/82] bpf: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23 18:00   ` David Sterba
  2024-01-23  0:27 ` [PATCH 45/82] cifs: " Kees Cook
                   ` (39 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Chris Mason, Josef Bacik, David Sterba, linux-btrfs,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Chris Mason <clm@fb.com>
Cc: Josef Bacik <josef@toxicpanda.com>
Cc: David Sterba <dsterba@suse.com>
Cc: linux-btrfs@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/btrfs/ordered-data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 59850dc17b22..2e0865693cee 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -813,7 +813,7 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
 	u64 orig_end;
 	struct btrfs_ordered_extent *ordered;
 
-	if (start + len < start) {
+	if (add_would_overflow(start, len)) {
 		orig_end = OFFSET_MAX;
 	} else {
 		orig_end = start + len - 1;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 45/82] cifs: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (43 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 44/82] btrfs: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 46/82] crypto: " Kees Cook
                   ` (38 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Steve French, Paulo Alcantara, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, linux-cifs, samba-technical,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Steve French <sfrench@samba.org>
Cc: Paulo Alcantara <pc@manguebit.com>
Cc: Ronnie Sahlberg <lsahlber@redhat.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/smb/client/smb2pdu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 288199f0b987..85399525f0a7 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -5007,7 +5007,7 @@ num_entries(int infotype, char *bufstart, char *end_of_buf, char **lastentry,
 	entryptr = bufstart;
 
 	while (1) {
-		if (entryptr + next_offset < entryptr ||
+		if (add_would_overflow(entryptr, next_offset) ||
 		    entryptr + next_offset > end_of_buf ||
 		    entryptr + next_offset + size > end_of_buf) {
 			cifs_dbg(VFS, "malformed search entry would overflow\n");
@@ -5023,7 +5023,7 @@ num_entries(int infotype, char *bufstart, char *end_of_buf, char **lastentry,
 			len = le32_to_cpu(dir_info->FileNameLength);
 
 		if (len < 0 ||
-		    entryptr + len < entryptr ||
+		    add_would_overflow(entryptr, len) ||
 		    entryptr + len > end_of_buf ||
 		    entryptr + len + size > end_of_buf) {
 			cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n",
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 46/82] crypto: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (44 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 45/82] cifs: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  3:07   ` Eric Biggers
  2024-01-23  0:27 ` [PATCH 47/82] dm verity: " Kees Cook
                   ` (37 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Herbert Xu, David S. Miller, Aditya Srivastava,
	Randy Dunlap, linux-crypto, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Aditya Srivastava <yashsri421@gmail.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: linux-crypto@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 crypto/adiantum.c                   | 2 +-
 drivers/crypto/amcc/crypto4xx_alg.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/crypto/adiantum.c b/crypto/adiantum.c
index 60f3883b736a..c2f62ca455af 100644
--- a/crypto/adiantum.c
+++ b/crypto/adiantum.c
@@ -190,7 +190,7 @@ static inline void le128_add(le128 *r, const le128 *v1, const le128 *v2)
 
 	r->b = cpu_to_le64(x + y);
 	r->a = cpu_to_le64(le64_to_cpu(v1->a) + le64_to_cpu(v2->a) +
-			   (x + y < x));
+			   (add_would_overflow(x, y)));
 }
 
 /* Subtraction in Z/(2^{128}Z) */
diff --git a/drivers/crypto/amcc/crypto4xx_alg.c b/drivers/crypto/amcc/crypto4xx_alg.c
index e0af611a95d8..33f73234ddd9 100644
--- a/drivers/crypto/amcc/crypto4xx_alg.c
+++ b/drivers/crypto/amcc/crypto4xx_alg.c
@@ -251,7 +251,7 @@ crypto4xx_ctr_crypt(struct skcipher_request *req, bool encrypt)
 	 * the whole IV is a counter.  So fallback if the counter is going to
 	 * overlow.
 	 */
-	if (counter + nblks < counter) {
+	if (add_would_overflow(counter, nblks)) {
 		SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->sw_cipher.cipher);
 		int ret;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 47/82] dm verity: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (45 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 46/82] crypto: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-30 18:58   ` Mike Snitzer
  2024-01-23  0:27 ` [PATCH 48/82] drm/nouveau/mmu: " Kees Cook
                   ` (36 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Alasdair Kergon, Mike Snitzer, Mikulas Patocka,
	dm-devel, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Alasdair Kergon <agk@redhat.com>
Cc: Mike Snitzer <snitzer@kernel.org>
Cc: Mikulas Patocka <mpatocka@redhat.com>
Cc: dm-devel@lists.linux.dev
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/md/dm-switch.c        | 2 +-
 drivers/md/dm-verity-target.c | 2 +-
 drivers/md/dm-writecache.c    | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/md/dm-switch.c b/drivers/md/dm-switch.c
index dfd9fb52a6f3..9053d7e65603 100644
--- a/drivers/md/dm-switch.c
+++ b/drivers/md/dm-switch.c
@@ -410,7 +410,7 @@ static int process_set_region_mappings(struct switch_ctx *sctx,
 				       cycle_length - 1, region_index);
 				return -EINVAL;
 			}
-			if (unlikely(region_index + num_write < region_index) ||
+			if (unlikely(add_would_overflow(region_index, num_write)) ||
 			    unlikely(region_index + num_write >= sctx->nr_regions)) {
 				DMWARN("invalid set_region_mappings region number: %lu + %lu >= %lu",
 				       region_index, num_write, sctx->nr_regions);
diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
index 14e58ae70521..f2676c8c83c0 100644
--- a/drivers/md/dm-verity-target.c
+++ b/drivers/md/dm-verity-target.c
@@ -1392,7 +1392,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 		v->hash_level_block[i] = hash_position;
 		s = (v->data_blocks + ((sector_t)1 << ((i + 1) * v->hash_per_block_bits)) - 1)
 					>> ((i + 1) * v->hash_per_block_bits);
-		if (hash_position + s < hash_position) {
+		if (add_would_overflow(hash_position, s)) {
 			ti->error = "Hash device offset overflow";
 			r = -E2BIG;
 			goto bad;
diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
index 074cb785eafc..45e54edd24aa 100644
--- a/drivers/md/dm-writecache.c
+++ b/drivers/md/dm-writecache.c
@@ -2631,7 +2631,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 	offset = (offset + wc->block_size - 1) & ~(size_t)(wc->block_size - 1);
 	data_size = wc->n_blocks * (size_t)wc->block_size;
 	if (!offset || (data_size / wc->block_size != wc->n_blocks) ||
-	    (offset + data_size < offset))
+	    (add_would_overflow(offset, data_size)))
 		goto overflow;
 	if (offset + data_size > wc->memory_map_size) {
 		ti->error = "Memory area is too small";
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 48/82] drm/nouveau/mmu: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (46 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 47/82] dm verity: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 49/82] drm/i915: " Kees Cook
                   ` (35 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Karol Herbst, Lyude Paul, Danilo Krummrich,
	David Airlie, Daniel Vetter, Dave Airlie, Ben Skeggs, dri-devel,
	nouveau, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Karol Herbst <kherbst@redhat.com>
Cc: Lyude Paul <lyude@redhat.com>
Cc: Danilo Krummrich <dakr@redhat.com>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: dri-devel@lists.freedesktop.org
Cc: nouveau@lists.freedesktop.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
index 6ca1a82ccbc1..87c0903be9a7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c
@@ -1291,7 +1291,7 @@ nvkm_vmm_pfn_map(struct nvkm_vmm *vmm, u8 shift, u64 addr, u64 size, u64 *pfn)
 
 	if (!page->shift || !IS_ALIGNED(addr, 1ULL << shift) ||
 			    !IS_ALIGNED(size, 1ULL << shift) ||
-	    addr + size < addr || addr + size > vmm->limit) {
+	    add_would_overflow(addr, size) || addr + size > vmm->limit) {
 		VMM_DEBUG(vmm, "paged map %d %d %016llx %016llx\n",
 			  shift, page->shift, addr, size);
 		return -EINVAL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 49/82] drm/i915: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (47 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 48/82] drm/nouveau/mmu: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 50/82] drm/vc4: " Kees Cook
                   ` (34 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Jani Nikula, Joonas Lahtinen, Rodrigo Vivi, Tvrtko Ursulin,
	David Airlie, Daniel Vetter, intel-gfx, dri-devel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: intel-gfx@lists.freedesktop.org
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/gpu/drm/i915/i915_vma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c
index d09aad34ba37..1a4f048a5df9 100644
--- a/drivers/gpu/drm/i915/i915_vma.c
+++ b/drivers/gpu/drm/i915/i915_vma.c
@@ -1535,7 +1535,7 @@ int i915_vma_pin_ww(struct i915_vma *vma, struct i915_gem_ww_ctx *ww,
 		goto err_remove;
 
 	/* There should only be at most 2 active bindings (user, global) */
-	GEM_BUG_ON(bound + I915_VMA_PAGES_ACTIVE < bound);
+	GEM_BUG_ON(add_would_overflow(bound, I915_VMA_PAGES_ACTIVE));
 	atomic_add(I915_VMA_PAGES_ACTIVE, &vma->pages_count);
 	list_move_tail(&vma->vm_link, &vma->vm->bound_list);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 50/82] drm/vc4: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (48 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 49/82] drm/i915: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 51/82] ext4: " Kees Cook
                   ` (33 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Maxime Ripard, Maarten Lankhorst, Thomas Zimmermann,
	David Airlie, Daniel Vetter, dri-devel, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/gpu/drm/vc4/vc4_validate.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
index 9affba9c58b3..677d9975f888 100644
--- a/drivers/gpu/drm/vc4/vc4_validate.c
+++ b/drivers/gpu/drm/vc4/vc4_validate.c
@@ -206,7 +206,7 @@ vc4_check_tex_size(struct vc4_exec_info *exec, struct drm_gem_dma_object *fbo,
 	stride = aligned_width * cpp;
 	size = stride * aligned_height;
 
-	if (size + offset < size ||
+	if (add_would_overflow(size, offset) ||
 	    size + offset > fbo->base.size) {
 		DRM_DEBUG("Overflow in %dx%d (%dx%d) fbo size (%d + %d > %zd)\n",
 			  width, height,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 51/82] ext4: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (49 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 50/82] drm/vc4: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 52/82] f2fs: " Kees Cook
                   ` (32 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Theodore Ts'o, Andreas Dilger, linux-ext4,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: linux-ext4@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/ext4/block_validity.c | 2 +-
 fs/ext4/resize.c         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
index 6fe3c941b565..85f859979d2f 100644
--- a/fs/ext4/block_validity.c
+++ b/fs/ext4/block_validity.c
@@ -302,7 +302,7 @@ int ext4_sb_block_valid(struct super_block *sb, struct inode *inode,
 	int ret = 1;
 
 	if ((start_blk <= le32_to_cpu(sbi->s_es->s_first_data_block)) ||
-	    (start_blk + count < start_blk) ||
+	    (add_would_overflow(start_blk, count)) ||
 	    (start_blk + count > ext4_blocks_count(sbi->s_es)))
 		return 0;
 
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 4d4a5a32e310..fb8d3745d031 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1871,7 +1871,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
 
 	add = EXT4_BLOCKS_PER_GROUP(sb) - last;
 
-	if (o_blocks_count + add < o_blocks_count) {
+	if (add_would_overflow(o_blocks_count, add)) {
 		ext4_warning(sb, "blocks_count overflow");
 		return -EINVAL;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 52/82] f2fs: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (50 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 51/82] ext4: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 53/82] fs: " Kees Cook
                   ` (31 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Jaegeuk Kim, Chao Yu, linux-f2fs-devel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Jaegeuk Kim <jaegeuk@kernel.org>
Cc: Chao Yu <chao@kernel.org>
Cc: linux-f2fs-devel@lists.sourceforge.net
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/f2fs/file.c   | 2 +-
 fs/f2fs/verity.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index b58ab1157b7e..6360efb98f64 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2819,7 +2819,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
 	}
 
 	ret = -EINVAL;
-	if (pos_in + len > src->i_size || pos_in + len < pos_in)
+	if (pos_in + len > src->i_size || add_would_overflow(pos_in, len))
 		goto out_unlock;
 	if (len == 0)
 		olen = len = src->i_size - pos_in;
diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
index 4fc95f353a7a..b641cb8d75e8 100644
--- a/fs/f2fs/verity.c
+++ b/fs/f2fs/verity.c
@@ -237,7 +237,7 @@ static int f2fs_get_verity_descriptor(struct inode *inode, void *buf,
 	pos = le64_to_cpu(dloc.pos);
 
 	/* Get the descriptor */
-	if (pos + size < pos || pos + size > inode->i_sb->s_maxbytes ||
+	if (add_would_overflow(pos, size) || pos + size > inode->i_sb->s_maxbytes ||
 	    pos < f2fs_verity_metadata_pos(inode) || size > INT_MAX) {
 		f2fs_warn(F2FS_I_SB(inode), "invalid verity xattr");
 		f2fs_handle_error(F2FS_I_SB(inode),
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 53/82] fs: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (51 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 52/82] f2fs: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23 18:02   ` Jan Kara
  2024-01-23  0:27 ` [PATCH 54/82] hpfs: " Kees Cook
                   ` (30 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Alexander Viro, Christian Brauner, Jan Kara,
	linux-fsdevel, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/remap_range.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/remap_range.c b/fs/remap_range.c
index f8c1120b8311..15e91bf2c5e3 100644
--- a/fs/remap_range.c
+++ b/fs/remap_range.c
@@ -45,7 +45,7 @@ static int generic_remap_checks(struct file *file_in, loff_t pos_in,
 		return -EINVAL;
 
 	/* Ensure offsets don't wrap. */
-	if (pos_in + count < pos_in || pos_out + count < pos_out)
+	if (add_would_overflow(pos_in, count) || add_would_overflow(pos_out, count))
 		return -EINVAL;
 
 	size_in = i_size_read(inode_in);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 54/82] hpfs: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (52 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 53/82] fs: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 55/82] kasan: " Kees Cook
                   ` (29 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Mikulas Patocka, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/hpfs/alloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/hpfs/alloc.c b/fs/hpfs/alloc.c
index 66617b1557c6..e9c7cc6033b5 100644
--- a/fs/hpfs/alloc.c
+++ b/fs/hpfs/alloc.c
@@ -99,7 +99,7 @@ static int chk_if_allocated(struct super_block *s, secno sec, char *msg)
 	
 int hpfs_chk_sectors(struct super_block *s, secno start, int len, char *msg)
 {
-	if (start + len < start || start < 0x12 ||
+	if (add_would_overflow(start, len) || start < 0x12 ||
 	    start + len > hpfs_sb(s)->sb_fs_size) {
 	    	hpfs_error(s, "sector(s) '%s' badly placed at %08x", msg, start);
 		return 1;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 55/82] kasan: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (53 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 54/82] hpfs: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-25 22:35   ` Andrey Konovalov
  2024-01-23  0:27 ` [PATCH 56/82] usercopy: " Kees Cook
                   ` (28 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Andrey Ryabinin, Alexander Potapenko,
	Andrey Konovalov, Dmitry Vyukov, Vincenzo Frascino,
	Andrew Morton, kasan-dev, linux-mm, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: kasan-dev@googlegroups.com
Cc: linux-mm@kvack.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 mm/kasan/generic.c | 2 +-
 mm/kasan/sw_tags.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index df6627f62402..f9bc29ae09bd 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -171,7 +171,7 @@ static __always_inline bool check_region_inline(const void *addr,
 	if (unlikely(size == 0))
 		return true;
 
-	if (unlikely(addr + size < addr))
+	if (unlikely(add_would_overflow(addr, size)))
 		return !kasan_report(addr, size, write, ret_ip);
 
 	if (unlikely(!addr_has_metadata(addr)))
diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c
index 220b5d4c6876..79a3bbd66c32 100644
--- a/mm/kasan/sw_tags.c
+++ b/mm/kasan/sw_tags.c
@@ -80,7 +80,7 @@ bool kasan_check_range(const void *addr, size_t size, bool write,
 	if (unlikely(size == 0))
 		return true;
 
-	if (unlikely(addr + size < addr))
+	if (unlikely(add_would_overflow(addr, size)))
 		return !kasan_report(addr, size, write, ret_ip);
 
 	tag = get_tag((const void *)addr);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 56/82] usercopy: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (54 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 55/82] kasan: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 57/82] KVM: arm64: vgic-v3: " Kees Cook
                   ` (27 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Gustavo A. R. Silva, Andrew Morton, linux-mm,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Kees Cook <keescook@chromium.org>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-hardening@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: Gustavo A. R. Silva <gustavoars@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 mm/usercopy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/usercopy.c b/mm/usercopy.c
index 83c164aba6e0..5141c4402903 100644
--- a/mm/usercopy.c
+++ b/mm/usercopy.c
@@ -151,7 +151,7 @@ static inline void check_bogus_address(const unsigned long ptr, unsigned long n,
 				       bool to_user)
 {
 	/* Reject if object wraps past end of memory. */
-	if (ptr + (n - 1) < ptr)
+	if (add_would_overflow(ptr, (n - 1)))
 		usercopy_abort("wrapped address", NULL, to_user, 0, ptr + n);
 
 	/* Reject if NULL or ZERO-allocation. */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 57/82] KVM: arm64: vgic-v3: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (55 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 56/82] usercopy: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23 10:50   ` Marc Zyngier
  2024-01-24 15:12   ` Eric Auger
  2024-01-23  0:27 ` [PATCH 58/82] s390/mm: " Kees Cook
                   ` (26 subsequent siblings)
  83 siblings, 2 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Marc Zyngier, Oliver Upton, James Morse,
	Suzuki K Poulose, Zenghui Yu, Catalin Marinas, Will Deacon,
	Eric Auger, linux-arm-kernel, kvmarm, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: James Morse <james.morse@arm.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Zenghui Yu <yuzenghui@huawei.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Eric Auger <eric.auger@redhat.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: kvmarm@lists.linux.dev
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arm64/kvm/vgic/vgic-mmio-v3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
index c15ee1df036a..860b774c0c13 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -863,7 +863,7 @@ static int vgic_v3_alloc_redist_region(struct kvm *kvm, uint32_t index,
 	int ret;
 
 	/* cross the end of memory ? */
-	if (base + size < base)
+	if (add_would_overflow(base, size))
 		return -EINVAL;
 
 	if (list_empty(rd_regions)) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 58/82] s390/mm: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (56 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 57/82] KVM: arm64: vgic-v3: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 59/82] lib/scatterlist: " Kees Cook
                   ` (25 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Christian Borntraeger, Janosch Frank,
	Claudio Imbrenda, David Hildenbrand, Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik, Sven Schnelle,
	kvm, linux-s390, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: kvm@vger.kernel.org
Cc: linux-s390@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/s390/mm/gmap.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c
index 6f96b5a71c63..977b61ab59f2 100644
--- a/arch/s390/mm/gmap.c
+++ b/arch/s390/mm/gmap.c
@@ -411,7 +411,7 @@ int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len)
 	BUG_ON(gmap_is_shadow(gmap));
 	if ((to | len) & (PMD_SIZE - 1))
 		return -EINVAL;
-	if (len == 0 || to + len < to)
+	if (len == 0 || add_would_overflow(to, len))
 		return -EINVAL;
 
 	flush = 0;
@@ -443,7 +443,7 @@ int gmap_map_segment(struct gmap *gmap, unsigned long from,
 	BUG_ON(gmap_is_shadow(gmap));
 	if ((from | to | len) & (PMD_SIZE - 1))
 		return -EINVAL;
-	if (len == 0 || from + len < from || to + len < to ||
+	if (len == 0 || add_would_overflow(from, len) || add_would_overflow(to, len) ||
 	    from + len - 1 > TASK_SIZE_MAX || to + len - 1 > gmap->asce_end)
 		return -EINVAL;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 59/82] lib/scatterlist: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (57 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 58/82] s390/mm: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 60/82] powerpc: " Kees Cook
                   ` (24 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Andrew Morton, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/scatterlist.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index 68b45c82c37a..121905119bbc 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -624,7 +624,7 @@ struct scatterlist *sgl_alloc_order(unsigned long long length,
 	nalloc = nent;
 	if (chainable) {
 		/* Check for integer overflow */
-		if (nalloc + 1 < nalloc)
+		if (add_would_overflow(nalloc, 1))
 			return NULL;
 		nalloc++;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 60/82] powerpc: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (58 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 59/82] lib/scatterlist: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-02-12  5:38   ` Michael Ellerman
  2024-01-23  0:27 ` [PATCH 61/82] scsi: mpt3sas: " Kees Cook
                   ` (23 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Michael Ellerman, Nicholas Piggin, Christophe Leroy,
	Aneesh Kumar K.V, Naveen N. Rao, Mahesh Salgaonkar, Vasant Hegde,
	dingsenjie, linuxppc-dev, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@kernel.org>
Cc: "Naveen N. Rao" <naveen.n.rao@linux.ibm.com>
Cc: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Cc: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Cc: dingsenjie <dingsenjie@yulong.com>
Cc: linuxppc-dev@lists.ozlabs.org
Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Cc: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/powerpc/platforms/powernv/opal-prd.c | 2 +-
 arch/powerpc/xmon/xmon.c                  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-prd.c b/arch/powerpc/platforms/powernv/opal-prd.c
index b66b06efcef1..eaf95dc82925 100644
--- a/arch/powerpc/platforms/powernv/opal-prd.c
+++ b/arch/powerpc/platforms/powernv/opal-prd.c
@@ -51,7 +51,7 @@ static bool opal_prd_range_is_valid(uint64_t addr, uint64_t size)
 	struct device_node *parent, *node;
 	bool found;
 
-	if (addr + size < addr)
+	if (add_would_overflow(addr, size))
 		return false;
 
 	parent = of_find_node_by_path("/reserved-memory");
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index b3b94cd37713..b91fdda49434 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -3252,7 +3252,7 @@ memzcan(void)
 		} else if (!ok && ook)
 			printf("%.8lx\n", a - mskip);
 		ook = ok;
-		if (a + mskip < a)
+		if (add_would_overflow(a, mskip))
 			break;
 	}
 	if (ook)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 61/82] scsi: mpt3sas: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (59 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 60/82] powerpc: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 62/82] mwifiex: pcie: " Kees Cook
                   ` (22 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Sathya Prakash, Sreekanth Reddy,
	Suganath Prabu Subramani, James E.J. Bottomley,
	Martin K. Petersen, MPT-FusionLinux.pdl, linux-scsi,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Sathya Prakash <sathya.prakash@broadcom.com>
Cc: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Cc: Suganath Prabu Subramani <suganath-prabu.subramani@broadcom.com>
Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: MPT-FusionLinux.pdl@broadcom.com
Cc: linux-scsi@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 147cb7088d55..b36a9188720f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -2382,7 +2382,7 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
 			    karg.bytes_to_read));
 
 	/* Truncate data on requests that are too large */
-	if ((diag_data + karg.bytes_to_read < diag_data) ||
+	if ((add_would_overflow(diag_data, karg.bytes_to_read)) ||
 	    (diag_data + karg.bytes_to_read > request_data + request_size))
 		copy_size = request_size - karg.starting_offset;
 	else
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 62/82] mwifiex: pcie: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (60 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 61/82] scsi: mpt3sas: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  6:36   ` Kalle Valo
  2024-01-23  0:27 ` [PATCH 63/82] mm: " Kees Cook
                   ` (21 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Brian Norris, Kalle Valo, Jonas Dreßler,
	Dmitry Antipov, Tsuchiya Yuto, linux-wireless,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Brian Norris <briannorris@chromium.org>
Cc: Kalle Valo <kvalo@kernel.org>
Cc: "Jonas Dreßler" <verdre@v0yd.nl>
Cc: Dmitry Antipov <dmantipov@yandex.ru>
Cc: Tsuchiya Yuto <kitakar@gmail.com>
Cc: linux-wireless@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 5f997becdbaa..e69347e65f0e 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -2086,7 +2086,7 @@ static int mwifiex_extract_wifi_fw(struct mwifiex_adapter *adapter,
 
 		switch (dnld_cmd) {
 		case MWIFIEX_FW_DNLD_CMD_1:
-			if (offset + data_len < data_len) {
+			if (add_would_overflow(data_len, offset)) {
 				mwifiex_dbg(adapter, ERROR, "bad FW parse\n");
 				ret = -1;
 				goto done;
@@ -2110,7 +2110,7 @@ static int mwifiex_extract_wifi_fw(struct mwifiex_adapter *adapter,
 		case MWIFIEX_FW_DNLD_CMD_5:
 			first_cmd = true;
 			/* Check for integer overflow */
-			if (offset + data_len < data_len) {
+			if (add_would_overflow(data_len, offset)) {
 				mwifiex_dbg(adapter, ERROR, "bad FW parse\n");
 				ret = -1;
 				goto done;
@@ -2120,7 +2120,7 @@ static int mwifiex_extract_wifi_fw(struct mwifiex_adapter *adapter,
 		case MWIFIEX_FW_DNLD_CMD_6:
 			first_cmd = true;
 			/* Check for integer overflow */
-			if (offset + data_len < data_len) {
+			if (add_would_overflow(data_len, offset)) {
 				mwifiex_dbg(adapter, ERROR, "bad FW parse\n");
 				ret = -1;
 				goto done;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 63/82] mm: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (61 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 62/82] mwifiex: pcie: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 64/82] netfilter: " Kees Cook
                   ` (20 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Andrew Morton, Shuah Khan, linux-mm, linux-kselftest,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: linux-mm@kvack.org
Cc: linux-kselftest@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 mm/memory.c | 4 ++--
 mm/mmap.c   | 2 +-
 mm/mremap.c | 2 +-
 mm/nommu.c  | 4 ++--
 mm/util.c   | 2 +-
 5 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/mm/memory.c b/mm/memory.c
index 7e1f4849463a..d47acdff7af3 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2559,7 +2559,7 @@ int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long
 	unsigned long vm_len, pfn, pages;
 
 	/* Check that the physical memory area passed in looks valid */
-	if (start + len < start)
+	if (add_would_overflow(start, len))
 		return -EINVAL;
 	/*
 	 * You *really* shouldn't map things that aren't page-aligned,
@@ -2569,7 +2569,7 @@ int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long
 	len += start & ~PAGE_MASK;
 	pfn = start >> PAGE_SHIFT;
 	pages = (len + ~PAGE_MASK) >> PAGE_SHIFT;
-	if (pfn + pages < pfn)
+	if (add_would_overflow(pfn, pages))
 		return -EINVAL;
 
 	/* We start the mapping 'vm_pgoff' pages into the area */
diff --git a/mm/mmap.c b/mm/mmap.c
index b78e83d351d2..16501fcaf511 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -3023,7 +3023,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
 		return ret;
 
 	/* Does pgoff wrap? */
-	if (pgoff + (size >> PAGE_SHIFT) < pgoff)
+	if (add_would_overflow(pgoff, (size >> PAGE_SHIFT)))
 		return ret;
 
 	if (mmap_write_lock_killable(mm))
diff --git a/mm/mremap.c b/mm/mremap.c
index 38d98465f3d8..efa27019a05d 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -848,7 +848,7 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
 	/* Need to be careful about a growing mapping */
 	pgoff = (addr - vma->vm_start) >> PAGE_SHIFT;
 	pgoff += vma->vm_pgoff;
-	if (pgoff + (new_len >> PAGE_SHIFT) < pgoff)
+	if (add_would_overflow(pgoff, (new_len >> PAGE_SHIFT)))
 		return ERR_PTR(-EINVAL);
 
 	if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP))
diff --git a/mm/nommu.c b/mm/nommu.c
index b6dc558d3144..299bcfe19eed 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -202,7 +202,7 @@ EXPORT_SYMBOL(vmalloc_to_pfn);
 long vread_iter(struct iov_iter *iter, const char *addr, size_t count)
 {
 	/* Don't allow overflow */
-	if ((unsigned long) addr + count < count)
+	if (add_would_overflow(count, (unsigned long)addr))
 		count = -(unsigned long) addr;
 
 	return copy_to_iter(addr, count, iter);
@@ -1705,7 +1705,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
 {
 	struct mm_struct *mm;
 
-	if (addr + len < addr)
+	if (add_would_overflow(addr, len))
 		return 0;
 
 	mm = get_task_mm(tsk);
diff --git a/mm/util.c b/mm/util.c
index 5a6a9802583b..e6beeb23b48b 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -567,7 +567,7 @@ unsigned long vm_mmap(struct file *file, unsigned long addr,
 	unsigned long len, unsigned long prot,
 	unsigned long flag, unsigned long offset)
 {
-	if (unlikely(offset + PAGE_ALIGN(len) < offset))
+	if (unlikely(add_would_overflow(offset, PAGE_ALIGN(len))))
 		return -EINVAL;
 	if (unlikely(offset_in_page(offset)))
 		return -EINVAL;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 64/82] netfilter: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (62 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 63/82] mm: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23 18:03   ` Florian Westphal
  2024-01-23  0:27 ` [PATCH 65/82] nios2: " Kees Cook
                   ` (19 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	netfilter-devel, coreteam, netdev, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: Jozsef Kadlecsik <kadlec@netfilter.org>
Cc: Florian Westphal <fw@strlen.de>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: netfilter-devel@vger.kernel.org
Cc: coreteam@netfilter.org
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 net/netfilter/xt_u32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
index 117d4615d668..8623fe2d97e9 100644
--- a/net/netfilter/xt_u32.c
+++ b/net/netfilter/xt_u32.c
@@ -58,11 +58,11 @@ static bool u32_match_it(const struct xt_u32 *data,
 				val >>= number;
 				break;
 			case XT_U32_AT:
-				if (at + val < at)
+				if (add_would_overflow(at, val))
 					return false;
 				at += val;
 				pos = number;
-				if (at + 4 < at || skb->len < at + 4 ||
+				if (add_would_overflow(at, 4) || skb->len < at + 4 ||
 				    pos > skb->len - at - 4)
 					return false;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 65/82] nios2: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (63 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 64/82] netfilter: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23 13:15   ` Dinh Nguyen
  2024-01-23  0:27 ` [PATCH 66/82] fs/ntfs3: " Kees Cook
                   ` (18 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Dinh Nguyen, Jann Horn, Ley Foon Tan,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Dinh Nguyen <dinguyen@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Ley Foon Tan <ley.foon.tan@intel.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/nios2/kernel/sys_nios2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/nios2/kernel/sys_nios2.c b/arch/nios2/kernel/sys_nios2.c
index b1ca85699952..df53efdc96e3 100644
--- a/arch/nios2/kernel/sys_nios2.c
+++ b/arch/nios2/kernel/sys_nios2.c
@@ -32,7 +32,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len,
 		return -EINVAL;
 
 	/* Check for overflow */
-	if (addr + len < addr)
+	if (add_would_overflow(addr, len))
 		return -EFAULT;
 
 	if (mmap_read_lock_killable(mm))
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 66/82] fs/ntfs3: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (64 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 65/82] nios2: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 67/82] ocfs2: " Kees Cook
                   ` (17 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Konstantin Komarov, ntfs3, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Cc: ntfs3@lists.linux.dev
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/ntfs3/record.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
index 53629b1f65e9..8cd738c1dbe6 100644
--- a/fs/ntfs3/record.c
+++ b/fs/ntfs3/record.c
@@ -235,7 +235,7 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
 		}
 
 		/* Overflow check. */
-		if (off + asize < off)
+		if (add_would_overflow(off, asize))
 			return NULL;
 
 		prev_type = le32_to_cpu(attr->type);
@@ -266,7 +266,7 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
 		return NULL;
 
 	/* Check overflow and boundary. */
-	if (off + asize < off || off + asize > used)
+	if (add_would_overflow(off, asize) || off + asize > used)
 		return NULL;
 
 	/* Check size of attribute. */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 67/82] ocfs2: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (65 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 66/82] fs/ntfs3: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 68/82] PCI: " Kees Cook
                   ` (16 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Mark Fasheh, Joel Becker, Joseph Qi, ocfs2-devel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: ocfs2-devel@lists.linux.dev
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/ocfs2/resize.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c
index d65d43c61857..5cc83e1d54a7 100644
--- a/fs/ocfs2/resize.c
+++ b/fs/ocfs2/resize.c
@@ -423,7 +423,7 @@ static int ocfs2_verify_group_and_input(struct inode *inode,
 	else if (next_free != cl_count && next_free != input->chain)
 		mlog(ML_ERROR,
 		     "the add group should be in chain %u\n", next_free);
-	else if (total_clusters + input->clusters < total_clusters)
+	else if (add_would_overflow(total_clusters, input->clusters))
 		mlog(ML_ERROR, "add group's clusters overflow.\n");
 	else if (input->clusters > cl_cpg)
 		mlog(ML_ERROR, "the cluster exceeds the maximum of a group\n");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 68/82] PCI: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (66 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 67/82] ocfs2: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 69/82] perf tools: " Kees Cook
                   ` (15 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Bjorn Helgaas, linux-pci, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/pci/pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d8f11a078924..ebf6d9064a59 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4251,7 +4251,7 @@ int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
 #ifdef PCI_IOBASE
 	struct logic_pio_hwaddr *range;
 
-	if (!size || addr + size < addr)
+	if (!size || add_would_overflow(addr, size))
 		return -EINVAL;
 
 	range = kzalloc(sizeof(*range), GFP_ATOMIC);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 69/82] perf tools: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (67 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 68/82] PCI: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  6:21   ` Adrian Hunter
  2024-01-23  0:27 ` [PATCH 70/82] remoteproc: " Kees Cook
                   ` (14 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, Adrian Hunter, John Garry, Fangrui Song,
	linux-perf-users, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: John Garry <john.garry@huawei.com>
Cc: Fangrui Song <maskray@google.com>
Cc: linux-perf-users@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 tools/perf/util/dso.c                    | 2 +-
 tools/perf/util/unwind-libdw.c           | 2 +-
 tools/perf/util/unwind-libunwind-local.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 22fd5fa806ed..470a86f1cdfd 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -1122,7 +1122,7 @@ static ssize_t data_read_write_offset(struct dso *dso, struct machine *machine,
 	if (offset > dso->data.file_size)
 		return -1;
 
-	if (offset + size < offset)
+	if (add_would_overflow(offset, size))
 		return -1;
 
 	return cached_io(dso, machine, offset, data, size, out);
diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
index 6013335a8dae..45a89cbb2c8d 100644
--- a/tools/perf/util/unwind-libdw.c
+++ b/tools/perf/util/unwind-libdw.c
@@ -198,7 +198,7 @@ static bool memory_read(Dwfl *dwfl __maybe_unused, Dwarf_Addr addr, Dwarf_Word *
 	end = start + stack->size;
 
 	/* Check overflow. */
-	if (addr + sizeof(Dwarf_Word) < addr)
+	if (add_would_overflow(addr, sizeof(Dwarf_Word)))
 		return false;
 
 	if (addr < start || addr + sizeof(Dwarf_Word) > end) {
diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
index dac536e28360..ac71cc7f53b9 100644
--- a/tools/perf/util/unwind-libunwind-local.c
+++ b/tools/perf/util/unwind-libunwind-local.c
@@ -587,7 +587,7 @@ static int access_mem(unw_addr_space_t __maybe_unused as,
 	end = start + stack->size;
 
 	/* Check overflow. */
-	if (addr + sizeof(unw_word_t) < addr)
+	if (add_would_overflow(addr, sizeof(unw_word_t)))
 		return -EINVAL;
 
 	if (addr < start || addr + sizeof(unw_word_t) >= end) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 70/82] remoteproc: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (68 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 69/82] perf tools: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-02-06 18:55   ` Bjorn Andersson
  2024-01-23  0:27 ` [PATCH 71/82] s390/mm: " Kees Cook
                   ` (13 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Bjorn Andersson, Mathieu Poirier, linux-remoteproc,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Bjorn Andersson <andersson@kernel.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: linux-remoteproc@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/remoteproc/pru_rproc.c             | 2 +-
 drivers/remoteproc/remoteproc_elf_loader.c | 2 +-
 drivers/remoteproc/remoteproc_virtio.c     | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
index 327f0c7ee3d6..834249ee3dd3 100644
--- a/drivers/remoteproc/pru_rproc.c
+++ b/drivers/remoteproc/pru_rproc.c
@@ -893,7 +893,7 @@ pru_rproc_find_interrupt_map(struct device *dev, const struct firmware *fw)
 			continue;
 
 		/* make sure we have the entire irq map */
-		if (offset + size > fw->size || offset + size < size) {
+		if (offset + size > fw->size || add_would_overflow(size, offset)) {
 			dev_err(dev, ".pru_irq_map section truncated\n");
 			return ERR_PTR(-EINVAL);
 		}
diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
index 94177e416047..b9231cf46d68 100644
--- a/drivers/remoteproc/remoteproc_elf_loader.c
+++ b/drivers/remoteproc/remoteproc_elf_loader.c
@@ -278,7 +278,7 @@ find_table(struct device *dev, const struct firmware *fw)
 		table = (struct resource_table *)(elf_data + offset);
 
 		/* make sure we have the entire table */
-		if (offset + size > fw_size || offset + size < size) {
+		if (offset + size > fw_size || add_would_overflow(size, offset)) {
 			dev_err(dev, "resource table truncated\n");
 			return NULL;
 		}
diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
index 83d76915a6ad..58742c666e35 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -298,7 +298,7 @@ static void rproc_virtio_get(struct virtio_device *vdev, unsigned int offset,
 	rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;
 	cfg = &rsc->vring[rsc->num_of_vrings];
 
-	if (offset + len > rsc->config_len || offset + len < len) {
+	if (offset + len > rsc->config_len || add_would_overflow(len, offset)) {
 		dev_err(&vdev->dev, "rproc_virtio_get: access out of bounds\n");
 		return;
 	}
@@ -316,7 +316,7 @@ static void rproc_virtio_set(struct virtio_device *vdev, unsigned int offset,
 	rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;
 	cfg = &rsc->vring[rsc->num_of_vrings];
 
-	if (offset + len > rsc->config_len || offset + len < len) {
+	if (offset + len > rsc->config_len || add_would_overflow(len, offset)) {
 		dev_err(&vdev->dev, "rproc_virtio_set: access out of bounds\n");
 		return;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 71/82] s390/mm: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (69 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 70/82] remoteproc: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 72/82] scsi: sd_zbc: " Kees Cook
                   ` (12 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Sven Schnelle, linux-s390,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: linux-s390@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/s390/mm/vmem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index 186a020857cf..98a7f08141f0 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -538,7 +538,7 @@ int vmem_add_mapping(unsigned long start, unsigned long size)
 
 	if (start < range.start ||
 	    start + size > range.end + 1 ||
-	    start + size < start)
+	    add_would_overflow(start, size))
 		return -ERANGE;
 
 	mutex_lock(&vmem_mutex);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 72/82] scsi: sd_zbc: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (70 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 71/82] s390/mm: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 73/82] sh: " Kees Cook
                   ` (11 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, James E.J. Bottomley, Martin K. Petersen, linux-scsi,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: "James E.J. Bottomley" <jejb@linux.ibm.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: linux-scsi@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/scsi/sd_zbc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index 26af5ab7d7c1..2c377e4cdb2b 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -295,7 +295,7 @@ int sd_zbc_report_zones(struct gendisk *disk, sector_t sector,
 			    (lba < start_lba ||
 			     lba >= start_lba + zone_length)) ||
 			    (zone_idx > 0 && start_lba != lba) ||
-			    start_lba + zone_length < start_lba) {
+			    add_would_overflow(start_lba, zone_length)) {
 				sd_printk(KERN_ERR, sdkp,
 					  "Zone %d at LBA %llu is invalid: %llu + %llu\n",
 					  zone_idx, lba, start_lba, zone_length);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 73/82] sh: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (71 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 72/82] scsi: sd_zbc: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  7:31   ` John Paul Adrian Glaubitz
  2024-01-23  0:27 ` [PATCH 74/82] ARC: dw2 unwind: " Kees Cook
                   ` (10 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Yoshinori Sato, Rich Felker,
	John Paul Adrian Glaubitz, linux-sh, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: linux-sh@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/sh/kernel/sys_sh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index a5a7b33ed81a..e390caeb8c00 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -66,7 +66,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
 	 * Verify that the specified address region actually belongs
 	 * to this process.
 	 */
-	if (addr + len < addr)
+	if (add_would_overflow(addr, len))
 		return -EFAULT;
 
 	mmap_read_lock(current->mm);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 74/82] ARC: dw2 unwind: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (72 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 73/82] sh: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 75/82] timekeeping: " Kees Cook
                   ` (9 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Vineet Gupta, Luis Chamberlain, dean.yang_cp,
	Song Liu, Yihao Han, linux-snps-arc, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Vineet Gupta <vgupta@kernel.org>
Cc: Luis Chamberlain <mcgrof@kernel.org>
Cc: "dean.yang_cp" <yangdianqing@yulong.com>
Cc: Song Liu <song@kernel.org>
Cc: Yihao Han <hanyihao@vivo.com>
Cc: linux-snps-arc@lists.infradead.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 arch/arc/kernel/unwind.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c
index 8924fa2a8f29..649b56204580 100644
--- a/arch/arc/kernel/unwind.c
+++ b/arch/arc/kernel/unwind.c
@@ -1278,7 +1278,7 @@ int arc_unwind(struct unwind_frame_info *frame)
 			if ((state.regs[i].value * state.dataAlign)
 			    % sizeof(unsigned long)
 			    || addr < startLoc
-			    || addr + sizeof(unsigned long) < addr
+			    || add_would_overflow(addr, sizeof(unsigned long))
 			    || addr + sizeof(unsigned long) > endLoc)
 					return -EIO;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 75/82] timekeeping: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (73 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 74/82] ARC: dw2 unwind: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  1:06   ` John Stultz
  2024-01-24 19:34   ` Thomas Gleixner
  2024-01-23  0:27 ` [PATCH 76/82] udf: " Kees Cook
                   ` (8 subsequent siblings)
  83 siblings, 2 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, John Stultz, Thomas Gleixner, Stephen Boyd,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: John Stultz <jstultz@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 kernel/time/timekeeping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 266d02809dbb..2fc7cf16584c 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1984,7 +1984,7 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
 	 * Which simplifies to:
 	 *	xtime_nsec -= offset
 	 */
-	if ((mult_adj > 0) && (tk->tkr_mono.mult + mult_adj < mult_adj)) {
+	if ((mult_adj > 0) && (add_would_overflow(mult_adj, tk->tkr_mono.mult))) {
 		/* NTP adjustment caused clocksource mult overflow */
 		WARN_ON_ONCE(1);
 		return;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 76/82] udf: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (74 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 75/82] timekeeping: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23 17:14   ` Jan Kara
  2024-01-23  0:27 ` [PATCH 77/82] virtio: " Kees Cook
                   ` (7 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Jan Kara, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Jan Kara <jack@suse.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 fs/udf/balloc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index ab3ffc355949..5c88300c3de7 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -139,7 +139,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
 
 	mutex_lock(&sbi->s_alloc_mutex);
 	partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-	if (bloc->logicalBlockNum + count < count ||
+	if (add_would_overflow(count, bloc->logicalBlockNum) ||
 	    (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
 		udf_debug("%u < %d || %u + %u > %u\n",
 			  bloc->logicalBlockNum, 0,
@@ -390,7 +390,7 @@ static void udf_table_free_blocks(struct super_block *sb,
 
 	mutex_lock(&sbi->s_alloc_mutex);
 	partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
-	if (bloc->logicalBlockNum + count < count ||
+	if (add_would_overflow(count, bloc->logicalBlockNum) ||
 	    (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
 		udf_debug("%u < %d || %u + %u > %u\n",
 			  bloc->logicalBlockNum, 0,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 77/82] virtio: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (75 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 76/82] udf: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-26 19:33   ` Eugenio Perez Martin
  2024-01-23  0:27 ` [PATCH 78/82] mm/vmalloc: " Kees Cook
                   ` (6 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	virtualization, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Cc: virtualization@lists.linux.dev
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/virtio/virtio_pci_modern_dev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c
index 0d3dbfaf4b23..710d3bd45b4f 100644
--- a/drivers/virtio/virtio_pci_modern_dev.c
+++ b/drivers/virtio/virtio_pci_modern_dev.c
@@ -59,7 +59,7 @@ vp_modern_map_capability(struct virtio_pci_modern_device *mdev, int off,
 
 	length -= start;
 
-	if (start + offset < offset) {
+	if (add_would_overflow(offset, start)) {
 		dev_err(&dev->dev,
 			"virtio_pci: map wrap-around %u+%u\n",
 			start, offset);
@@ -81,7 +81,7 @@ vp_modern_map_capability(struct virtio_pci_modern_device *mdev, int off,
 	if (len)
 		*len = length;
 
-	if (minlen + offset < minlen ||
+	if (add_would_overflow(minlen, offset) ||
 	    minlen + offset > pci_resource_len(dev, bar)) {
 		dev_err(&dev->dev,
 			"virtio_pci: map virtio %zu@%u "
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 78/82] mm/vmalloc: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (76 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 77/82] virtio: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-30 18:56   ` Lorenzo Stoakes
  2024-01-23  0:27 ` [PATCH 79/82] staging: vme_user: " Kees Cook
                   ` (5 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Andrew Morton, Uladzislau Rezki, Christoph Hellwig,
	Lorenzo Stoakes, linux-mm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Uladzislau Rezki <urezki@gmail.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Lorenzo Stoakes <lstoakes@gmail.com>
Cc: linux-mm@kvack.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 mm/vmalloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 7932ac99e9d3..3d73f2ac6957 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3750,7 +3750,7 @@ long vread_iter(struct iov_iter *iter, const char *addr, size_t count)
 	addr = kasan_reset_tag(addr);
 
 	/* Don't allow overflow */
-	if ((unsigned long) addr + count < count)
+	if (add_would_overflow(count, (unsigned long)addr))
 		count = -(unsigned long) addr;
 
 	remains = count;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 79/82] staging: vme_user: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (77 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 78/82] mm/vmalloc: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 80/82] xen-netback: " Kees Cook
                   ` (4 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Martyn Welch, Manohar Vanga, Greg Kroah-Hartman,
	Soumya Negi, Alexon Oliveira, linux-staging, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Martyn Welch <martyn@welchs.me.uk>
Cc: Manohar Vanga <manohar.vanga@gmail.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Soumya Negi <soumya.negi97@gmail.com>
Cc: Alexon Oliveira <alexondunkan@gmail.com>
Cc: linux-staging@lists.linux.dev
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/staging/vme_user/vme.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c
index e9461a7a7ab8..a0acf2a295cd 100644
--- a/drivers/staging/vme_user/vme.c
+++ b/drivers/staging/vme_user/vme.c
@@ -165,7 +165,7 @@ int vme_check_window(struct vme_bridge *bridge, u32 aspace,
 {
 	int retval = 0;
 
-	if (vme_base + size < size)
+	if (add_would_overflow(size, vme_base))
 		return -EINVAL;
 
 	switch (aspace) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 80/82] xen-netback: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (78 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 79/82] staging: vme_user: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  7:55   ` Jan Beulich
  2024-01-23  0:27 ` [PATCH 81/82] lib: zstd: " Kees Cook
                   ` (3 subsequent siblings)
  83 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Wei Liu, Paul Durrant, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, xen-devel, netdev,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Wei Liu <wei.liu@kernel.org>
Cc: Paul Durrant <paul@xen.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: xen-devel@lists.xenproject.org
Cc: netdev@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 drivers/net/xen-netback/hash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c
index ff96f22648ef..69b03b4feba9 100644
--- a/drivers/net/xen-netback/hash.c
+++ b/drivers/net/xen-netback/hash.c
@@ -345,7 +345,7 @@ u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len,
 		.flags = GNTCOPY_source_gref
 	}};
 
-	if ((off + len < off) || (off + len > vif->hash.size) ||
+	if ((add_would_overflow(off, len)) || (off + len > vif->hash.size) ||
 	    len > XEN_PAGE_SIZE / sizeof(*mapping))
 		return XEN_NETIF_CTRL_STATUS_INVALID_PARAMETER;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 81/82] lib: zstd: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (79 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 80/82] xen-netback: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  0:27 ` [PATCH 82/82] mqueue: " Kees Cook
                   ` (2 subsequent siblings)
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Nick Terrell, Paul Jones, Sedat Dilek,
	Oleksandr Natalenko, Xin Gao, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Switch to a more regular type for a 64-bit value and refactor the
open-coded wrap-around addition test to use subtraction from the type max
(since add_would_overflow() may not be defined in early boot code). This
paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Nick Terrell <terrelln@fb.com>
Cc: Paul Jones <paul@pauljones.id.au>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
Cc: Xin Gao <gaoxin@cdjrlc.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 lib/zstd/decompress/zstd_decompress.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/zstd/decompress/zstd_decompress.c b/lib/zstd/decompress/zstd_decompress.c
index 6b3177c94711..2c87cf702ad6 100644
--- a/lib/zstd/decompress/zstd_decompress.c
+++ b/lib/zstd/decompress/zstd_decompress.c
@@ -585,7 +585,7 @@ ZSTDLIB_API size_t ZSTD_readSkippableFrame(void* dst, size_t dstCapacity, unsign
  *  @return : decompressed size of the frames contained */
 unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
 {
-    unsigned long long totalDstSize = 0;
+    U64 totalDstSize = 0;
 
     while (srcSize >= ZSTD_startingInputLength(ZSTD_f_zstd1)) {
         U32 const magicNumber = MEM_readLE32(src);
@@ -606,7 +606,7 @@ unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
             if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
 
             /* check for overflow */
-            if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
+            if (U64_MAX - totalDstSize < ret) return ZSTD_CONTENTSIZE_ERROR;
             totalDstSize += ret;
         }
         {   size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* [PATCH 82/82] mqueue: Refactor intentional wrap-around test
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (80 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 81/82] lib: zstd: " Kees Cook
@ 2024-01-23  0:27 ` Kees Cook
  2024-01-23  2:22 ` [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kent Overstreet
  2024-01-23  9:46 ` Mark Rutland
  83 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  0:27 UTC (permalink / raw)
  To: linux-hardening
  Cc: Kees Cook, Christian Brauner, Andrew Morton, Eric W. Biederman,
	Dave Chinner, Alexey Gladkov, Jeff Layton, Waiman Long,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

In an effort to separate intentional arithmetic wrap-around from
unexpected wrap-around, we need to refactor places that depend on this
kind of math. One of the most common code patterns of this is:

	VAR + value < VAR

Notably, this is considered "undefined behavior" for signed and pointer
types, which the kernel works around by using the -fno-strict-overflow
option in the build[1] (which used to just be -fwrapv). Regardless, we
want to get the kernel source to the position where we can meaningfully
instrument arithmetic wrap-around conditions and catch them when they
are unexpected, regardless of whether they are signed[2], unsigned[3],
or pointer[4] types.

Refactor open-coded wrap-around addition test to use add_would_overflow().
This paves the way to enabling the wrap-around sanitizers in the future.

Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
Link: https://github.com/KSPP/linux/issues/26 [2]
Link: https://github.com/KSPP/linux/issues/27 [3]
Link: https://github.com/KSPP/linux/issues/344 [4]
Cc: Christian Brauner <brauner@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Dave Chinner <dchinner@redhat.com>
Cc: Alexey Gladkov <legion@kernel.org>
Cc: Jeff Layton <jlayton@kernel.org>
Cc: Waiman Long <longman@redhat.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
 ipc/mqueue.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 5eea4dc0509e..7ef9d325183a 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -366,7 +366,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
 			min_t(unsigned int, info->attr.mq_maxmsg, MQ_PRIO_MAX) *
 			sizeof(struct posix_msg_tree_node);
 		mq_bytes = info->attr.mq_maxmsg * info->attr.mq_msgsize;
-		if (mq_bytes + mq_treesize < mq_bytes)
+		if (add_would_overflow(mq_bytes, mq_treesize))
 			goto out_inode;
 		mq_bytes += mq_treesize;
 		info->ucounts = get_ucounts(current_ucounts());
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 163+ messages in thread

* Re: [PATCH 75/82] timekeeping: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 75/82] timekeeping: " Kees Cook
@ 2024-01-23  1:06   ` John Stultz
  2024-01-24 19:34   ` Thomas Gleixner
  1 sibling, 0 replies; 163+ messages in thread
From: John Stultz @ 2024-01-23  1:06 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Thomas Gleixner, Stephen Boyd,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 4:36 PM Kees Cook <keescook@chromium.org> wrote:
>
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
>         VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: John Stultz <jstultz@google.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  kernel/time/timekeeping.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> index 266d02809dbb..2fc7cf16584c 100644
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -1984,7 +1984,7 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
>          * Which simplifies to:
>          *      xtime_nsec -= offset
>          */
> -       if ((mult_adj > 0) && (tk->tkr_mono.mult + mult_adj < mult_adj)) {
> +       if ((mult_adj > 0) && (add_would_overflow(mult_adj, tk->tkr_mono.mult))) {
>                 /* NTP adjustment caused clocksource mult overflow */
>                 WARN_ON_ONCE(1);
>                 return;

Acked-by: John Stultz <jstultz@google.com>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 34/82] ipc: Refactor intentional wrap-around calculation
  2024-01-23  0:27 ` [PATCH 34/82] ipc: " Kees Cook
@ 2024-01-23  1:07   ` Linus Torvalds
  2024-01-23  1:38     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Linus Torvalds @ 2024-01-23  1:07 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Andrew Morton, Liam R. Howlett, Mark Brown,
	Mike Kravetz, Vasily Averin, Alexander Mikhalitsyn,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, 22 Jan 2024 at 16:46, Kees Cook <keescook@chromium.org> wrote:
>
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(),

NAK.

First off, none of this has anything to do with -fno-strict-overflow.
We do that, because without it gcc ends up doing various odd and
surprising things, the same way it does with strict-aliasing.

IOW, you should think of -fno-strict-overflow as a hardening thing.
Any optimization that depends on "this can overflow, so I can do
anything I want" is just a dangerous optimization for the kernel.

It matches -fno-strict-aliasing and -fno-delete-null-pointer-checks,
in other words.

And I do not understand why you mention it in the first place, since
this code USES UNSIGNED INTEGER ARITHMETIC, and thus has absolutely
nothing to do with that no-strict-overflow flag.

So the commit message is actively misleading and broken. Unsigned
arithmetic has very well-defined behavior, and the code uses that with
a very traditional and valid test.

The comment about "redundant open-coded addition" is also PURE
GARBAGE, since the compiler will trivially do the CSE - and on the
source code level your modified code is actively bigger and uglier.

So your patch improves neither code generation or source code.

And if there's some unsigned wrap-around checker that doesn't
understand this traditional way of doing overflow checking, that piece
of crap needs fixing.

I don't want to see mindless conversion patches that work around some
broken tooling.

I want to see them even less when pretty much EVERY SINGLE WORD in the
commit message seems to be actively misleading and irrelevant garbage.

Stop making the world a worse place.

                 Linus

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 34/82] ipc: Refactor intentional wrap-around calculation
  2024-01-23  1:07   ` Linus Torvalds
@ 2024-01-23  1:38     ` Kees Cook
  2024-01-23 18:06       ` Linus Torvalds
  0 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  1:38 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-hardening, Andrew Morton, Liam R. Howlett, Mark Brown,
	Mike Kravetz, Vasily Averin, Alexander Mikhalitsyn,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 05:07:40PM -0800, Linus Torvalds wrote:
> First off, none of this has anything to do with -fno-strict-overflow.
> We do that, because without it gcc ends up doing various odd and
> surprising things, the same way it does with strict-aliasing.
> 
> IOW, you should think of -fno-strict-overflow as a hardening thing.
> Any optimization that depends on "this can overflow, so I can do
> anything I want" is just a dangerous optimization for the kernel.
> 
> It matches -fno-strict-aliasing and -fno-delete-null-pointer-checks,
> in other words.
> 
> And I do not understand why you mention it in the first place, since
> this code USES UNSIGNED INTEGER ARITHMETIC, and thus has absolutely
> nothing to do with that no-strict-overflow flag.

I've tried to find the right balance between not enough details and too
much. I guess I got it wrong. I go into more detail in the cover letter:
https://lore.kernel.org/linux-hardening/20240122235208.work.748-kees@kernel.org/

Basically, this isn't about -fno-strict-overflow -- that's just a wrinkle
on the compiler side. I completely agree: we have to keep the "undefined
behavior" junk as far away from the kernel as possible.

This is about disambiguating the intent of C arithmetic so we can be in
the position to instrument the kernel to catch unexpected wrap-arounds.
We can't use C++ tricks with operator overloading and the introduction
of wrapping vs trapping types, so we have to annotate things directly.

And we have sanitizers for signed, unsigned, and pointers. Hence, the
need to adjust these open-coded wrap tests. It's not about removing UB:
-fno-strict-overflow already does that. This is about let us trap
unexpected wrap-around, regardless of type.

> Stop making the world a worse place.

Rude. I'll leave that to ice storms.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 13/82] btrfs: Refactor intentional wrap-around calculation
  2024-01-23  0:26 ` [PATCH 13/82] btrfs: Refactor intentional wrap-around calculation Kees Cook
@ 2024-01-23  1:45   ` David Sterba
  0 siblings, 0 replies; 163+ messages in thread
From: David Sterba @ 2024-01-23  1:45 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Chris Mason, Josef Bacik, David Sterba,
	linux-btrfs, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Mon, Jan 22, 2024 at 04:26:48PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> wrap-around sanitizer in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Chris Mason <clm@fb.com>
> Cc: Josef Bacik <josef@toxicpanda.com>
> Cc: David Sterba <dsterba@suse.com>
> Cc: linux-btrfs@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Acked-by: David Sterba <dsterba@suse.com>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (81 preceding siblings ...)
  2024-01-23  0:27 ` [PATCH 82/82] mqueue: " Kees Cook
@ 2024-01-23  2:22 ` Kent Overstreet
  2024-01-23  2:51   ` Kees Cook
  2024-01-23  9:46 ` Mark Rutland
  83 siblings, 1 reply; 163+ messages in thread
From: Kent Overstreet @ 2024-01-23  2:22 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:26:35PM -0800, Kees Cook wrote:
> Hi,
> 
> In our continuing effort to eliminate root causes of flaws in the kernel,
> this series is the start to providing a way to have sensible coverage
> for catching unexpected arithmetic wrap-around.
> 
> A quick word on language: while discussing[1] the finer details of
> the C standard's view on arithmetic, I was disabused of using the term
> "overflow" when what I really mean is "wrap-around". When describing
> security vulnerabilities, "overflow" is the common term and often used
> interchangeably with "wrap-around". Strictly speaking, though, "overflow"
> applies only to signed[2] and pointer[3] types, and "wrap-around" is for
> unsigned[4]. An arithmetic "overflow" is considered undefined behavior,
> which has caused our builds pain in the past, since "impossible"
> conditions might get elided by the compiler. As a result, we build
> with -fno-strict-overflow which coverts all "overflow" conditions into
> "wrap-around" (i.e. 2s complement), regardless of type.
> 
> All this is to say I am discussing arithmetic wrap-around, which is
> the condition where the value exceeds a type's maximum value (or goes
> below its minimum value) and wraps around. I'm not interested in the
> narrow definition of "undefined behavior" -- we need to stamp out the
> _unexpected_ behavior, where the kernel operates on a pathological value
> that wrapped around without the code author's intent.
> 
> As always, this is about being able disambiguate the intent of arithmetic
> in the kernel. We intentionally use wrapping arithmetic in all kinds of
> places, but we need to be able to annotate it as such going forward so
> the compiler can distinguish when it needs to perform instrumentation
> (when such instrumentation is enabled).
> 
> Getting back to my earlier mention of -fno-strict-overflow, the bulk of
> the series is refactoring for a common code pattern in the kernel where
> to test for potentially overflowing addition, the addition is performed,
> and wrap-around is tested for. This is what originally[5] caused us to
> enable -fno-strict-overflow:
> 
> 	var + offset < var
> 
> For these cases we can use either check_add_overflow() or
> add_would_overflow(). These helpers will not trip the wrap-around
> instrumentation, and do not depend on the whims of the compiler options.
> (Note that I have no intention of removing -fno-strict-overflow any
> time soon, if ever. As with all these kinds of changes, we need to
> evolve our support for it, and we can't introduce undefined behavior
> into the kernel.)
> 
> This series is mainly 3 parts:

This all seems fine, but... Rust already has this at the type system
level....

I know you're not one of the people bringing bickering into the Rust
threads, so I'm wondering if perhaps your secret plan is to annoy the
die hard "I want everything to be fast with razor blades everywhere" C
programmers enough to finally get onboard the "let's just switch to a
language with less razor wire" train.

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers
  2024-01-23  0:26 ` [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers Kees Cook
@ 2024-01-23  2:24   ` Miguel Ojeda
  2024-01-23  4:45     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Miguel Ojeda @ 2024-01-23  2:24 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Justin Stitt, Miguel Ojeda, Nathan Chancellor,
	Nick Desaulniers, Peter Zijlstra, Marco Elver, Hao Luo,
	Przemek Kitszel, Gustavo A. R. Silva, Bill Wendling,
	linux-kernel

On Tue, Jan 23, 2024 at 1:28 AM Kees Cook <keescook@chromium.org> wrote:
>
> Because the kernel is built with -fno-strict-overflow, signed and pointer
> arithmetic is defined to always wrap around instead of "overflowing"
> (which would either be elided due to being undefined behavior or would
> wrap around, which led to very weird bugs in the kernel).

By elided I guess you also mean assumed to not happen and thus the
usual chain-of-logic magic?

> So, the config options are added back as CONFIG_UBSAN_SIGNED_WRAP and
> CONFIG_UBSAN_UNSIGNED_WRAP. Since the kernel has several places that
> explicitly depend on wrap-around behavior (e.g. counters, atomics, etc),
> also introduce the __signed_wrap and __unsigned_wrap function attributes
> for annotating functions where wrapping is expected and should not
> be caught. This will allow us to distinguish in the kernel between
> intentional and unintentional cases of arithmetic wrap-around.

Sounds good -- it seems to go in the direction of Rust, i.e. to have a
way to mark expected wrap-arounds so that we can start catching the
unintended ones.

> +       depends on !COMPILE_TEST
> +       depends on $(cc-option,-fsanitize=signed-integer-overflow)

Maybe this line goes above the other, to be consistent with the
unsigned case? (or the other way around)

> +       depends on !X86_32 # avoid excessive stack usage on x86-32/clang
> +       depends on !COMPILE_TEST
> +       help
> +         This option enables -fsanitize=unsigned-integer-overflow which checks
> +         for wrap-around of any arithmetic operations with unsigned integers. This
> +         currently causes x86 to fail to boot.

Is it related to the excessive stack usage? In that case, users would
not reach the point to see this description, right? If so, I guess it
could be removed from the `help` and moved into the comment above or
similar.

> +static void test_ubsan_sub_overflow(void)
> +{
> +       volatile int val = INT_MIN;
> +       volatile unsigned int uval = 0;
> +       volatile int val2 = 2;

In the other tests you use a constant instead of `val2`, I am curious
if there is a reason for it?

Thanks!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 27/82] m68k: Refactor intentional wrap-around calculation
  2024-01-23  0:27 ` [PATCH 27/82] m68k: " Kees Cook
@ 2024-01-23  2:29   ` Liam R. Howlett
  2024-01-23  8:13   ` Geert Uytterhoeven
  1 sibling, 0 replies; 163+ messages in thread
From: Liam R. Howlett @ 2024-01-23  2:29 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Geert Uytterhoeven, Andrew Morton,
	Arnd Bergmann, Matthew Wilcox (Oracle),
	Hugh Dickins, linux-m68k, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

* Kees Cook <keescook@chromium.org> [240122 19:36]:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> unsigned wrap-around sanitizer[2] in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Liam Howlett <liam.howlett@oracle.com>
> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: linux-m68k@lists.linux-m68k.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/m68k/kernel/sys_m68k.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
> index 1af5e6082467..b2b9248f2566 100644
> --- a/arch/m68k/kernel/sys_m68k.c
> +++ b/arch/m68k/kernel/sys_m68k.c
> @@ -391,10 +391,11 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
>  
>  		mmap_read_lock(current->mm);
>  	} else {
> +		unsigned long sum;
>  		struct vm_area_struct *vma;
>  
>  		/* Check for overflow.  */

With your nice self-documenting code, you can probably drop that
comment.

With or without the change,

Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>

> -		if (addr + len < addr)
> +		if (check_add_overflow(addr, len, &sum))
>  			goto out;
>  
>  		/*
> @@ -403,7 +404,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
>  		 */
>  		mmap_read_lock(current->mm);
>  		vma = vma_lookup(current->mm, addr);
> -		if (!vma || addr + len > vma->vm_end)
> +		if (!vma || sum > vma->vm_end)
>  			goto out_unlock;
>  	}
>  
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around
  2024-01-23  2:22 ` [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kent Overstreet
@ 2024-01-23  2:51   ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  2:51 UTC (permalink / raw)
  To: Kent Overstreet, Kees Cook
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel



On January 22, 2024 6:22:13 PM PST, Kent Overstreet <kent.overstreet@linux.dev> wrote:
>On Mon, Jan 22, 2024 at 04:26:35PM -0800, Kees Cook wrote:
>> In our continuing effort to eliminate root causes of flaws in the kernel,
>> this series is the start to providing a way to have sensible coverage
>> for catching unexpected arithmetic wrap-around.
>> 
>This all seems fine, but... Rust already has this at the type system
>level....
>
>I know you're not one of the people bringing bickering into the Rust
>threads, so I'm wondering if perhaps your secret plan is to annoy the
>die hard "I want everything to be fast with razor blades everywhere" C
>programmers enough to finally get onboard the "let's just switch to a
>language with less razor wire" train.

I don't want to annoy anyone, but yeah, in the process of getting rid of dangerous stuff we do end up asking people to make changes they're not used to. I hope to make it as easy as possible, though.

I'm a big fan of Rust, but I know it's not going to happen over night; there is a LOT of C code in Linux. :) I look at making the kernel safer by removing as many C foot-guns as possible. As we remove the ambiguities in C that lead to vulnerabilities, we'll eventually meet halfway with the new Rust code.

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 46/82] crypto: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 46/82] crypto: " Kees Cook
@ 2024-01-23  3:07   ` Eric Biggers
  2024-01-23  3:29     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Eric Biggers @ 2024-01-23  3:07 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Herbert Xu, David S. Miller, Aditya Srivastava,
	Randy Dunlap, linux-crypto, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:21PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Aditya Srivastava <yashsri421@gmail.com>
> Cc: Randy Dunlap <rdunlap@infradead.org>
> Cc: linux-crypto@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  crypto/adiantum.c                   | 2 +-
>  drivers/crypto/amcc/crypto4xx_alg.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/crypto/adiantum.c b/crypto/adiantum.c
> index 60f3883b736a..c2f62ca455af 100644
> --- a/crypto/adiantum.c
> +++ b/crypto/adiantum.c
> @@ -190,7 +190,7 @@ static inline void le128_add(le128 *r, const le128 *v1, const le128 *v2)
>  
>  	r->b = cpu_to_le64(x + y);
>  	r->a = cpu_to_le64(le64_to_cpu(v1->a) + le64_to_cpu(v2->a) +
> -			   (x + y < x));
> +			   (add_would_overflow(x, y)));
>  }
>  
>  /* Subtraction in Z/(2^{128}Z) */
> diff --git a/drivers/crypto/amcc/crypto4xx_alg.c b/drivers/crypto/amcc/crypto4xx_alg.c
> index e0af611a95d8..33f73234ddd9 100644
> --- a/drivers/crypto/amcc/crypto4xx_alg.c
> +++ b/drivers/crypto/amcc/crypto4xx_alg.c
> @@ -251,7 +251,7 @@ crypto4xx_ctr_crypt(struct skcipher_request *req, bool encrypt)
>  	 * the whole IV is a counter.  So fallback if the counter is going to
>  	 * overlow.
>  	 */
> -	if (counter + nblks < counter) {
> +	if (add_would_overflow(counter, nblks)) {
>  		SYNC_SKCIPHER_REQUEST_ON_STACK(subreq, ctx->sw_cipher.cipher);
>  		int ret;

Just to double check, you really intend to forbid *unsigned* integer wraparound?
This patch's commit message focuses on signed, and barely mentions unsigned.
The actual code changes in this patch only deals with unsigned.

Also, what's the motivation for addressing the 'x + y < x' case but not other
cases in the same file?  For example, the le128_add() function which this patch
modifies has two other intentional wraparounds, which this patch doesn't touch.
Also, the le128_sub() function just below le128_add() is very similar but does
wraparound in the other direction.  That's 6 cases in 20 lines of code, but this
patch only addresses 1.  And of course, lots of other crypto code relies on
unsigned wraparounds too, which this patch overlooks.  So I'm a bit confused
about the point of this patch.  If we really wanted to explicitly annotate all
the intentional wraparounds in a particular piece of code, so that the code can
be run with the corresponding sanitizer enabled, wouldn't it be necessary to
actually test the code with that sanitizer enabled to find all the cases?

- Eric

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 46/82] crypto: Refactor intentional wrap-around test
  2024-01-23  3:07   ` Eric Biggers
@ 2024-01-23  3:29     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23  3:29 UTC (permalink / raw)
  To: Eric Biggers, Kees Cook
  Cc: linux-hardening, Herbert Xu, David S. Miller, Aditya Srivastava,
	Randy Dunlap, linux-crypto, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel



On January 22, 2024 7:07:45 PM PST, Eric Biggers <ebiggers@kernel.org> wrote:
>Just to double check, you really intend to forbid *unsigned* integer wraparound?
>This patch's commit message focuses on signed, and barely mentions unsigned.
>The actual code changes in this patch only deals with unsigned.

I don't mean to forbid wrap-around; we just need to annotate it. I can see how this commit log didn't do a great job explaining this. I hope the cover letter is more sensible:
https://lore.kernel.org/linux-hardening/20240122235208.work.748-kees@kernel.org/

>Also, what's the motivation for addressing the 'x + y < x' case but not other
>cases in the same file?

It's a code pattern we could find easily. It's working from the instances found via Coccinelle earlier in the series:
https://lore.kernel.org/linux-hardening/20240123002814.1396804-5-keescook@chromium.org/

> For example, the le128_add() function which this patch
>modifies has two other intentional wraparounds, which this patch doesn't touch.

For dedicated wrapping functions we can mark them with __unsigned_wrap:
https://lore.kernel.org/linux-hardening/20240123002814.1396804-6-keescook@chromium.org/

>Also, the le128_sub() function just below le128_add() is very similar but does
>wraparound in the other direction.  That's 6 cases in 20 lines of code, but this
>patch only addresses 1.  And of course, lots of other crypto code relies on
>unsigned wraparounds too, which this patch overlooks.  

Right -- finding these kinds of things is where a lot of time will be spent in the future, I suspect. :)

> So I'm a bit confused
>about the point of this patch.  If we really wanted to explicitly annotate all
>the intentional wraparounds in a particular piece of code, so that the code can
>be run with the corresponding sanitizer enabled, wouldn't it be necessary to
>actually test the code with that sanitizer enabled to find all the cases?

Yes, but there's a lot of code to test -- I'm trying to get the first steps done. And then once the sanitizers are in good shape, the fuzzers can grind. (I'm trying to add some parallelism to this project; this code pattern was known so I figured we could address it now.)

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 43/82] bpf: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 43/82] bpf: " Kees Cook
@ 2024-01-23  4:00   ` Yonghong Song
  2024-01-23  4:07     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Yonghong Song @ 2024-01-23  4:00 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, KP Singh,
	Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel


On 1/22/24 4:27 PM, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: John Fastabend <john.fastabend@gmail.com>
> Cc: Andrii Nakryiko <andrii@kernel.org>
> Cc: Martin KaFai Lau <martin.lau@linux.dev>
> Cc: Song Liu <song@kernel.org>
> Cc: Yonghong Song <yonghong.song@linux.dev>
> Cc: KP Singh <kpsingh@kernel.org>
> Cc: Stanislav Fomichev <sdf@google.com>
> Cc: Hao Luo <haoluo@google.com>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: bpf@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>   kernel/bpf/verifier.c | 12 ++++++------
>   1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 65f598694d55..21e3f30c8757 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -12901,8 +12901,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
>   			dst_reg->smin_value = smin_ptr + smin_val;
>   			dst_reg->smax_value = smax_ptr + smax_val;
>   		}
> -		if (umin_ptr + umin_val < umin_ptr ||
> -		    umax_ptr + umax_val < umax_ptr) {
> +		if (add_would_overflow(umin_ptr, umin_val) ||
> +		    add_would_overflow(umax_ptr, umax_val)) {

Maybe you could give a reference to the definition of add_would_overflow()?
A link or a patch with add_would_overflow() defined cc'ed to bpf program.
The patch itselfs looks good to me.

>   			dst_reg->umin_value = 0;
>   			dst_reg->umax_value = U64_MAX;
>   		} else {
> @@ -13023,8 +13023,8 @@ static void scalar32_min_max_add(struct bpf_reg_state *dst_reg,
>   		dst_reg->s32_min_value += smin_val;
>   		dst_reg->s32_max_value += smax_val;
>   	}
> -	if (dst_reg->u32_min_value + umin_val < umin_val ||
> -	    dst_reg->u32_max_value + umax_val < umax_val) {
> +	if (add_would_overflow(umin_val, dst_reg->u32_min_value) ||
> +	    add_would_overflow(umax_val, dst_reg->u32_max_value)) {
>   		dst_reg->u32_min_value = 0;
>   		dst_reg->u32_max_value = U32_MAX;
>   	} else {
> @@ -13049,8 +13049,8 @@ static void scalar_min_max_add(struct bpf_reg_state *dst_reg,
>   		dst_reg->smin_value += smin_val;
>   		dst_reg->smax_value += smax_val;
>   	}
> -	if (dst_reg->umin_value + umin_val < umin_val ||
> -	    dst_reg->umax_value + umax_val < umax_val) {
> +	if (add_would_overflow(umin_val, dst_reg->umin_value) ||
> +	    add_would_overflow(umax_val, dst_reg->umax_value)) {
>   		dst_reg->umin_value = 0;
>   		dst_reg->umax_value = U64_MAX;
>   	} else {

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 43/82] bpf: Refactor intentional wrap-around test
  2024-01-23  4:00   ` Yonghong Song
@ 2024-01-23  4:07     ` Kees Cook
  2024-01-23  5:13       ` Yonghong Song
  0 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  4:07 UTC (permalink / raw)
  To: Yonghong Song, Kees Cook, linux-hardening
  Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, KP Singh,
	Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel



On January 22, 2024 8:00:26 PM PST, Yonghong Song <yonghong.song@linux.dev> wrote:
>
>On 1/22/24 4:27 PM, Kees Cook wrote:
>> In an effort to separate intentional arithmetic wrap-around from
>> unexpected wrap-around, we need to refactor places that depend on this
>> kind of math. One of the most common code patterns of this is:
>> 
>> 	VAR + value < VAR
>> 
>> Notably, this is considered "undefined behavior" for signed and pointer
>> types, which the kernel works around by using the -fno-strict-overflow
>> option in the build[1] (which used to just be -fwrapv). Regardless, we
>> want to get the kernel source to the position where we can meaningfully
>> instrument arithmetic wrap-around conditions and catch them when they
>> are unexpected, regardless of whether they are signed[2], unsigned[3],
>> or pointer[4] types.
>> 
>> Refactor open-coded wrap-around addition test to use add_would_overflow().
>> This paves the way to enabling the wrap-around sanitizers in the future.
>> 
>> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
>> Link: https://github.com/KSPP/linux/issues/26 [2]
>> Link: https://github.com/KSPP/linux/issues/27 [3]
>> Link: https://github.com/KSPP/linux/issues/344 [4]
>> Cc: Alexei Starovoitov <ast@kernel.org>
>> Cc: Daniel Borkmann <daniel@iogearbox.net>
>> Cc: John Fastabend <john.fastabend@gmail.com>
>> Cc: Andrii Nakryiko <andrii@kernel.org>
>> Cc: Martin KaFai Lau <martin.lau@linux.dev>
>> Cc: Song Liu <song@kernel.org>
>> Cc: Yonghong Song <yonghong.song@linux.dev>
>> Cc: KP Singh <kpsingh@kernel.org>
>> Cc: Stanislav Fomichev <sdf@google.com>
>> Cc: Hao Luo <haoluo@google.com>
>> Cc: Jiri Olsa <jolsa@kernel.org>
>> Cc: bpf@vger.kernel.org
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>> ---
>>   kernel/bpf/verifier.c | 12 ++++++------
>>   1 file changed, 6 insertions(+), 6 deletions(-)
>> 
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 65f598694d55..21e3f30c8757 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -12901,8 +12901,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
>>   			dst_reg->smin_value = smin_ptr + smin_val;
>>   			dst_reg->smax_value = smax_ptr + smax_val;
>>   		}
>> -		if (umin_ptr + umin_val < umin_ptr ||
>> -		    umax_ptr + umax_val < umax_ptr) {
>> +		if (add_would_overflow(umin_ptr, umin_val) ||
>> +		    add_would_overflow(umax_ptr, umax_val)) {
>
>Maybe you could give a reference to the definition of add_would_overflow()?
>A link or a patch with add_would_overflow() defined cc'ed to bpf program.

Sure! It was earlier in the series:
https://lore.kernel.org/linux-hardening/20240123002814.1396804-2-keescook@chromium.org/

The cover letter also has more details:
https://lore.kernel.org/linux-hardening/20240122235208.work.748-kees@kernel.org/

>The patch itselfs looks good to me.

Thanks!

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers
  2024-01-23  2:24   ` Miguel Ojeda
@ 2024-01-23  4:45     ` Kees Cook
  2024-01-23 11:20       ` Miguel Ojeda
  0 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-23  4:45 UTC (permalink / raw)
  To: Miguel Ojeda, Kees Cook
  Cc: linux-hardening, Justin Stitt, Miguel Ojeda, Nathan Chancellor,
	Nick Desaulniers, Peter Zijlstra, Marco Elver, Hao Luo,
	Przemek Kitszel, Gustavo A. R. Silva, Bill Wendling,
	linux-kernel



On January 22, 2024 6:24:14 PM PST, Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote:
>On Tue, Jan 23, 2024 at 1:28 AM Kees Cook <keescook@chromium.org> wrote:
>>
>> Because the kernel is built with -fno-strict-overflow, signed and pointer
>> arithmetic is defined to always wrap around instead of "overflowing"
>> (which would either be elided due to being undefined behavior or would
>> wrap around, which led to very weird bugs in the kernel).
>
>By elided I guess you also mean assumed to not happen and thus the
>usual chain-of-logic magic?

Yes. We removed this bad behavior by using -fno-strict-overflow, and we will want to keep it enabled.

>
>> So, the config options are added back as CONFIG_UBSAN_SIGNED_WRAP and
>> CONFIG_UBSAN_UNSIGNED_WRAP. Since the kernel has several places that
>> explicitly depend on wrap-around behavior (e.g. counters, atomics, etc),
>> also introduce the __signed_wrap and __unsigned_wrap function attributes
>> for annotating functions where wrapping is expected and should not
>> be caught. This will allow us to distinguish in the kernel between
>> intentional and unintentional cases of arithmetic wrap-around.
>
>Sounds good -- it seems to go in the direction of Rust, i.e. to have a
>way to mark expected wrap-arounds so that we can start catching the
>unintended ones.

Yup! That's the plan.

>
>> +       depends on !COMPILE_TEST
>> +       depends on $(cc-option,-fsanitize=signed-integer-overflow)
>
>Maybe this line goes above the other, to be consistent with the
>unsigned case? (or the other way around)

Sure, I can move it around.

>
>> +       depends on !X86_32 # avoid excessive stack usage on x86-32/clang
>> +       depends on !COMPILE_TEST
>> +       help
>> +         This option enables -fsanitize=unsigned-integer-overflow which checks
>> +         for wrap-around of any arithmetic operations with unsigned integers. This
>> +         currently causes x86 to fail to boot.
>
>Is it related to the excessive stack usage? In that case, users would
>not reach the point to see this description, right? If so, I guess it
>could be removed from the `help` and moved into the comment above or
>similar.

The stack usage is separate. (This may even be fixed in modern Clang; this comes from the original version of this Kconfig.) The not booting part is separate and has not been tracked down yet.

>
>> +static void test_ubsan_sub_overflow(void)
>> +{
>> +       volatile int val = INT_MIN;
>> +       volatile unsigned int uval = 0;
>> +       volatile int val2 = 2;
>
>In the other tests you use a constant instead of `val2`, I am curious
>if there is a reason for it?

I wondered the same -- they were this way when they were removed, so I just restored them as they were. :)

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 43/82] bpf: Refactor intentional wrap-around test
  2024-01-23  4:07     ` Kees Cook
@ 2024-01-23  5:13       ` Yonghong Song
  0 siblings, 0 replies; 163+ messages in thread
From: Yonghong Song @ 2024-01-23  5:13 UTC (permalink / raw)
  To: Kees Cook, Kees Cook, linux-hardening
  Cc: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
	Andrii Nakryiko, Martin KaFai Lau, Song Liu, KP Singh,
	Stanislav Fomichev, Hao Luo, Jiri Olsa, bpf, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel


On 1/22/24 8:07 PM, Kees Cook wrote:
>
> On January 22, 2024 8:00:26 PM PST, Yonghong Song <yonghong.song@linux.dev> wrote:
>> On 1/22/24 4:27 PM, Kees Cook wrote:
>>> In an effort to separate intentional arithmetic wrap-around from
>>> unexpected wrap-around, we need to refactor places that depend on this
>>> kind of math. One of the most common code patterns of this is:
>>>
>>> 	VAR + value < VAR
>>>
>>> Notably, this is considered "undefined behavior" for signed and pointer
>>> types, which the kernel works around by using the -fno-strict-overflow
>>> option in the build[1] (which used to just be -fwrapv). Regardless, we
>>> want to get the kernel source to the position where we can meaningfully
>>> instrument arithmetic wrap-around conditions and catch them when they
>>> are unexpected, regardless of whether they are signed[2], unsigned[3],
>>> or pointer[4] types.
>>>
>>> Refactor open-coded wrap-around addition test to use add_would_overflow().
>>> This paves the way to enabling the wrap-around sanitizers in the future.
>>>
>>> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
>>> Link: https://github.com/KSPP/linux/issues/26 [2]
>>> Link: https://github.com/KSPP/linux/issues/27 [3]
>>> Link: https://github.com/KSPP/linux/issues/344 [4]
>>> Cc: Alexei Starovoitov <ast@kernel.org>
>>> Cc: Daniel Borkmann <daniel@iogearbox.net>
>>> Cc: John Fastabend <john.fastabend@gmail.com>
>>> Cc: Andrii Nakryiko <andrii@kernel.org>
>>> Cc: Martin KaFai Lau <martin.lau@linux.dev>
>>> Cc: Song Liu <song@kernel.org>
>>> Cc: Yonghong Song <yonghong.song@linux.dev>
>>> Cc: KP Singh <kpsingh@kernel.org>
>>> Cc: Stanislav Fomichev <sdf@google.com>
>>> Cc: Hao Luo <haoluo@google.com>
>>> Cc: Jiri Olsa <jolsa@kernel.org>
>>> Cc: bpf@vger.kernel.org
>>> Signed-off-by: Kees Cook <keescook@chromium.org>
>>> ---
>>>    kernel/bpf/verifier.c | 12 ++++++------
>>>    1 file changed, 6 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>> index 65f598694d55..21e3f30c8757 100644
>>> --- a/kernel/bpf/verifier.c
>>> +++ b/kernel/bpf/verifier.c
>>> @@ -12901,8 +12901,8 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
>>>    			dst_reg->smin_value = smin_ptr + smin_val;
>>>    			dst_reg->smax_value = smax_ptr + smax_val;
>>>    		}
>>> -		if (umin_ptr + umin_val < umin_ptr ||
>>> -		    umax_ptr + umax_val < umax_ptr) {
>>> +		if (add_would_overflow(umin_ptr, umin_val) ||
>>> +		    add_would_overflow(umax_ptr, umax_val)) {
>> Maybe you could give a reference to the definition of add_would_overflow()?
>> A link or a patch with add_would_overflow() defined cc'ed to bpf program.
> Sure! It was earlier in the series:
> https://lore.kernel.org/linux-hardening/20240123002814.1396804-2-keescook@chromium.org/
>
> The cover letter also has more details:
> https://lore.kernel.org/linux-hardening/20240122235208.work.748-kees@kernel.org/

Thanks for the pointer.

Acked-by: Yonghong Song <yonghong.song@linux.dev>

>
>> The patch itselfs looks good to me.
> Thanks!
>
> -Kees
>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 69/82] perf tools: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 69/82] perf tools: " Kees Cook
@ 2024-01-23  6:21   ` Adrian Hunter
  2024-01-23 21:31     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Adrian Hunter @ 2024-01-23  6:21 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	Ian Rogers, John Garry, Fangrui Song, linux-perf-users,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On 23/01/24 02:27, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Ian Rogers <irogers@google.com>
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: John Garry <john.garry@huawei.com>
> Cc: Fangrui Song <maskray@google.com>
> Cc: linux-perf-users@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  tools/perf/util/dso.c                    | 2 +-
>  tools/perf/util/unwind-libdw.c           | 2 +-
>  tools/perf/util/unwind-libunwind-local.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
> index 22fd5fa806ed..470a86f1cdfd 100644
> --- a/tools/perf/util/dso.c
> +++ b/tools/perf/util/dso.c
> @@ -1122,7 +1122,7 @@ static ssize_t data_read_write_offset(struct dso *dso, struct machine *machine,
>  	if (offset > dso->data.file_size)
>  		return -1;
>  
> -	if (offset + size < offset)
> +	if (add_would_overflow(offset, size))

perf tools has separate includes to the kernel, so does not
seem to include add_would_overflow() in any of its include
files at this point.  Need to update
tools/include/linux/overflow.h first.


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 41/82] wil6210: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 41/82] wil6210: " Kees Cook
@ 2024-01-23  6:36   ` Kalle Valo
  2024-01-23 11:50   ` Kalle Valo
  1 sibling, 0 replies; 163+ messages in thread
From: Kalle Valo @ 2024-01-23  6:36 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Johannes Berg, Max Chen, Yang Shen,
	linux-wireless, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

Kees Cook <keescook@chromium.org> writes:

> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Kalle Valo <kvalo@kernel.org>
> Cc: Johannes Berg <johannes.berg@intel.com>
> Cc: Max Chen <mxchen@codeaurora.org>
> Cc: Yang Shen <shenyang39@huawei.com>
> Cc: linux-wireless@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

I assume this goes via some other tree than wireless-next so:

Acked-by: Kalle Valo <kvalo@kernel.org>

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 62/82] mwifiex: pcie: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 62/82] mwifiex: pcie: " Kees Cook
@ 2024-01-23  6:36   ` Kalle Valo
  0 siblings, 0 replies; 163+ messages in thread
From: Kalle Valo @ 2024-01-23  6:36 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Brian Norris, Jonas Dreßler,
	Dmitry Antipov, Tsuchiya Yuto, linux-wireless,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

Kees Cook <keescook@chromium.org> writes:

> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Brian Norris <briannorris@chromium.org>
> Cc: Kalle Valo <kvalo@kernel.org>
> Cc: "Jonas Dreßler" <verdre@v0yd.nl>
> Cc: Dmitry Antipov <dmantipov@yandex.ru>
> Cc: Tsuchiya Yuto <kitakar@gmail.com>
> Cc: linux-wireless@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

I assume this goes via some other tree than wireless-next so:

Acked-by: Kalle Valo <kvalo@kernel.org>

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 42/82] bcachefs: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 42/82] bcachefs: " Kees Cook
@ 2024-01-23  6:36   ` Kent Overstreet
  0 siblings, 0 replies; 163+ messages in thread
From: Kent Overstreet @ 2024-01-23  6:36 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Brian Foster, linux-bcachefs,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:17PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Kent Overstreet <kent.overstreet@linux.dev>
> Cc: Brian Foster <bfoster@redhat.com>
> Cc: linux-bcachefs@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Acked-by: Kent Overstreet <kent.overstreet@linux.dev>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 73/82] sh: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 73/82] sh: " Kees Cook
@ 2024-01-23  7:31   ` John Paul Adrian Glaubitz
  0 siblings, 0 replies; 163+ messages in thread
From: John Paul Adrian Glaubitz @ 2024-01-23  7:31 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Yoshinori Sato, Rich Felker, linux-sh, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

Hello Kees,

On Mon, 2024-01-22 at 16:27 -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Cc: Rich Felker <dalias@libc.org>
> Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
> Cc: linux-sh@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/sh/kernel/sys_sh.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
> index a5a7b33ed81a..e390caeb8c00 100644
> --- a/arch/sh/kernel/sys_sh.c
> +++ b/arch/sh/kernel/sys_sh.c
> @@ -66,7 +66,7 @@ asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
>  	 * Verify that the specified address region actually belongs
>  	 * to this process.
>  	 */
> -	if (addr + len < addr)
> +	if (add_would_overflow(addr, len))
>  		return -EFAULT;
>  
>  	mmap_read_lock(current->mm);

Sounds like a very sensible change to me.

Acked-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>

Adrian

-- 
 .''`.  John Paul Adrian Glaubitz
: :' :  Debian Developer
`. `'   Physicist
  `-    GPG: 62FF 8A75 84E0 2956 9546  0006 7426 3B37 F5B5 F913

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 80/82] xen-netback: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 80/82] xen-netback: " Kees Cook
@ 2024-01-23  7:55   ` Jan Beulich
  2024-01-23 21:32     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Jan Beulich @ 2024-01-23  7:55 UTC (permalink / raw)
  To: Kees Cook
  Cc: Wei Liu, Paul Durrant, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, xen-devel, netdev,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel,
	linux-hardening

On 23.01.2024 01:27, Kees Cook wrote:
> --- a/drivers/net/xen-netback/hash.c
> +++ b/drivers/net/xen-netback/hash.c
> @@ -345,7 +345,7 @@ u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len,
>  		.flags = GNTCOPY_source_gref
>  	}};
>  
> -	if ((off + len < off) || (off + len > vif->hash.size) ||
> +	if ((add_would_overflow(off, len)) || (off + len > vif->hash.size) ||

I'm not maintainer of this code, but if I was I would ask that the
excess parentheses be removed, to improve readability.

Jan

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 02/82] overflow: Introduce add_would_overflow()
  2024-01-23  0:26 ` [PATCH 02/82] overflow: Introduce add_would_overflow() Kees Cook
@ 2024-01-23  8:03   ` Rasmus Villemoes
  2024-01-23 21:38     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Rasmus Villemoes @ 2024-01-23  8:03 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On 23/01/2024 01.26, Kees Cook wrote:
> For instances where only the overflow needs to be checked (and the sum
> isn't used), provide the new helper add_would_overflow(), which is
> a wrapper for check_add_overflow().
> 
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: linux-hardening@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  include/linux/overflow.h | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index 099f2e559aa8..ac088f73e0fd 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -108,6 +108,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
>  		__builtin_add_overflow(__filter_integral(a), b,		\
>  				       __filter_ptrint(d))))
>  
> +/**
> + * add_would_overflow() - Check if an addition would overflow
> + * @a: first addend
> + * @b: second addend
> + *
> + * Returns true if the sum would overflow.
> + *
> + * To keep a copy of the sum when the addition doesn't overflow, use
> + * check_add_overflow() instead.
> + */
> +#define add_would_overflow(a, b)			\
> +	__must_check_overflow(({			\
> +		size_t __result;			\
> +		check_add_overflow(a, b, &__result);\
> +	}))

Hm, I think this is a bit too ill-defined. Why is the target type
hard-coded as size_t? What if a and b are u64, and we're on a 32 bit
target? Then a+b might not overflow but this helper would claim it did.

But we also cannot just use typeof(a+b) instead of size_t, since that
breaks when a and b are narrower than int (adding two u16 never
overflows since they get promoted to int, but then if assigning the
result to a u16 one truncates...).

Perhaps the target type must be explicit? sum_fits_in_type(T, a, b) ?
IDK, I just don't think size_t is the right thing to use in something
that is otherwise supposed to be type-generic.

Rasmus


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 27/82] m68k: Refactor intentional wrap-around calculation
  2024-01-23  0:27 ` [PATCH 27/82] m68k: " Kees Cook
  2024-01-23  2:29   ` Liam R. Howlett
@ 2024-01-23  8:13   ` Geert Uytterhoeven
  2024-01-23 13:29     ` Eero Tamminen
  1 sibling, 1 reply; 163+ messages in thread
From: Geert Uytterhoeven @ 2024-01-23  8:13 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Andrew Morton, Arnd Bergmann, Liam Howlett,
	Matthew Wilcox (Oracle),
	Hugh Dickins, linux-m68k, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

Hi Kees,

On Tue, Jan 23, 2024 at 1:35 AM Kees Cook <keescook@chromium.org> wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
>         VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> unsigned wrap-around sanitizer[2] in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Liam Howlett <liam.howlett@oracle.com>
> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> Cc: Hugh Dickins <hughd@google.com>
> Cc: linux-m68k@lists.linux-m68k.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Thanks for your patch!

> --- a/arch/m68k/kernel/sys_m68k.c
> +++ b/arch/m68k/kernel/sys_m68k.c
> @@ -391,10 +391,11 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
>
>                 mmap_read_lock(current->mm);
>         } else {
> +               unsigned long sum;

"sum" sounds like this is a dummy variable, to please the third
parameter of check_add_overflow()...

>                 struct vm_area_struct *vma;
>
>                 /* Check for overflow.  */

I agree with Liam: please drop the comment.

> -               if (addr + len < addr)
> +               if (check_add_overflow(addr, len, &sum))
>                         goto out;
>
>                 /*
> @@ -403,7 +404,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
>                  */
>                 mmap_read_lock(current->mm);
>                 vma = vma_lookup(current->mm, addr);
> -               if (!vma || addr + len > vma->vm_end)
> +               if (!vma || sum > vma->vm_end)

... Oh, it is actually used. What about renaming it to "end" instead?

>                         goto out_unlock;
>         }

With the above fixed:

Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>

If you want me to take this through the m68k tree (for v6.9), please
let me know.
Thanks!

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 03/82] overflow: Introduce add_wrap()
  2024-01-23  0:26 ` [PATCH 03/82] overflow: Introduce add_wrap() Kees Cook
@ 2024-01-23  8:14   ` Rasmus Villemoes
  2024-01-23 21:51     ` Kees Cook
  2024-01-23  9:22   ` Mark Rutland
  1 sibling, 1 reply; 163+ messages in thread
From: Rasmus Villemoes @ 2024-01-23  8:14 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On 23/01/2024 01.26, Kees Cook wrote:
> Provide a helper that will perform wrapping addition without tripping
> the arithmetic wrap-around sanitizers.
> 
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: linux-hardening@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  include/linux/overflow.h | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index ac088f73e0fd..30779905a77a 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -124,6 +124,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
>  		check_add_overflow(a, b, &__result);\
>  	}))
>  
> +/**
> + * add_wrap() - Intentionally perform a wrapping addition
> + * @a: first addend
> + * @b: second addend
> + *
> + * Return the potentially wrapped-around addition without
> + * tripping any overflow sanitizers that may be enabled.
> + */
> +#define add_wrap(a, b)					\
> +	({						\
> +		typeof(a) __sum;			\
> +		if (check_add_overflow(a, b, &__sum))	\
> +			/* do nothing */;		\
> +		__sum;					\
> +	})
> +

I don't know where this is supposed to be used, but at first glance this
seems to introduce a footgun. This is not symmetric in a and b, so both
the type and value of the result may differ between add_wrap(a, b) and
add_wrap(b, a). That seems dangerous.

Rasmus


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 22/82] x86/sgx: Refactor intentional wrap-around calculation
  2024-01-23  0:26 ` [PATCH 22/82] x86/sgx: " Kees Cook
@ 2024-01-23  9:15   ` Jarkko Sakkinen
  0 siblings, 0 replies; 163+ messages in thread
From: Jarkko Sakkinen @ 2024-01-23  9:15 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Dave Hansen, Thomas Gleixner, Ingo Molnar, Borislav Petkov, x86,
	H. Peter Anvin, linux-sgx, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue Jan 23, 2024 at 12:26 AM UTC, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Jarkko Sakkinen <jarkko@kernel.org>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: x86@kernel.org
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: linux-sgx@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/x86/kernel/cpu/sgx/ioctl.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
> index b65ab214bdf5..4b8f6c9f8ef5 100644
> --- a/arch/x86/kernel/cpu/sgx/ioctl.c
> +++ b/arch/x86/kernel/cpu/sgx/ioctl.c
> @@ -350,16 +350,18 @@ static int sgx_validate_offset_length(struct sgx_encl *encl,
>  				      unsigned long offset,
>  				      unsigned long length)
>  {
> +	unsigned long sum;
> +
>  	if (!IS_ALIGNED(offset, PAGE_SIZE))
>  		return -EINVAL;
>  
>  	if (!length || !IS_ALIGNED(length, PAGE_SIZE))
>  		return -EINVAL;
>  
> -	if (offset + length < offset)
> +	if (check_add_overflow(offset, length, &sum))
>  		return -EINVAL;
>  
> -	if (offset + length - PAGE_SIZE >= encl->size)
> +	if (sum - PAGE_SIZE >= encl->size)
>  		return -EINVAL;
>  
>  	return 0;

Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

BR, Jarkko

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 03/82] overflow: Introduce add_wrap()
  2024-01-23  0:26 ` [PATCH 03/82] overflow: Introduce add_wrap() Kees Cook
  2024-01-23  8:14   ` Rasmus Villemoes
@ 2024-01-23  9:22   ` Mark Rutland
  2024-01-23 21:52     ` Kees Cook
  1 sibling, 1 reply; 163+ messages in thread
From: Mark Rutland @ 2024-01-23  9:22 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:26:38PM -0800, Kees Cook wrote:
> Provide a helper that will perform wrapping addition without tripping
> the arithmetic wrap-around sanitizers.
> 
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: linux-hardening@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  include/linux/overflow.h | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index ac088f73e0fd..30779905a77a 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -124,6 +124,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
>  		check_add_overflow(a, b, &__result);\
>  	}))
>  
> +/**
> + * add_wrap() - Intentionally perform a wrapping addition
> + * @a: first addend
> + * @b: second addend
> + *
> + * Return the potentially wrapped-around addition without
> + * tripping any overflow sanitizers that may be enabled.
> + */
> +#define add_wrap(a, b)					\
> +	({						\
> +		typeof(a) __sum;			\
> +		if (check_add_overflow(a, b, &__sum))	\
> +			/* do nothing */;		\
> +		__sum;					\
> +	})

It's really difficult to see the semicolon for the empty statement here; could
we make that part:

		if ((check_add_overflow(a, b, &__sum)) {	\
			/* do nothing */			\
		}						\

... to be a little clearer (and less at risk of breakage in a refactoring)?

I realise coding style says not to use braces for a single statement, but IMO
it's far clearer in this instance with the braces.

Mark.

> +
>  /**
>   * check_sub_overflow() - Calculate subtraction with overflow checking
>   * @a: minuend; value to subtract from
> -- 
> 2.34.1
> 
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 10/82] locking/atomic/x86: Silence intentional wrapping addition
  2024-01-23  0:26 ` [PATCH 10/82] locking/atomic/x86: Silence intentional wrapping addition Kees Cook
@ 2024-01-23  9:27   ` Mark Rutland
  2024-01-23 21:54     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Mark Rutland @ 2024-01-23  9:27 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Will Deacon, Peter Zijlstra, Boqun Feng,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Mon, Jan 22, 2024 at 04:26:45PM -0800, Kees Cook wrote:
> Annotate atomic_add_return() to avoid signed overflow instrumentation.
> It is expected to wrap around.
> 
> Cc: Will Deacon <will@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Boqun Feng <boqun.feng@gmail.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: x86@kernel.org
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/x86/include/asm/atomic.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
> index 55a55ec04350..4120cdd87da8 100644
> --- a/arch/x86/include/asm/atomic.h
> +++ b/arch/x86/include/asm/atomic.h
> @@ -80,7 +80,7 @@ static __always_inline bool arch_atomic_add_negative(int i, atomic_t *v)
>  }
>  #define arch_atomic_add_negative arch_atomic_add_negative
>  
> -static __always_inline int arch_atomic_add_return(int i, atomic_t *v)
> +static __always_inline __signed_wrap int arch_atomic_add_return(int i, atomic_t *v)
>  {
>  	return i + xadd(&v->counter, i);
>  }

I think that here (and in the arm64 patch) it'd be better to use add_wrap() on
the specific statement, i.e. have:

static __always_inline int arch_atomic_add_return(int i, atomic_t *v)
{
	return add_wrap(i, xadd(&v->counter, i));
}

... since otherwise the annotation could applly to the '+' or something else
(e.g. if the 'xadd() part is a special macro), and the annotation might
unexpectedly hide things if we add other statements here in future.

Mark.

> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around
  2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
                   ` (82 preceding siblings ...)
  2024-01-23  2:22 ` [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kent Overstreet
@ 2024-01-23  9:46 ` Mark Rutland
  2024-01-23 21:56   ` Kees Cook
  2024-01-29  6:27   ` Kees Cook
  83 siblings, 2 replies; 163+ messages in thread
From: Mark Rutland @ 2024-01-23  9:46 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:26:35PM -0800, Kees Cook wrote:
> Hi,

Hi Kees,

> In our continuing effort to eliminate root causes of flaws in the kernel,
> this series is the start to providing a way to have sensible coverage
> for catching unexpected arithmetic wrap-around.
> 
> A quick word on language: while discussing[1] the finer details of
> the C standard's view on arithmetic, I was disabused of using the term
> "overflow" when what I really mean is "wrap-around". When describing
> security vulnerabilities, "overflow" is the common term and often used
> interchangeably with "wrap-around". Strictly speaking, though, "overflow"
> applies only to signed[2] and pointer[3] types, and "wrap-around" is for
> unsigned[4]. An arithmetic "overflow" is considered undefined behavior,
> which has caused our builds pain in the past, since "impossible"
> conditions might get elided by the compiler. As a result, we build
> with -fno-strict-overflow which coverts all "overflow" conditions into
> "wrap-around" (i.e. 2s complement), regardless of type.
> 
> All this is to say I am discussing arithmetic wrap-around, which is
> the condition where the value exceeds a type's maximum value (or goes
> below its minimum value) and wraps around. I'm not interested in the
> narrow definition of "undefined behavior" -- we need to stamp out the
> _unexpected_ behavior, where the kernel operates on a pathological value
> that wrapped around without the code author's intent.

With that in mind, I note that this patch primarily modifies addition
operations, but leaves subtraction operations unchanged (even though those
permit the value to go below the minimum, or above the maximum if a negative
value is used as the subtrahend).

Shouldn't we address both at the same time? I'll note that in many places the
same logic is used for both the add and sub, and can legitimately overflow or
underflow; I hope that whatever we use to suppress overflow warnings also
ignores underflow.

[...]

Looking at the diffstat, I think you've missed a few places:

>  Documentation/process/deprecated.rst          | 36 ++++++++
>  arch/arc/kernel/unwind.c                      |  7 +-
>  arch/arm/nwfpe/softfloat.c                    |  2 +-
>  arch/arm64/include/asm/atomic_lse.h           |  8 +-
>  arch/arm64/include/asm/stacktrace/common.h    |  2 +-
>  arch/arm64/kvm/vgic/vgic-kvm-device.c         |  6 +-
>  arch/arm64/kvm/vgic/vgic-mmio-v3.c            |  2 +-
>  arch/arm64/kvm/vgic/vgic-v2.c                 | 10 ++-
>  arch/m68k/kernel/sys_m68k.c                   |  5 +-
>  arch/nios2/kernel/sys_nios2.c                 |  2 +-
>  arch/powerpc/platforms/powernv/opal-prd.c     |  2 +-
>  arch/powerpc/xmon/xmon.c                      |  2 +-
>  arch/s390/include/asm/stacktrace.h            |  6 +-
>  arch/s390/kernel/machine_kexec_file.c         |  5 +-
>  arch/s390/mm/gmap.c                           |  4 +-
>  arch/s390/mm/vmem.c                           |  2 +-
>  arch/sh/kernel/sys_sh.c                       |  2 +-
>  arch/x86/include/asm/atomic.h                 |  2 +-
>  arch/x86/kernel/cpu/sgx/ioctl.c               |  6 +-
>  arch/x86/kvm/svm/sev.c                        |  5 +-
>  crypto/adiantum.c                             |  2 +-
>  drivers/acpi/custom_method.c                  |  2 +-
>  drivers/char/agp/generic.c                    |  2 +-
>  drivers/crypto/amcc/crypto4xx_alg.c           |  2 +-
>  drivers/crypto/axis/artpec6_crypto.c          |  2 +-
>  drivers/dma-buf/dma-buf.c                     |  7 +-
>  drivers/fpga/dfl.c                            |  5 +-
>  drivers/fsi/fsi-core.c                        |  6 +-
>  drivers/gpu/drm/i915/i915_vma.c               |  2 +-
>  drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c |  8 +-
>  drivers/gpu/drm/vc4/vc4_validate.c            |  7 +-
>  drivers/md/dm-switch.c                        |  2 +-
>  drivers/md/dm-verity-target.c                 |  2 +-
>  drivers/md/dm-writecache.c                    |  2 +-
>  drivers/net/ethernet/sun/niu.c                |  5 +-
>  drivers/net/wireless/ath/wil6210/wmi.c        |  2 +-
>  drivers/net/wireless/marvell/mwifiex/pcie.c   |  6 +-
>  drivers/net/xen-netback/hash.c                |  2 +-
>  drivers/pci/pci.c                             |  2 +-
>  drivers/remoteproc/pru_rproc.c                |  2 +-
>  drivers/remoteproc/remoteproc_elf_loader.c    |  2 +-
>  drivers/remoteproc/remoteproc_virtio.c        |  4 +-
>  drivers/scsi/mpt3sas/mpt3sas_ctl.c            |  2 +-
>  drivers/scsi/sd_zbc.c                         |  2 +-
>  drivers/staging/vme_user/vme.c                |  2 +-
>  drivers/vhost/vringh.c                        |  8 +-
>  drivers/virtio/virtio_pci_modern_dev.c        |  4 +-
>  fs/aio.c                                      |  2 +-
>  fs/bcachefs/bkey.c                            |  4 +-
>  fs/bcachefs/fs.c                              |  2 +-
>  fs/bcachefs/quota.c                           |  2 +-
>  fs/bcachefs/util.c                            |  2 +-
>  fs/btrfs/extent_map.c                         |  6 +-
>  fs/btrfs/extent_map.h                         |  6 +-
>  fs/btrfs/ordered-data.c                       |  2 +-
>  fs/ext4/block_validity.c                      |  2 +-
>  fs/ext4/extents.c                             |  5 +-
>  fs/ext4/resize.c                              |  2 +-
>  fs/f2fs/file.c                                |  2 +-
>  fs/f2fs/verity.c                              |  2 +-
>  fs/hpfs/alloc.c                               |  2 +-
>  fs/ntfs3/record.c                             |  4 +-
>  fs/ocfs2/resize.c                             |  2 +-
>  fs/read_write.c                               |  8 +-
>  fs/remap_range.c                              |  2 +-
>  fs/select.c                                   | 13 +--
>  fs/smb/client/readdir.c                       |  5 +-
>  fs/smb/client/smb2pdu.c                       |  4 +-
>  fs/udf/balloc.c                               |  4 +-
>  include/linux/compiler_types.h                | 29 +++++-

This misses the include/asm-generic/{atomic,atomic64}.h implementations.

This also misses the include/linux/atomic/atomic-arch-fallback.h
implementations. Those are generated from the scripts/atomic/fallbacks/*
templates, and you'll need to adjust at least fetch_add_unless and
inc_unless_negative. As noted on other patches, my preference is to use
add_wrap() in those.

>  include/linux/overflow.h                      | 76 +++++++++++++++-
>  ipc/mqueue.c                                  |  2 +-
>  ipc/shm.c                                     |  6 +-
>  kernel/bpf/verifier.c                         | 12 +--
>  kernel/time/timekeeping.c                     |  2 +-
>  lib/Kconfig.ubsan                             | 27 ++++++

This misses lib/atomic64.c.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 11/82] arm64: atomics: lse: Silence intentional wrapping addition
  2024-01-23  0:26 ` [PATCH 11/82] arm64: atomics: lse: " Kees Cook
@ 2024-01-23  9:53   ` Mark Rutland
  0 siblings, 0 replies; 163+ messages in thread
From: Mark Rutland @ 2024-01-23  9:53 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Will Deacon, Peter Zijlstra, Boqun Feng,
	Catalin Marinas, linux-arm-kernel, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:26:46PM -0800, Kees Cook wrote:
> Annotate atomic_add_return() and atomic_sub_return() to avoid signed
> overflow instrumentation. They are expected to wrap around.
> 
> Cc: Will Deacon <will@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Boqun Feng <boqun.feng@gmail.com>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/arm64/include/asm/atomic_lse.h | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
> index 87f568a94e55..30572458d702 100644
> --- a/arch/arm64/include/asm/atomic_lse.h
> +++ b/arch/arm64/include/asm/atomic_lse.h
> @@ -79,13 +79,13 @@ ATOMIC_FETCH_OP_SUB(        )
>  #undef ATOMIC_FETCH_OP_SUB
>  
>  #define ATOMIC_OP_ADD_SUB_RETURN(name)					\
> -static __always_inline int						\
> +static __always_inline __signed_wrap int				\
>  __lse_atomic_add_return##name(int i, atomic_t *v)			\
>  {									\
>  	return __lse_atomic_fetch_add##name(i, v) + i;			\
>  }									\

I'd strongly prefer using add_wrap() rather than annotating the function, i.e.
make this:

  static __always_inline int						\
  __lse_atomic_add_return##name(int i, atomic_t *v)			\
  {									\
  	return add_wrap(__lse_atomic_fetch_add##name(i, v), i);		\
  }									\

Likewise for the other instances below.

With that, this looks fine to me.

Mark.

>  									\
> -static __always_inline int						\
> +static __always_inline __signed_wrap int				\
>  __lse_atomic_sub_return##name(int i, atomic_t *v)			\
>  {									\
>  	return __lse_atomic_fetch_sub(i, v) - i;			\
> @@ -186,13 +186,13 @@ ATOMIC64_FETCH_OP_SUB(        )
>  #undef ATOMIC64_FETCH_OP_SUB
>  
>  #define ATOMIC64_OP_ADD_SUB_RETURN(name)				\
> -static __always_inline long						\
> +static __always_inline __signed_wrap long				\
>  __lse_atomic64_add_return##name(s64 i, atomic64_t *v)			\
>  {									\
>  	return __lse_atomic64_fetch_add##name(i, v) + i;		\
>  }									\
>  									\
> -static __always_inline long						\
> +static __always_inline __signed_wrap long				\
>  __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)			\
>  {									\
>  	return __lse_atomic64_fetch_sub##name(i, v) - i;		\
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 38/82] arm: 3117/1: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 38/82] arm: 3117/1: " Kees Cook
@ 2024-01-23  9:56   ` Mark Rutland
  2024-01-23 22:41     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Mark Rutland @ 2024-01-23  9:56 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Russell King, linux-arm-kernel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

The commit title is odd here; '3117/1' is the patch tracker name for the last
patch. The title should probably be:

	arm: nwfpe: Refactor intentional wrap-around test

Mark.

On Mon, Jan 22, 2024 at 04:27:13PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: linux-arm-kernel@lists.infradead.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/arm/nwfpe/softfloat.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
> index ffa6b438786b..0635b1eda1d3 100644
> --- a/arch/arm/nwfpe/softfloat.c
> +++ b/arch/arm/nwfpe/softfloat.c
> @@ -603,7 +603,7 @@ static floatx80
>      roundBits = zSig0 & roundMask;
>      if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
>          if (    ( 0x7FFE < zExp )
> -             || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
> +             || ( ( zExp == 0x7FFE ) && (add_would_overflow(zSig0, roundIncrement)) )
>             ) {
>              goto overflow;
>          }
> -- 
> 2.34.1
> 
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 40/82] arm64: stacktrace: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 40/82] arm64: stacktrace: " Kees Cook
@ 2024-01-23  9:58   ` Mark Rutland
  0 siblings, 0 replies; 163+ messages in thread
From: Mark Rutland @ 2024-01-23  9:58 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Catalin Marinas, Will Deacon, Kalesh Singh,
	Fuad Tabba, Mark Brown, Madhavan T. Venkataraman, Marc Zyngier,
	linux-arm-kernel, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:15PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Kalesh Singh <kaleshsingh@google.com>
> Cc: Fuad Tabba <tabba@google.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>
> Cc: Marc Zyngier <maz@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/arm64/include/asm/stacktrace/common.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/stacktrace/common.h b/arch/arm64/include/asm/stacktrace/common.h
> index f63dc654e545..6e0cb84961f8 100644
> --- a/arch/arm64/include/asm/stacktrace/common.h
> +++ b/arch/arm64/include/asm/stacktrace/common.h
> @@ -49,7 +49,7 @@ static inline bool stackinfo_on_stack(const struct stack_info *info,
>  	if (!info->low)
>  		return false;
>  
> -	if (sp < info->low || sp + size < sp || sp + size > info->high)
> +	if (sp < info->low || add_would_overflow(sp, size) || sp + size > info->high)
>  		return false;

This looks fine to me, so FWIW:

Acked-by: Mark Rutland <mark.rutland@arm.com>

Mark.

>  
>  	return true;
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 24/82] KVM: arm64: vgic: Refactor intentional wrap-around calculation
  2024-01-23  0:26 ` [PATCH 24/82] KVM: arm64: vgic: " Kees Cook
@ 2024-01-23 10:49   ` Marc Zyngier
  2024-01-24 15:13     ` Eric Auger
  0 siblings, 1 reply; 163+ messages in thread
From: Marc Zyngier @ 2024-01-23 10:49 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Reiji Watanabe,
	Eric Auger, Ricardo Koller, Raghavendra Rao Ananta,
	Quentin Perret, Jean-Philippe Brucker, linux-arm-kernel, kvmarm,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Tue, 23 Jan 2024 00:26:59 +0000,
Kees Cook <keescook@chromium.org> wrote:
> 
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Marc Zyngier <maz@kernel.org>
> Cc: Oliver Upton <oliver.upton@linux.dev>
> Cc: James Morse <james.morse@arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> Cc: Zenghui Yu <yuzenghui@huawei.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Reiji Watanabe <reijiw@google.com>
> Cc: Eric Auger <eric.auger@redhat.com>
> Cc: Ricardo Koller <ricarkol@google.com>
> Cc: Raghavendra Rao Ananta <rananta@google.com>
> Cc: Quentin Perret <qperret@google.com>
> Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: kvmarm@lists.linux.dev
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/arm64/kvm/vgic/vgic-kvm-device.c |  6 ++++--
>  arch/arm64/kvm/vgic/vgic-v2.c         | 10 ++++++----
>  2 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
> index f48b8dab8b3d..0eec5344d203 100644
> --- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
> +++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
> @@ -18,17 +18,19 @@ int vgic_check_iorange(struct kvm *kvm, phys_addr_t ioaddr,
>  		       phys_addr_t addr, phys_addr_t alignment,
>  		       phys_addr_t size)
>  {
> +	phys_addr_t sum;
> +
>  	if (!IS_VGIC_ADDR_UNDEF(ioaddr))
>  		return -EEXIST;
>  
>  	if (!IS_ALIGNED(addr, alignment) || !IS_ALIGNED(size, alignment))
>  		return -EINVAL;
>  
> -	if (addr + size < addr)
> +	if (check_add_overflow(addr, size, &sum))
>  		return -EINVAL;
>  
>  	if (addr & ~kvm_phys_mask(&kvm->arch.mmu) ||
> -	    (addr + size) > kvm_phys_size(&kvm->arch.mmu))
> +	    sum > kvm_phys_size(&kvm->arch.mmu))

nit: 'sum' doesn't mean much in this context. Something like 'end'
would be much more descriptive.

>  		return -E2BIG;
>  
>  	return 0;
> diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
> index 7e9cdb78f7ce..c8d1e965d3b7 100644
> --- a/arch/arm64/kvm/vgic/vgic-v2.c
> +++ b/arch/arm64/kvm/vgic/vgic-v2.c
> @@ -273,14 +273,16 @@ void vgic_v2_enable(struct kvm_vcpu *vcpu)
>  /* check for overlapping regions and for regions crossing the end of memory */
>  static bool vgic_v2_check_base(gpa_t dist_base, gpa_t cpu_base)
>  {
> -	if (dist_base + KVM_VGIC_V2_DIST_SIZE < dist_base)
> +	gpa_t dist_sum, cpu_sum;

Same here: dist_end, cpu_end.

> +
> +	if (check_add_overflow(dist_base, KVM_VGIC_V2_DIST_SIZE, &dist_sum))
>  		return false;
> -	if (cpu_base + KVM_VGIC_V2_CPU_SIZE < cpu_base)
> +	if (check_add_overflow(cpu_base, KVM_VGIC_V2_CPU_SIZE, &cpu_sum))
>  		return false;
>  
> -	if (dist_base + KVM_VGIC_V2_DIST_SIZE <= cpu_base)
> +	if (dist_sum <= cpu_base)
>  		return true;
> -	if (cpu_base + KVM_VGIC_V2_CPU_SIZE <= dist_base)
> +	if (cpu_sum <= dist_base)
>  		return true;
>  
>  	return false;

With these nits addressed, and assuming you intend to merge the whole
series yourself:

Acked-by: Marc Zyngier <maz@kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 57/82] KVM: arm64: vgic-v3: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 57/82] KVM: arm64: vgic-v3: " Kees Cook
@ 2024-01-23 10:50   ` Marc Zyngier
  2024-01-24 15:12   ` Eric Auger
  1 sibling, 0 replies; 163+ messages in thread
From: Marc Zyngier @ 2024-01-23 10:50 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Eric Auger,
	linux-arm-kernel, kvmarm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, 23 Jan 2024 00:27:32 +0000,
Kees Cook <keescook@chromium.org> wrote:
> 
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Marc Zyngier <maz@kernel.org>
> Cc: Oliver Upton <oliver.upton@linux.dev>
> Cc: James Morse <james.morse@arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> Cc: Zenghui Yu <yuzenghui@huawei.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Eric Auger <eric.auger@redhat.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: kvmarm@lists.linux.dev
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/arm64/kvm/vgic/vgic-mmio-v3.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> index c15ee1df036a..860b774c0c13 100644
> --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> @@ -863,7 +863,7 @@ static int vgic_v3_alloc_redist_region(struct kvm *kvm, uint32_t index,
>  	int ret;
>  
>  	/* cross the end of memory ? */
> -	if (base + size < base)
> +	if (add_would_overflow(base, size))
>  		return -EINVAL;
>  
>  	if (list_empty(rd_regions)) {

Acked-by: Marc Zyngier <maz@kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers
  2024-01-23  4:45     ` Kees Cook
@ 2024-01-23 11:20       ` Miguel Ojeda
  0 siblings, 0 replies; 163+ messages in thread
From: Miguel Ojeda @ 2024-01-23 11:20 UTC (permalink / raw)
  To: Kees Cook
  Cc: Kees Cook, linux-hardening, Justin Stitt, Miguel Ojeda,
	Nathan Chancellor, Nick Desaulniers, Peter Zijlstra, Marco Elver,
	Hao Luo, Przemek Kitszel, Gustavo A. R. Silva, Bill Wendling,
	linux-kernel

On Tue, Jan 23, 2024 at 5:45 AM Kees Cook <kees@kernel.org> wrote:
>
> Yes. We removed this bad behavior by using -fno-strict-overflow, and we will want to keep it enabled.

Yeah, I only meant that the wording of the commit seems to say there
is something special about the "overflowing behavior", i.e. I was
expecting just UB with the usual implications, but given the extra
text in the parenthesis, I wondered while reading it if there was
something different/special going on.

> The stack usage is separate. (This may even be fixed in modern Clang; this comes from the original version of this Kconfig.) The not booting part is separate and has not been tracked down yet.

I see. Thanks! In any case, if the sentence means only 32-bit x86,
users couldn't still see it. But since this was already in the revert
now that I take a look, I guess ignore this :)

> I wondered the same -- they were this way when they were removed, so I just restored them as they were. :)

Makes sense :)

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 41/82] wil6210: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 41/82] wil6210: " Kees Cook
  2024-01-23  6:36   ` Kalle Valo
@ 2024-01-23 11:50   ` Kalle Valo
  2024-01-23 22:52     ` Kees Cook
  1 sibling, 1 reply; 163+ messages in thread
From: Kalle Valo @ 2024-01-23 11:50 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Kees Cook, Johannes Berg, Max Chen, Yang Shen,
	linux-wireless, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

Kees Cook <keescook@chromium.org> wrote:

> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Kalle Valo <kvalo@kernel.org>
> Cc: Johannes Berg <johannes.berg@intel.com>
> Cc: Max Chen <mxchen@codeaurora.org>
> Cc: Yang Shen <shenyang39@huawei.com>
> Cc: linux-wireless@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> Acked-by: Kalle Valo <kvalo@kernel.org>

If you can edit before commit please add "wifi:" prefix to the wireless patches:

ERROR: 'wifi:' prefix missing: '[PATCH 41/82] wil6210: Refactor intentional wrap-around test'
ERROR: 'wifi:' prefix missing: '[PATCH 62/82] mwifiex: pcie: Refactor intentional wrap-around test'

2 patches set to Not Applicable.

13526631 [41/82] wil6210: Refactor intentional wrap-around test
13526632 [62/82] mwifiex: pcie: Refactor intentional wrap-around test

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20240123002814.1396804-41-keescook@chromium.org/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 65/82] nios2: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 65/82] nios2: " Kees Cook
@ 2024-01-23 13:15   ` Dinh Nguyen
  0 siblings, 0 replies; 163+ messages in thread
From: Dinh Nguyen @ 2024-01-23 13:15 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Jann Horn, Ley Foon Tan, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On 1/22/24 18:27, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Dinh Nguyen <dinguyen@kernel.org>
> Cc: Jann Horn <jannh@google.com>
> Cc: Ley Foon Tan <ley.foon.tan@intel.com>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>   arch/nios2/kernel/sys_nios2.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Dinh Nguyen <dinguyen@kernel.org>


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 27/82] m68k: Refactor intentional wrap-around calculation
  2024-01-23  8:13   ` Geert Uytterhoeven
@ 2024-01-23 13:29     ` Eero Tamminen
  2024-01-23 13:42       ` Geert Uytterhoeven
  0 siblings, 1 reply; 163+ messages in thread
From: Eero Tamminen @ 2024-01-23 13:29 UTC (permalink / raw)
  To: Geert Uytterhoeven, Kees Cook
  Cc: linux-hardening, Andrew Morton, Arnd Bergmann, Liam Howlett,
	Matthew Wilcox (Oracle),
	Hugh Dickins, linux-m68k, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

Hi,

On 23.1.2024 10.13, Geert Uytterhoeven wrote:
> On Tue, Jan 23, 2024 at 1:35 AM Kees Cook <keescook@chromium.org> wrote:
>> In an effort to separate intentional arithmetic wrap-around from
>> unexpected wrap-around, we need to refactor places that depend on this
>> kind of math. One of the most common code patterns of this is:
>>
>>          VAR + value < VAR
>>
>> Notably, this is considered "undefined behavior" for signed and pointer
>> types, which the kernel works around by using the -fno-strict-overflow
>> option in the build[1] (which used to just be -fwrapv). Regardless, we
>> want to get the kernel source to the position where we can meaningfully
>> instrument arithmetic wrap-around conditions and catch them when they
>> are unexpected, regardless of whether they are signed[2], unsigned[3],
>> or pointer[4] types.
>>
>> Refactor open-coded unsigned wrap-around addition test to use
>> check_add_overflow(), retaining the result for later usage (which removes
>> the redundant open-coded addition). This paves the way to enabling the
>> unsigned wrap-around sanitizer[2] in the future.
>>
>> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
>> Link: https://github.com/KSPP/linux/issues/26 [2]
>> Link: https://github.com/KSPP/linux/issues/27 [3]
>> Link: https://github.com/KSPP/linux/issues/344 [4]
>> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
>> Cc: Andrew Morton <akpm@linux-foundation.org>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Cc: Liam Howlett <liam.howlett@oracle.com>
>> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>> Cc: Hugh Dickins <hughd@google.com>
>> Cc: linux-m68k@lists.linux-m68k.org
>> Signed-off-by: Kees Cook <keescook@chromium.org>
> 
> Thanks for your patch!
> 
>> --- a/arch/m68k/kernel/sys_m68k.c
>> +++ b/arch/m68k/kernel/sys_m68k.c
>> @@ -391,10 +391,11 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
>>
>>                  mmap_read_lock(current->mm);
>>          } else {
>> +               unsigned long sum;
> 
> "sum" sounds like this is a dummy variable, to please the third
> parameter of check_add_overflow()...
> 
>>                  struct vm_area_struct *vma;
>>
>>                  /* Check for overflow.  */
> 
> I agree with Liam: please drop the comment.
> 
>> -               if (addr + len < addr)
>> +               if (check_add_overflow(addr, len, &sum))
>>                          goto out;
>>
>>                  /*
>> @@ -403,7 +404,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
>>                   */
>>                  mmap_read_lock(current->mm);
>>                  vma = vma_lookup(current->mm, addr);
>> -               if (!vma || addr + len > vma->vm_end)
>> +               if (!vma || sum > vma->vm_end)
> 
> ... Oh, it is actually used. What about renaming it to "end" instead?

IMHO this is more descriptive:
+               if (check_add_overflow(addr, len, &sum))

than this:
+               if (check_add_overflow(addr, len, &end))

"sum" is IMHO quite obviously sum of the preceding args, whereas I do 
not know what "end" would be.


	- Eero

>>                          goto out_unlock;
>>          }
> 
> With the above fixed:
> 
> Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
> 
> If you want me to take this through the m68k tree (for v6.9), please
> let me know.
> Thanks!
> 
> Gr{oetje,eeting}s,
> 
>                          Geert
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 27/82] m68k: Refactor intentional wrap-around calculation
  2024-01-23 13:29     ` Eero Tamminen
@ 2024-01-23 13:42       ` Geert Uytterhoeven
  0 siblings, 0 replies; 163+ messages in thread
From: Geert Uytterhoeven @ 2024-01-23 13:42 UTC (permalink / raw)
  To: Eero Tamminen
  Cc: Kees Cook, linux-hardening, Andrew Morton, Arnd Bergmann,
	Liam Howlett, Matthew Wilcox (Oracle),
	Hugh Dickins, linux-m68k, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

Hi Eero,

On Tue, Jan 23, 2024 at 2:30 PM Eero Tamminen <oak@helsinkinet.fi> wrote:
> On 23.1.2024 10.13, Geert Uytterhoeven wrote:
> > On Tue, Jan 23, 2024 at 1:35 AM Kees Cook <keescook@chromium.org> wrote:
> >> In an effort to separate intentional arithmetic wrap-around from
> >> unexpected wrap-around, we need to refactor places that depend on this
> >> kind of math. One of the most common code patterns of this is:
> >>
> >>          VAR + value < VAR
> >>
> >> Notably, this is considered "undefined behavior" for signed and pointer
> >> types, which the kernel works around by using the -fno-strict-overflow
> >> option in the build[1] (which used to just be -fwrapv). Regardless, we
> >> want to get the kernel source to the position where we can meaningfully
> >> instrument arithmetic wrap-around conditions and catch them when they
> >> are unexpected, regardless of whether they are signed[2], unsigned[3],
> >> or pointer[4] types.
> >>
> >> Refactor open-coded unsigned wrap-around addition test to use
> >> check_add_overflow(), retaining the result for later usage (which removes
> >> the redundant open-coded addition). This paves the way to enabling the
> >> unsigned wrap-around sanitizer[2] in the future.
> >>
> >> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> >> Link: https://github.com/KSPP/linux/issues/26 [2]
> >> Link: https://github.com/KSPP/linux/issues/27 [3]
> >> Link: https://github.com/KSPP/linux/issues/344 [4]
> >> Cc: Geert Uytterhoeven <geert@linux-m68k.org>
> >> Cc: Andrew Morton <akpm@linux-foundation.org>
> >> Cc: Arnd Bergmann <arnd@arndb.de>
> >> Cc: Liam Howlett <liam.howlett@oracle.com>
> >> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> >> Cc: Hugh Dickins <hughd@google.com>
> >> Cc: linux-m68k@lists.linux-m68k.org
> >> Signed-off-by: Kees Cook <keescook@chromium.org>
> >
> > Thanks for your patch!
> >
> >> --- a/arch/m68k/kernel/sys_m68k.c
> >> +++ b/arch/m68k/kernel/sys_m68k.c
> >> @@ -391,10 +391,11 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
> >>
> >>                  mmap_read_lock(current->mm);
> >>          } else {
> >> +               unsigned long sum;
> >
> > "sum" sounds like this is a dummy variable, to please the third
> > parameter of check_add_overflow()...
> >
> >>                  struct vm_area_struct *vma;
> >>
> >>                  /* Check for overflow.  */
> >
> > I agree with Liam: please drop the comment.
> >
> >> -               if (addr + len < addr)
> >> +               if (check_add_overflow(addr, len, &sum))
> >>                          goto out;
> >>
> >>                  /*
> >> @@ -403,7 +404,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
> >>                   */
> >>                  mmap_read_lock(current->mm);
> >>                  vma = vma_lookup(current->mm, addr);
> >> -               if (!vma || addr + len > vma->vm_end)
> >> +               if (!vma || sum > vma->vm_end)
> >
> > ... Oh, it is actually used. What about renaming it to "end" instead?
>
> IMHO this is more descriptive:
> +               if (check_add_overflow(addr, len, &sum))
>
> than this:
> +               if (check_add_overflow(addr, len, &end))
>
> "sum" is IMHO quite obviously sum of the preceding args, whereas I do
> not know what "end" would be.

"end" is the end of the block of size "len" pointed to by "addr".

IMHO "if (sum > vma->vm_end)" is less descriptive...

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 37/82] aio: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 37/82] aio: " Kees Cook
@ 2024-01-23 15:30   ` Christian Brauner
  2024-01-23 18:03   ` Jan Kara
  1 sibling, 0 replies; 163+ messages in thread
From: Christian Brauner @ 2024-01-23 15:30 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Benjamin LaHaise, Alexander Viro, Jan Kara,
	linux-aio, linux-fsdevel, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:12PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Benjamin LaHaise <bcrl@kvack.org>
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: linux-aio@kvack.org
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---

What's the plan?
Merge the generic infrastructure and we can pick the individual patches?

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 76/82] udf: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 76/82] udf: " Kees Cook
@ 2024-01-23 17:14   ` Jan Kara
  0 siblings, 0 replies; 163+ messages in thread
From: Jan Kara @ 2024-01-23 17:14 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Jan Kara, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon 22-01-24 16:27:51, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Jan Kara <jack@suse.com>
> Signed-off-by: Kees Cook <keescook@chromium.org>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/udf/balloc.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
> index ab3ffc355949..5c88300c3de7 100644
> --- a/fs/udf/balloc.c
> +++ b/fs/udf/balloc.c
> @@ -139,7 +139,7 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
>  
>  	mutex_lock(&sbi->s_alloc_mutex);
>  	partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
> -	if (bloc->logicalBlockNum + count < count ||
> +	if (add_would_overflow(count, bloc->logicalBlockNum) ||
>  	    (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
>  		udf_debug("%u < %d || %u + %u > %u\n",
>  			  bloc->logicalBlockNum, 0,
> @@ -390,7 +390,7 @@ static void udf_table_free_blocks(struct super_block *sb,
>  
>  	mutex_lock(&sbi->s_alloc_mutex);
>  	partmap = &sbi->s_partmaps[bloc->partitionReferenceNum];
> -	if (bloc->logicalBlockNum + count < count ||
> +	if (add_would_overflow(count, bloc->logicalBlockNum) ||
>  	    (bloc->logicalBlockNum + count) > partmap->s_partition_len) {
>  		udf_debug("%u < %d || %u + %u > %u\n",
>  			  bloc->logicalBlockNum, 0,
> -- 
> 2.34.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 09/82] select: Avoid wrap-around instrumentation in do_sys_poll()
  2024-01-23  0:26 ` [PATCH 09/82] select: Avoid wrap-around instrumentation in do_sys_poll() Kees Cook
@ 2024-01-23 18:00   ` Jan Kara
  0 siblings, 0 replies; 163+ messages in thread
From: Jan Kara @ 2024-01-23 18:00 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Alexander Viro, Christian Brauner, Jan Kara,
	linux-fsdevel, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Mon 22-01-24 16:26:44, Kees Cook wrote:
> The mix of int, unsigned int, and unsigned long used by struct
> poll_list::len, todo, len, and j meant that the signed overflow
> sanitizer got worried it needed to instrument several places where
> arithmetic happens between these variables. Since all of the variables
> are always positive and bounded by unsigned int, use a single type in
> all places. Additionally expand the zero-test into an explicit range
> check before updating "todo".
> 
> This keeps sanitizer instrumentation[1] out of a UACCESS path:
> 
> vmlinux.o: warning: objtool: do_sys_poll+0x285: call to __ubsan_handle_sub_overflow() with UACCESS enabled
> 
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/select.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/select.c b/fs/select.c
> index 0ee55af1a55c..11a3b1312abe 100644
> --- a/fs/select.c
> +++ b/fs/select.c
> @@ -839,7 +839,7 @@ SYSCALL_DEFINE1(old_select, struct sel_arg_struct __user *, arg)
>  
>  struct poll_list {
>  	struct poll_list *next;
> -	int len;
> +	unsigned int len;
>  	struct pollfd entries[];
>  };
>  
> @@ -975,14 +975,15 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
>  		struct timespec64 *end_time)
>  {
>  	struct poll_wqueues table;
> -	int err = -EFAULT, fdcount, len;
> +	int err = -EFAULT, fdcount;
>  	/* Allocate small arguments on the stack to save memory and be
>  	   faster - use long to make sure the buffer is aligned properly
>  	   on 64 bit archs to avoid unaligned access */
>  	long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
>  	struct poll_list *const head = (struct poll_list *)stack_pps;
>   	struct poll_list *walk = head;
> - 	unsigned long todo = nfds;
> +	unsigned int todo = nfds;
> +	unsigned int len;
>  
>  	if (nfds > rlimit(RLIMIT_NOFILE))
>  		return -EINVAL;
> @@ -998,9 +999,9 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
>  					sizeof(struct pollfd) * walk->len))
>  			goto out_fds;
>  
> -		todo -= walk->len;
> -		if (!todo)
> +		if (walk->len >= todo)
>  			break;
> +		todo -= walk->len;
>  
>  		len = min(todo, POLLFD_PER_PAGE);
>  		walk = walk->next = kmalloc(struct_size(walk, entries, len),
> @@ -1020,7 +1021,7 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds,
>  
>  	for (walk = head; walk; walk = walk->next) {
>  		struct pollfd *fds = walk->entries;
> -		int j;
> +		unsigned int j;
>  
>  		for (j = walk->len; j; fds++, ufds++, j--)
>  			unsafe_put_user(fds->revents, &ufds->revents, Efault);
> -- 
> 2.34.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 44/82] btrfs: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 44/82] btrfs: " Kees Cook
@ 2024-01-23 18:00   ` David Sterba
  0 siblings, 0 replies; 163+ messages in thread
From: David Sterba @ 2024-01-23 18:00 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Chris Mason, Josef Bacik, David Sterba,
	linux-btrfs, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Mon, Jan 22, 2024 at 04:27:19PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Chris Mason <clm@fb.com>
> Cc: Josef Bacik <josef@toxicpanda.com>
> Cc: David Sterba <dsterba@suse.com>
> Cc: linux-btrfs@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Acked-by: David Sterba <dsterba@suse.com>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 19/82] fs: Refactor intentional wrap-around calculation
  2024-01-23  0:26 ` [PATCH 19/82] fs: " Kees Cook
@ 2024-01-23 18:01   ` Jan Kara
  0 siblings, 0 replies; 163+ messages in thread
From: Jan Kara @ 2024-01-23 18:01 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Alexander Viro, Christian Brauner, Jan Kara,
	linux-fsdevel, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Mon 22-01-24 16:26:54, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/read_write.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/read_write.c b/fs/read_write.c
> index d4c036e82b6c..e24b94a8937d 100644
> --- a/fs/read_write.c
> +++ b/fs/read_write.c
> @@ -1417,6 +1417,7 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
>  	struct inode *inode_out = file_inode(file_out);
>  	uint64_t count = *req_count;
>  	loff_t size_in;
> +	loff_t sum_in, sum_out;
>  	int ret;
>  
>  	ret = generic_file_rw_checks(file_in, file_out);
> @@ -1451,7 +1452,8 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
>  		return -ETXTBSY;
>  
>  	/* Ensure offsets don't wrap. */
> -	if (pos_in + count < pos_in || pos_out + count < pos_out)
> +	if (check_add_overflow(pos_in, count, &sum_in) ||
> +	    check_add_overflow(pos_out, count, &sum_out))
>  		return -EOVERFLOW;
>  
>  	/* Shorten the copy to EOF */
> @@ -1467,8 +1469,8 @@ static int generic_copy_file_checks(struct file *file_in, loff_t pos_in,
>  
>  	/* Don't allow overlapped copying within the same file. */
>  	if (inode_in == inode_out &&
> -	    pos_out + count > pos_in &&
> -	    pos_out < pos_in + count)
> +	    sum_out > pos_in &&
> +	    pos_out < sum_in)
>  		return -EINVAL;
>  
>  	*req_count = count;
> -- 
> 2.34.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 53/82] fs: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 53/82] fs: " Kees Cook
@ 2024-01-23 18:02   ` Jan Kara
  0 siblings, 0 replies; 163+ messages in thread
From: Jan Kara @ 2024-01-23 18:02 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Alexander Viro, Christian Brauner, Jan Kara,
	linux-fsdevel, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Mon 22-01-24 16:27:28, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Looks good atlhough I'd prefer wrapping the line to not overflow 80 chars.
Anyway feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/remap_range.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/remap_range.c b/fs/remap_range.c
> index f8c1120b8311..15e91bf2c5e3 100644
> --- a/fs/remap_range.c
> +++ b/fs/remap_range.c
> @@ -45,7 +45,7 @@ static int generic_remap_checks(struct file *file_in, loff_t pos_in,
>  		return -EINVAL;
>  
>  	/* Ensure offsets don't wrap. */
> -	if (pos_in + count < pos_in || pos_out + count < pos_out)
> +	if (add_would_overflow(pos_in, count) || add_would_overflow(pos_out, count))
>  		return -EINVAL;
>  
>  	size_in = i_size_read(inode_in);
> -- 
> 2.34.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 64/82] netfilter: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 64/82] netfilter: " Kees Cook
@ 2024-01-23 18:03   ` Florian Westphal
  0 siblings, 0 replies; 163+ messages in thread
From: Florian Westphal @ 2024-01-23 18:03 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Pablo Neira Ayuso, Jozsef Kadlecsik,
	Florian Westphal, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, netfilter-devel, coreteam, netdev,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

Kees Cook <keescook@chromium.org> wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR

Acked-by: Florian Westphal <fw@strlen.de>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 37/82] aio: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 37/82] aio: " Kees Cook
  2024-01-23 15:30   ` Christian Brauner
@ 2024-01-23 18:03   ` Jan Kara
  1 sibling, 0 replies; 163+ messages in thread
From: Jan Kara @ 2024-01-23 18:03 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Benjamin LaHaise, Alexander Viro,
	Christian Brauner, Jan Kara, linux-aio, linux-fsdevel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon 22-01-24 16:27:12, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Benjamin LaHaise <bcrl@kvack.org>
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: linux-aio@kvack.org
> Cc: linux-fsdevel@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>

Looks good. Feel free to add:

Reviewed-by: Jan Kara <jack@suse.cz>

								Honza

> ---
>  fs/aio.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/aio.c b/fs/aio.c
> index bb2ff48991f3..edd19be3f4b1 100644
> --- a/fs/aio.c
> +++ b/fs/aio.c
> @@ -796,7 +796,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
>  	/* limit the number of system wide aios */
>  	spin_lock(&aio_nr_lock);
>  	if (aio_nr + ctx->max_reqs > aio_max_nr ||
> -	    aio_nr + ctx->max_reqs < aio_nr) {
> +	    add_would_overflow(aio_nr, ctx->max_reqs)) {
>  		spin_unlock(&aio_nr_lock);
>  		err = -EAGAIN;
>  		goto err_ctx;
> -- 
> 2.34.1
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 34/82] ipc: Refactor intentional wrap-around calculation
  2024-01-23  1:38     ` Kees Cook
@ 2024-01-23 18:06       ` Linus Torvalds
  2024-01-23 19:00         ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Linus Torvalds @ 2024-01-23 18:06 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Andrew Morton, Liam R. Howlett, Mark Brown,
	Mike Kravetz, Vasily Averin, Alexander Mikhalitsyn,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, 22 Jan 2024 at 17:38, Kees Cook <keescook@chromium.org> wrote:
>
> I've tried to find the right balance between not enough details and too
> much. I guess I got it wrong.

My complaint isn't about the level of detail.

My complaint is about how the commit log IS ACTIVELY MISLEADING
GARBAGE and does not match the actual patch in any way, shape, or
form.

It talks about completely irrelevant issues that simply have nothing
to do with it.

It talks about undefined behavior and about a "unsigned wrap-around
sanitizer[2]", which is nonsensical, since there is no undefined
behavior to sanitize. It literally gives a link to a github "issue"
for that claim, but when you follow the link, it's actually about
*signed* overflow, which is something entirely different.

And honestly, the patch itself is garbage. The code is fine. Any
"sanitizer" that complains about that code is pure and utter shite.

Really.

If you actually have some real "detect unsigned wraparound" tool
(NOTE: that is *NOT* undefined behavior, and that is *NOT* a
"sanitizer", it's at most some helpful checker), then such a tool had
better recognize the perfectly fine traditional idiom for this, which
is to do the addition and check that the result is smaller. Like the
code does.

See what I'm saying? The patch is garbage. Any sanitizer that would
complain about the old code is garbage. And the commit message is
worse than garbage, it is actively misleading to the point that I'd
call it lying, trying to confuse the issues by bringing up things that
are utterly and entirely irrelevant to the patch.

So:

 - get rid of that commit message that is lying garbage

 - fix the so-called "sanitizer".

 - stop calling the unsigned wrap-around a "sanitizer" and talking
about "undefined behavior" in the same sentence, since it's neither.

Do you really not see why I think that thing is actively *WRONG*?

           Linus

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 34/82] ipc: Refactor intentional wrap-around calculation
  2024-01-23 18:06       ` Linus Torvalds
@ 2024-01-23 19:00         ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 19:00 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-hardening, Andrew Morton, Liam R. Howlett, Mark Brown,
	Mike Kravetz, Vasily Averin, Alexander Mikhalitsyn,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 10:06:12AM -0800, Linus Torvalds wrote:
> So:
> 
>  - get rid of that commit message that is lying garbage
> 
>  - fix the so-called "sanitizer".
> 
>  - stop calling the unsigned wrap-around a "sanitizer" and talking
> about "undefined behavior" in the same sentence, since it's neither.
> 
> Do you really not see why I think that thing is actively *WRONG*?

Yes -- I was trying to head off the confusion about what the larger goal
is (trapping unexpected wrap-around) so that people don't assume I'm
talking about Undefined Behavior (we don't have any UB arithmetic in the
kernel, very intentionally). I did not succeed! I'll rewrite it all.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 69/82] perf tools: Refactor intentional wrap-around test
  2024-01-23  6:21   ` Adrian Hunter
@ 2024-01-23 21:31     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 21:31 UTC (permalink / raw)
  To: Adrian Hunter
  Cc: linux-hardening, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin,
	Jiri Olsa, Namhyung Kim, Ian Rogers, John Garry, Fangrui Song,
	linux-perf-users, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 08:21:41AM +0200, Adrian Hunter wrote:
> perf tools has separate includes to the kernel, so does not
> seem to include add_would_overflow() in any of its include
> files at this point.  Need to update
> tools/include/linux/overflow.h first.

Oops, thank you! I will adjust this.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 80/82] xen-netback: Refactor intentional wrap-around test
  2024-01-23  7:55   ` Jan Beulich
@ 2024-01-23 21:32     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 21:32 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Wei Liu, Paul Durrant, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, xen-devel, netdev,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel,
	linux-hardening

On Tue, Jan 23, 2024 at 08:55:44AM +0100, Jan Beulich wrote:
> On 23.01.2024 01:27, Kees Cook wrote:
> > --- a/drivers/net/xen-netback/hash.c
> > +++ b/drivers/net/xen-netback/hash.c
> > @@ -345,7 +345,7 @@ u32 xenvif_set_hash_mapping(struct xenvif *vif, u32 gref, u32 len,
> >  		.flags = GNTCOPY_source_gref
> >  	}};
> >  
> > -	if ((off + len < off) || (off + len > vif->hash.size) ||
> > +	if ((add_would_overflow(off, len)) || (off + len > vif->hash.size) ||
> 
> I'm not maintainer of this code, but if I was I would ask that the
> excess parentheses be removed, to improve readability.

Good call. I will adjust that. Thanks!

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 02/82] overflow: Introduce add_would_overflow()
  2024-01-23  8:03   ` Rasmus Villemoes
@ 2024-01-23 21:38     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 21:38 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 09:03:10AM +0100, Rasmus Villemoes wrote:
> On 23/01/2024 01.26, Kees Cook wrote:
> > For instances where only the overflow needs to be checked (and the sum
> > isn't used), provide the new helper add_would_overflow(), which is
> > a wrapper for check_add_overflow().
> > 
> > Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> > Cc: linux-hardening@vger.kernel.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  include/linux/overflow.h | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> > index 099f2e559aa8..ac088f73e0fd 100644
> > --- a/include/linux/overflow.h
> > +++ b/include/linux/overflow.h
> > @@ -108,6 +108,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
> >  		__builtin_add_overflow(__filter_integral(a), b,		\
> >  				       __filter_ptrint(d))))
> >  
> > +/**
> > + * add_would_overflow() - Check if an addition would overflow
> > + * @a: first addend
> > + * @b: second addend
> > + *
> > + * Returns true if the sum would overflow.
> > + *
> > + * To keep a copy of the sum when the addition doesn't overflow, use
> > + * check_add_overflow() instead.
> > + */
> > +#define add_would_overflow(a, b)			\
> > +	__must_check_overflow(({			\
> > +		size_t __result;			\
> > +		check_add_overflow(a, b, &__result);\
> > +	}))
> 
> Hm, I think this is a bit too ill-defined. Why is the target type
> hard-coded as size_t? What if a and b are u64, and we're on a 32 bit
> target? Then a+b might not overflow but this helper would claim it did.

Oooh, yes. That's no good. Thanks.

> But we also cannot just use typeof(a+b) instead of size_t, since that
> breaks when a and b are narrower than int (adding two u16 never
> overflows since they get promoted to int, but then if assigning the
> result to a u16 one truncates...).

The add_would_overflow() is aimed at replacing the "v + o < v" pattern,
so perhaps use typeof(a) ?

> Perhaps the target type must be explicit? sum_fits_in_type(T, a, b) ?
> IDK, I just don't think size_t is the right thing to use in something
> that is otherwise supposed to be type-generic.

I will use typeof(a) and check binary differences to see if there are
any places doing something unexpected...

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 03/82] overflow: Introduce add_wrap()
  2024-01-23  8:14   ` Rasmus Villemoes
@ 2024-01-23 21:51     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 21:51 UTC (permalink / raw)
  To: Rasmus Villemoes
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 09:14:20AM +0100, Rasmus Villemoes wrote:
> On 23/01/2024 01.26, Kees Cook wrote:
> > Provide a helper that will perform wrapping addition without tripping
> > the arithmetic wrap-around sanitizers.
> > 
> > Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> > Cc: linux-hardening@vger.kernel.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  include/linux/overflow.h | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> > index ac088f73e0fd..30779905a77a 100644
> > --- a/include/linux/overflow.h
> > +++ b/include/linux/overflow.h
> > @@ -124,6 +124,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
> >  		check_add_overflow(a, b, &__result);\
> >  	}))
> >  
> > +/**
> > + * add_wrap() - Intentionally perform a wrapping addition
> > + * @a: first addend
> > + * @b: second addend
> > + *
> > + * Return the potentially wrapped-around addition without
> > + * tripping any overflow sanitizers that may be enabled.
> > + */
> > +#define add_wrap(a, b)					\
> > +	({						\
> > +		typeof(a) __sum;			\
> > +		if (check_add_overflow(a, b, &__sum))	\
> > +			/* do nothing */;		\
> > +		__sum;					\
> > +	})
> > +
> 
> I don't know where this is supposed to be used, but at first glance this
> seems to introduce a footgun. This is not symmetric in a and b, so both
> the type and value of the result may differ between add_wrap(a, b) and
> add_wrap(b, a). That seems dangerous.

I see three options here (and for add_would_overflow()):

1- document that it is typed to the first argument (but this seems weak)
2- require a and b have the same type, and use typeof(a) (but is possibly
   inflexible, like the problems we've had with min()/max())
3- explicitly require a result type (this seems overly verbose, and might
   have problems like we've had with min_t()/max_t())

In the one place this series uses add_wrap(), I have these arguments:

	int segs
	u32 delta

and the result type is expected to be int:

	return atomic_add_return(add_wrap(segs, delta), p_id) - segs;

So as written (option 1) it's (accidentally?) correct.

It would be rejected with option 2, which seems a strong signal that
it's not a good option.

So, your idea about explicit typing is probably best, since I can't
examine the lvalue type within the macro.

	return atomic_add_return(add_wrap(int, segs, delta), p_id) - segs;

I'll give this a try and check for binary differences.

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 03/82] overflow: Introduce add_wrap()
  2024-01-23  9:22   ` Mark Rutland
@ 2024-01-23 21:52     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 21:52 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 09:22:52AM +0000, Mark Rutland wrote:
> On Mon, Jan 22, 2024 at 04:26:38PM -0800, Kees Cook wrote:
> > Provide a helper that will perform wrapping addition without tripping
> > the arithmetic wrap-around sanitizers.
> > 
> > Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> > Cc: linux-hardening@vger.kernel.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  include/linux/overflow.h | 16 ++++++++++++++++
> >  1 file changed, 16 insertions(+)
> > 
> > diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> > index ac088f73e0fd..30779905a77a 100644
> > --- a/include/linux/overflow.h
> > +++ b/include/linux/overflow.h
> > @@ -124,6 +124,22 @@ static inline bool __must_check __must_check_overflow(bool overflow)
> >  		check_add_overflow(a, b, &__result);\
> >  	}))
> >  
> > +/**
> > + * add_wrap() - Intentionally perform a wrapping addition
> > + * @a: first addend
> > + * @b: second addend
> > + *
> > + * Return the potentially wrapped-around addition without
> > + * tripping any overflow sanitizers that may be enabled.
> > + */
> > +#define add_wrap(a, b)					\
> > +	({						\
> > +		typeof(a) __sum;			\
> > +		if (check_add_overflow(a, b, &__sum))	\
> > +			/* do nothing */;		\
> > +		__sum;					\
> > +	})
> 
> It's really difficult to see the semicolon for the empty statement here; could
> we make that part:
> 
> 		if ((check_add_overflow(a, b, &__sum)) {	\
> 			/* do nothing */			\
> 		}						\
> 
> ... to be a little clearer (and less at risk of breakage in a refactoring)?

Yeah, agreed -- that stands out more clearly.

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 10/82] locking/atomic/x86: Silence intentional wrapping addition
  2024-01-23  9:27   ` Mark Rutland
@ 2024-01-23 21:54     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 21:54 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-hardening, Will Deacon, Peter Zijlstra, Boqun Feng,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Tue, Jan 23, 2024 at 09:27:26AM +0000, Mark Rutland wrote:
> On Mon, Jan 22, 2024 at 04:26:45PM -0800, Kees Cook wrote:
> > Annotate atomic_add_return() to avoid signed overflow instrumentation.
> > It is expected to wrap around.
> > 
> > Cc: Will Deacon <will@kernel.org>
> > Cc: Peter Zijlstra <peterz@infradead.org>
> > Cc: Boqun Feng <boqun.feng@gmail.com>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Cc: Ingo Molnar <mingo@redhat.com>
> > Cc: Borislav Petkov <bp@alien8.de>
> > Cc: Dave Hansen <dave.hansen@linux.intel.com>
> > Cc: x86@kernel.org
> > Cc: "H. Peter Anvin" <hpa@zytor.com>
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  arch/x86/include/asm/atomic.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
> > index 55a55ec04350..4120cdd87da8 100644
> > --- a/arch/x86/include/asm/atomic.h
> > +++ b/arch/x86/include/asm/atomic.h
> > @@ -80,7 +80,7 @@ static __always_inline bool arch_atomic_add_negative(int i, atomic_t *v)
> >  }
> >  #define arch_atomic_add_negative arch_atomic_add_negative
> >  
> > -static __always_inline int arch_atomic_add_return(int i, atomic_t *v)
> > +static __always_inline __signed_wrap int arch_atomic_add_return(int i, atomic_t *v)
> >  {
> >  	return i + xadd(&v->counter, i);
> >  }
> 
> I think that here (and in the arm64 patch) it'd be better to use add_wrap() on
> the specific statement, i.e. have:
> 
> static __always_inline int arch_atomic_add_return(int i, atomic_t *v)
> {
> 	return add_wrap(i, xadd(&v->counter, i));
> }
> 
> ... since otherwise the annotation could applly to the '+' or something else
> (e.g. if the 'xadd() part is a special macro), and the annotation might
> unexpectedly hide things if we add other statements here in future.

Okay, sure, I can do that. I may have some header inclusion problems,
but I'll give it a shot.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around
  2024-01-23  9:46 ` Mark Rutland
@ 2024-01-23 21:56   ` Kees Cook
  2024-01-29  6:27   ` Kees Cook
  1 sibling, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 21:56 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 09:46:35AM +0000, Mark Rutland wrote:
> With that in mind, I note that this patch primarily modifies addition
> operations, but leaves subtraction operations unchanged (even though those
> permit the value to go below the minimum, or above the maximum if a negative
> value is used as the subtrahend).

Right, this was kind of a "first pass" on what I'd found so far.

> Shouldn't we address both at the same time? I'll note that in many places the
> same logic is used for both the add and sub, and can legitimately overflow or
> underflow; I hope that whatever we use to suppress overflow warnings also
> ignores underflow.
> 
> [...]
> 
> Looking at the diffstat, I think you've missed a few places:
> 
> [...]
> 
> This misses the include/asm-generic/{atomic,atomic64}.h implementations.
> 
> This also misses the include/linux/atomic/atomic-arch-fallback.h
> implementations. Those are generated from the scripts/atomic/fallbacks/*
> templates, and you'll need to adjust at least fetch_add_unless and
> inc_unless_negative. As noted on other patches, my preference is to use
> add_wrap() in those.
> [...]
> This misses lib/atomic64.c.

Thanks! I'll take a closer look at places we can use the helpers on the
atomics.

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 38/82] arm: 3117/1: Refactor intentional wrap-around test
  2024-01-23  9:56   ` Mark Rutland
@ 2024-01-23 22:41     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 22:41 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-hardening, Russell King, linux-arm-kernel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 09:56:22AM +0000, Mark Rutland wrote:
> The commit title is odd here; '3117/1' is the patch tracker name for the last
> patch. The title should probably be:
> 
> 	arm: nwfpe: Refactor intentional wrap-around test

Whoops, yes. I need to teach my prefix-guessing script to drop the ARM
patch tracker numbers...

-Kees

> 
> Mark.
> 
> On Mon, Jan 22, 2024 at 04:27:13PM -0800, Kees Cook wrote:
> > In an effort to separate intentional arithmetic wrap-around from
> > unexpected wrap-around, we need to refactor places that depend on this
> > kind of math. One of the most common code patterns of this is:
> > 
> > 	VAR + value < VAR
> > 
> > Notably, this is considered "undefined behavior" for signed and pointer
> > types, which the kernel works around by using the -fno-strict-overflow
> > option in the build[1] (which used to just be -fwrapv). Regardless, we
> > want to get the kernel source to the position where we can meaningfully
> > instrument arithmetic wrap-around conditions and catch them when they
> > are unexpected, regardless of whether they are signed[2], unsigned[3],
> > or pointer[4] types.
> > 
> > Refactor open-coded wrap-around addition test to use add_would_overflow().
> > This paves the way to enabling the wrap-around sanitizers in the future.
> > 
> > Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> > Link: https://github.com/KSPP/linux/issues/26 [2]
> > Link: https://github.com/KSPP/linux/issues/27 [3]
> > Link: https://github.com/KSPP/linux/issues/344 [4]
> > Cc: Russell King <linux@armlinux.org.uk>
> > Cc: linux-arm-kernel@lists.infradead.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  arch/arm/nwfpe/softfloat.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c
> > index ffa6b438786b..0635b1eda1d3 100644
> > --- a/arch/arm/nwfpe/softfloat.c
> > +++ b/arch/arm/nwfpe/softfloat.c
> > @@ -603,7 +603,7 @@ static floatx80
> >      roundBits = zSig0 & roundMask;
> >      if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
> >          if (    ( 0x7FFE < zExp )
> > -             || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
> > +             || ( ( zExp == 0x7FFE ) && (add_would_overflow(zSig0, roundIncrement)) )
> >             ) {
> >              goto overflow;
> >          }
> > -- 
> > 2.34.1
> > 
> > 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 41/82] wil6210: Refactor intentional wrap-around test
  2024-01-23 11:50   ` Kalle Valo
@ 2024-01-23 22:52     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-23 22:52 UTC (permalink / raw)
  To: Kalle Valo
  Cc: linux-hardening, Johannes Berg, Max Chen, Yang Shen,
	linux-wireless, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Tue, Jan 23, 2024 at 11:50:34AM +0000, Kalle Valo wrote:
> Kees Cook <keescook@chromium.org> wrote:
> 
> > In an effort to separate intentional arithmetic wrap-around from
> > unexpected wrap-around, we need to refactor places that depend on this
> > kind of math. One of the most common code patterns of this is:
> > 
> > 	VAR + value < VAR
> > 
> > Notably, this is considered "undefined behavior" for signed and pointer
> > types, which the kernel works around by using the -fno-strict-overflow
> > option in the build[1] (which used to just be -fwrapv). Regardless, we
> > want to get the kernel source to the position where we can meaningfully
> > instrument arithmetic wrap-around conditions and catch them when they
> > are unexpected, regardless of whether they are signed[2], unsigned[3],
> > or pointer[4] types.
> > 
> > Refactor open-coded wrap-around addition test to use add_would_overflow().
> > This paves the way to enabling the wrap-around sanitizers in the future.
> > 
> > Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> > Link: https://github.com/KSPP/linux/issues/26 [2]
> > Link: https://github.com/KSPP/linux/issues/27 [3]
> > Link: https://github.com/KSPP/linux/issues/344 [4]
> > Cc: Kalle Valo <kvalo@kernel.org>
> > Cc: Johannes Berg <johannes.berg@intel.com>
> > Cc: Max Chen <mxchen@codeaurora.org>
> > Cc: Yang Shen <shenyang39@huawei.com>
> > Cc: linux-wireless@vger.kernel.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > Acked-by: Kalle Valo <kvalo@kernel.org>
> 
> If you can edit before commit please add "wifi:" prefix to the wireless patches:
> 
> ERROR: 'wifi:' prefix missing: '[PATCH 41/82] wil6210: Refactor intentional wrap-around test'
> ERROR: 'wifi:' prefix missing: '[PATCH 62/82] mwifiex: pcie: Refactor intentional wrap-around test'

Ah yes, thank you! I will adjust them.

-Kees

> 
> 2 patches set to Not Applicable.
> 
> 13526631 [41/82] wil6210: Refactor intentional wrap-around test
> 13526632 [62/82] mwifiex: pcie: Refactor intentional wrap-around test
> 
> -- 
> https://patchwork.kernel.org/project/linux-wireless/patch/20240123002814.1396804-41-keescook@chromium.org/
> 
> https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
> 

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 57/82] KVM: arm64: vgic-v3: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 57/82] KVM: arm64: vgic-v3: " Kees Cook
  2024-01-23 10:50   ` Marc Zyngier
@ 2024-01-24 15:12   ` Eric Auger
  1 sibling, 0 replies; 163+ messages in thread
From: Eric Auger @ 2024-01-24 15:12 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Marc Zyngier, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, linux-arm-kernel,
	kvmarm, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel



On 1/23/24 01:27, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Marc Zyngier <maz@kernel.org>
> Cc: Oliver Upton <oliver.upton@linux.dev>
> Cc: James Morse <james.morse@arm.com>
> Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> Cc: Zenghui Yu <yuzenghui@huawei.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: Eric Auger <eric.auger@redhat.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: kvmarm@lists.linux.dev
> Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
> ---
>  arch/arm64/kvm/vgic/vgic-mmio-v3.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> index c15ee1df036a..860b774c0c13 100644
> --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
> @@ -863,7 +863,7 @@ static int vgic_v3_alloc_redist_region(struct kvm *kvm, uint32_t index,
>  	int ret;
>  
>  	/* cross the end of memory ? */
> -	if (base + size < base)
> +	if (add_would_overflow(base, size))
>  		return -EINVAL;
>  
>  	if (list_empty(rd_regions)) {


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 24/82] KVM: arm64: vgic: Refactor intentional wrap-around calculation
  2024-01-23 10:49   ` Marc Zyngier
@ 2024-01-24 15:13     ` Eric Auger
  0 siblings, 0 replies; 163+ messages in thread
From: Eric Auger @ 2024-01-24 15:13 UTC (permalink / raw)
  To: Marc Zyngier, Kees Cook
  Cc: linux-hardening, Oliver Upton, James Morse, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon, Reiji Watanabe,
	Ricardo Koller, Raghavendra Rao Ananta, Quentin Perret,
	Jean-Philippe Brucker, linux-arm-kernel, kvmarm,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel



On 1/23/24 11:49, Marc Zyngier wrote:
> On Tue, 23 Jan 2024 00:26:59 +0000,
> Kees Cook <keescook@chromium.org> wrote:
>> In an effort to separate intentional arithmetic wrap-around from
>> unexpected wrap-around, we need to refactor places that depend on this
>> kind of math. One of the most common code patterns of this is:
>>
>> 	VAR + value < VAR
>>
>> Notably, this is considered "undefined behavior" for signed and pointer
>> types, which the kernel works around by using the -fno-strict-overflow
>> option in the build[1] (which used to just be -fwrapv). Regardless, we
>> want to get the kernel source to the position where we can meaningfully
>> instrument arithmetic wrap-around conditions and catch them when they
>> are unexpected, regardless of whether they are signed[2], unsigned[3],
>> or pointer[4] types.
>>
>> Refactor open-coded unsigned wrap-around addition test to use
>> check_add_overflow(), retaining the result for later usage (which removes
>> the redundant open-coded addition). This paves the way to enabling the
>> wrap-around sanitizers in the future.
>>
>> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
>> Link: https://github.com/KSPP/linux/issues/26 [2]
>> Link: https://github.com/KSPP/linux/issues/27 [3]
>> Link: https://github.com/KSPP/linux/issues/344 [4]
>> Cc: Marc Zyngier <maz@kernel.org>
>> Cc: Oliver Upton <oliver.upton@linux.dev>
>> Cc: James Morse <james.morse@arm.com>
>> Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
>> Cc: Zenghui Yu <yuzenghui@huawei.com>
>> Cc: Catalin Marinas <catalin.marinas@arm.com>
>> Cc: Will Deacon <will@kernel.org>
>> Cc: Reiji Watanabe <reijiw@google.com>
>> Cc: Eric Auger <eric.auger@redhat.com>
>> Cc: Ricardo Koller <ricarkol@google.com>
>> Cc: Raghavendra Rao Ananta <rananta@google.com>
>> Cc: Quentin Perret <qperret@google.com>
>> Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>
>> Cc: linux-arm-kernel@lists.infradead.org
>> Cc: kvmarm@lists.linux.dev
>> Signed-off-by: Kees Cook <keescook@chromium.org>
>> ---
>>  arch/arm64/kvm/vgic/vgic-kvm-device.c |  6 ++++--
>>  arch/arm64/kvm/vgic/vgic-v2.c         | 10 ++++++----
>>  2 files changed, 10 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
>> index f48b8dab8b3d..0eec5344d203 100644
>> --- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
>> +++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
>> @@ -18,17 +18,19 @@ int vgic_check_iorange(struct kvm *kvm, phys_addr_t ioaddr,
>>  		       phys_addr_t addr, phys_addr_t alignment,
>>  		       phys_addr_t size)
>>  {
>> +	phys_addr_t sum;
>> +
>>  	if (!IS_VGIC_ADDR_UNDEF(ioaddr))
>>  		return -EEXIST;
>>  
>>  	if (!IS_ALIGNED(addr, alignment) || !IS_ALIGNED(size, alignment))
>>  		return -EINVAL;
>>  
>> -	if (addr + size < addr)
>> +	if (check_add_overflow(addr, size, &sum))
>>  		return -EINVAL;
>>  
>>  	if (addr & ~kvm_phys_mask(&kvm->arch.mmu) ||
>> -	    (addr + size) > kvm_phys_size(&kvm->arch.mmu))
>> +	    sum > kvm_phys_size(&kvm->arch.mmu))
> nit: 'sum' doesn't mean much in this context. Something like 'end'
> would be much more descriptive.
>
>>  		return -E2BIG;
>>  
>>  	return 0;
>> diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c
>> index 7e9cdb78f7ce..c8d1e965d3b7 100644
>> --- a/arch/arm64/kvm/vgic/vgic-v2.c
>> +++ b/arch/arm64/kvm/vgic/vgic-v2.c
>> @@ -273,14 +273,16 @@ void vgic_v2_enable(struct kvm_vcpu *vcpu)
>>  /* check for overlapping regions and for regions crossing the end of memory */
>>  static bool vgic_v2_check_base(gpa_t dist_base, gpa_t cpu_base)
>>  {
>> -	if (dist_base + KVM_VGIC_V2_DIST_SIZE < dist_base)
>> +	gpa_t dist_sum, cpu_sum;
> Same here: dist_end, cpu_end.
I do agree.
>
>> +
>> +	if (check_add_overflow(dist_base, KVM_VGIC_V2_DIST_SIZE, &dist_sum))
>>  		return false;
>> -	if (cpu_base + KVM_VGIC_V2_CPU_SIZE < cpu_base)
>> +	if (check_add_overflow(cpu_base, KVM_VGIC_V2_CPU_SIZE, &cpu_sum))
>>  		return false;
>>  
>> -	if (dist_base + KVM_VGIC_V2_DIST_SIZE <= cpu_base)
>> +	if (dist_sum <= cpu_base)
>>  		return true;
>> -	if (cpu_base + KVM_VGIC_V2_CPU_SIZE <= dist_base)
>> +	if (cpu_sum <= dist_base)
>>  		return true;
>>  
>>  	return false;
> With these nits addressed, and assuming you intend to merge the whole
> series yourself:
>
> Acked-by: Marc Zyngier <maz@kernel.org>
assuming above suggested changes,

Reviewed-by: Eric Auger <eric.auger@redhat.com>

Eric
>
> 	M.
>


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 25/82] KVM: SVM: Refactor intentional wrap-around calculation
  2024-01-23  0:27 ` [PATCH 25/82] KVM: SVM: " Kees Cook
@ 2024-01-24 16:15   ` Sean Christopherson
  0 siblings, 0 replies; 163+ messages in thread
From: Sean Christopherson @ 2024-01-24 16:15 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Paolo Bonzini, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, kvm,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> wrap-around sanitizers in the future.

IIUC, the plan is to get UBSAN to detect unexpected overflow, at which point an
explicit annotation will be needed to avoid false positives.  If that's correct,
can you put something like that in these changelogs?  Nothing in the changelog
actually says _why_ open coded wrap-around checks will be problematic.

> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Sean Christopherson <seanjc@google.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: Borislav Petkov <bp@alien8.de>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: x86@kernel.org
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: kvm@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/x86/kvm/svm/sev.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index f760106c31f8..12a6a2b1ac81 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -400,16 +400,17 @@ static struct page **sev_pin_memory(struct kvm *kvm, unsigned long uaddr,
>  	unsigned long locked, lock_limit;
>  	struct page **pages;
>  	unsigned long first, last;
> +	unsigned long sum;

Similar to Marc's comments, I would much prefer to call this uaddr_last.

>  	int ret;
>  
>  	lockdep_assert_held(&kvm->lock);
>  
> -	if (ulen == 0 || uaddr + ulen < uaddr)
> +	if (ulen == 0 || check_add_overflow(uaddr, ulen, &sum))
>  		return ERR_PTR(-EINVAL);
>  
>  	/* Calculate number of pages. */
>  	first = (uaddr & PAGE_MASK) >> PAGE_SHIFT;
> -	last = ((uaddr + ulen - 1) & PAGE_MASK) >> PAGE_SHIFT;
> +	last = ((sum - 1) & PAGE_MASK) >> PAGE_SHIFT;
>  	npages = (last - first + 1);
>  
>  	locked = sev->pages_locked + npages;
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 23/82] KVM: Refactor intentional wrap-around calculation
  2024-01-23  0:26 ` [PATCH 23/82] KVM: " Kees Cook
@ 2024-01-24 16:25   ` Sean Christopherson
  0 siblings, 0 replies; 163+ messages in thread
From: Sean Christopherson @ 2024-01-24 16:25 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Paolo Bonzini, kvm, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notable, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed, unsigned, or
> pointer types.
> 
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> unsigned wrap-around sanitizer[2] in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/27 [2]
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Cc: kvm@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  virt/kvm/coalesced_mmio.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c
> index 1b90acb6e3fe..0a3b706fbf4c 100644
> --- a/virt/kvm/coalesced_mmio.c
> +++ b/virt/kvm/coalesced_mmio.c
> @@ -25,17 +25,19 @@ static inline struct kvm_coalesced_mmio_dev *to_mmio(struct kvm_io_device *dev)
>  static int coalesced_mmio_in_range(struct kvm_coalesced_mmio_dev *dev,
>  				   gpa_t addr, int len)
>  {
> +	gpa_t sum;

s/sum/end?

Also, given that your're fixing a gpa_t, which is a u64, presumably that means
that this code in __kvm_set_memory_region() also needs to be fixed:

	if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr)
		return -EINVAL; 

and for that one I'd really like to avoid an ignored output parameter (KVM
converts the incoming mem->memory_size to pages, so the "sum" is never used
directly).

Would it make sense to add an API that feeds a dummy "sum" value?  I assume UBSAN
won't fire on the usage of the known good value, i.e. using the output parameter
isn't necessary for functional correctness.  Having an API that does just the
check would trim down the size of many of these patches and avoid having to come
up with names for the local variables.  And IMO, the existing code is a wee bit
more intuitive, it'd be nice to give developers the flexibility to choose which
flavor yields the "best" code on a case-by-case basis.

> +
>  	/* is it in a batchable area ?
>  	 * (addr,len) is fully included in
>  	 * (zone->addr, zone->size)
>  	 */
>  	if (len < 0)
>  		return 0;
> -	if (addr + len < addr)
> +	if (check_add_overflow(addr, len, &sum))
>  		return 0;
>  	if (addr < dev->zone.addr)
>  		return 0;
> -	if (addr + len > dev->zone.addr + dev->zone.size)
> +	if (sum > dev->zone.addr + dev->zone.size)
>  		return 0;
>  	return 1;
>  }
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 75/82] timekeeping: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 75/82] timekeeping: " Kees Cook
  2024-01-23  1:06   ` John Stultz
@ 2024-01-24 19:34   ` Thomas Gleixner
  1 sibling, 0 replies; 163+ messages in thread
From: Thomas Gleixner @ 2024-01-24 19:34 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Kees Cook, John Stultz, Stephen Boyd, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22 2024 at 16:27, Kees Cook wrote:

> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: John Stultz <jstultz@google.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Kees Cook <keescook@chromium.org>

Reviewed-by: Thomas Gleixner <tglx@linutronix.de>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 35/82] ACPI: custom_method: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 35/82] ACPI: custom_method: Refactor intentional wrap-around test Kees Cook
@ 2024-01-24 19:52   ` Rafael J. Wysocki
  2024-01-24 20:16     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Rafael J. Wysocki @ 2024-01-24 19:52 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Rafael J. Wysocki, Len Brown, linux-acpi,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 2:03 AM Kees Cook <keescook@chromium.org> wrote:
>
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
>         VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Len Brown <lenb@kernel.org>
> Cc: linux-acpi@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  drivers/acpi/custom_method.c | 2 +-

I may attempt to drop custom_method.c in this cycle, is there a
problem if I take this into my tree for now?

>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
> index d39a9b474727..0789317f4a1a 100644
> --- a/drivers/acpi/custom_method.c
> +++ b/drivers/acpi/custom_method.c
> @@ -54,7 +54,7 @@ static ssize_t cm_write(struct file *file, const char __user *user_buf,
>
>         if ((*ppos > max_size) ||
>             (*ppos + count > max_size) ||
> -           (*ppos + count < count) ||
> +           (add_would_overflow(count, *ppos)) ||
>             (count > uncopied_bytes)) {
>                 kfree(buf);
>                 buf = NULL;
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 35/82] ACPI: custom_method: Refactor intentional wrap-around test
  2024-01-24 19:52   ` Rafael J. Wysocki
@ 2024-01-24 20:16     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-24 20:16 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-hardening, Len Brown, linux-acpi, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

On Wed, Jan 24, 2024 at 08:52:48PM +0100, Rafael J. Wysocki wrote:
> On Tue, Jan 23, 2024 at 2:03 AM Kees Cook <keescook@chromium.org> wrote:
> >
> > In an effort to separate intentional arithmetic wrap-around from
> > unexpected wrap-around, we need to refactor places that depend on this
> > kind of math. One of the most common code patterns of this is:
> >
> >         VAR + value < VAR
> >
> > Notably, this is considered "undefined behavior" for signed and pointer
> > types, which the kernel works around by using the -fno-strict-overflow
> > option in the build[1] (which used to just be -fwrapv). Regardless, we
> > want to get the kernel source to the position where we can meaningfully
> > instrument arithmetic wrap-around conditions and catch them when they
> > are unexpected, regardless of whether they are signed[2], unsigned[3],
> > or pointer[4] types.
> >
> > Refactor open-coded wrap-around addition test to use add_would_overflow().
> > This paves the way to enabling the wrap-around sanitizers in the future.
> >
> > Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> > Link: https://github.com/KSPP/linux/issues/26 [2]
> > Link: https://github.com/KSPP/linux/issues/27 [3]
> > Link: https://github.com/KSPP/linux/issues/344 [4]
> > Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> > Cc: Len Brown <lenb@kernel.org>
> > Cc: linux-acpi@vger.kernel.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  drivers/acpi/custom_method.c | 2 +-
> 
> I may attempt to drop custom_method.c in this cycle, is there a
> problem if I take this into my tree for now?

The helper doesn't exist in tree yet, but it may be a bit before these
refactors land, so if custom_method vanishes before then, that's great!
:)

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 55/82] kasan: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 55/82] kasan: " Kees Cook
@ 2024-01-25 22:35   ` Andrey Konovalov
  0 siblings, 0 replies; 163+ messages in thread
From: Andrey Konovalov @ 2024-01-25 22:35 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Andrey Ryabinin, Alexander Potapenko,
	Dmitry Vyukov, Vincenzo Frascino, Andrew Morton, kasan-dev,
	linux-mm, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Tue, Jan 23, 2024 at 1:29 AM Kees Cook <keescook@chromium.org> wrote:
>
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
>         VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> Cc: Alexander Potapenko <glider@google.com>
> Cc: Andrey Konovalov <andreyknvl@gmail.com>
> Cc: Dmitry Vyukov <dvyukov@google.com>
> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: kasan-dev@googlegroups.com
> Cc: linux-mm@kvack.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  mm/kasan/generic.c | 2 +-
>  mm/kasan/sw_tags.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
> index df6627f62402..f9bc29ae09bd 100644
> --- a/mm/kasan/generic.c
> +++ b/mm/kasan/generic.c
> @@ -171,7 +171,7 @@ static __always_inline bool check_region_inline(const void *addr,
>         if (unlikely(size == 0))
>                 return true;
>
> -       if (unlikely(addr + size < addr))
> +       if (unlikely(add_would_overflow(addr, size)))
>                 return !kasan_report(addr, size, write, ret_ip);
>
>         if (unlikely(!addr_has_metadata(addr)))
> diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c
> index 220b5d4c6876..79a3bbd66c32 100644
> --- a/mm/kasan/sw_tags.c
> +++ b/mm/kasan/sw_tags.c
> @@ -80,7 +80,7 @@ bool kasan_check_range(const void *addr, size_t size, bool write,
>         if (unlikely(size == 0))
>                 return true;
>
> -       if (unlikely(addr + size < addr))
> +       if (unlikely(add_would_overflow(addr, size)))
>                 return !kasan_report(addr, size, write, ret_ip);
>
>         tag = get_tag((const void *)addr);
> --
> 2.34.1
>

Acked-by: Andrey Konovalov <andreyknvl@gmail.com>

Thanks!

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 32/82] vringh: Refactor intentional wrap-around calculation
  2024-01-23  0:27 ` [PATCH 32/82] vringh: " Kees Cook
@ 2024-01-26 19:31   ` Eugenio Perez Martin
  2024-01-26 19:42     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Eugenio Perez Martin @ 2024-01-26 19:31 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Michael S. Tsirkin, Jason Wang, kvm,
	virtualization, netdev, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 2:42 AM Kees Cook <keescook@chromium.org> wrote:
>
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
>         VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> unsigned wrap-around sanitizer[2] in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Jason Wang <jasowang@redhat.com>
> Cc: kvm@vger.kernel.org
> Cc: virtualization@lists.linux.dev
> Cc: netdev@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  drivers/vhost/vringh.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
> index 7b8fd977f71c..07442f0a52bd 100644
> --- a/drivers/vhost/vringh.c
> +++ b/drivers/vhost/vringh.c
> @@ -145,6 +145,8 @@ static inline bool range_check(struct vringh *vrh, u64 addr, size_t *len,
>                                bool (*getrange)(struct vringh *,
>                                                 u64, struct vringh_range *))
>  {
> +       u64 sum;

I understand this is part of a bulk change so little time to think
about names :). But what about "end" or similar?

Either way,
Acked-by: Eugenio Pérez <eperezma@redhat.com>

> +
>         if (addr < range->start || addr > range->end_incl) {
>                 if (!getrange(vrh, addr, range))
>                         return false;
> @@ -152,20 +154,20 @@ static inline bool range_check(struct vringh *vrh, u64 addr, size_t *len,
>         BUG_ON(addr < range->start || addr > range->end_incl);
>
>         /* To end of memory? */
> -       if (unlikely(addr + *len == 0)) {
> +       if (unlikely(U64_MAX - addr == *len)) {
>                 if (range->end_incl == -1ULL)
>                         return true;
>                 goto truncate;
>         }
>
>         /* Otherwise, don't wrap. */
> -       if (addr + *len < addr) {
> +       if (check_add_overflow(addr, *len, &sum)) {
>                 vringh_bad("Wrapping descriptor %zu@0x%llx",
>                            *len, (unsigned long long)addr);
>                 return false;
>         }
>
> -       if (unlikely(addr + *len - 1 > range->end_incl))
> +       if (unlikely(sum - 1 > range->end_incl))
>                 goto truncate;
>         return true;
>
> --
> 2.34.1
>
>


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 77/82] virtio: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 77/82] virtio: " Kees Cook
@ 2024-01-26 19:33   ` Eugenio Perez Martin
  0 siblings, 0 replies; 163+ messages in thread
From: Eugenio Perez Martin @ 2024-01-26 19:33 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Michael S. Tsirkin, Jason Wang, Xuan Zhuo,
	virtualization, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

On Tue, Jan 23, 2024 at 2:28 AM Kees Cook <keescook@chromium.org> wrote:
>
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
>         VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: Jason Wang <jasowang@redhat.com>
> Cc: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> Cc: virtualization@lists.linux.dev
> Signed-off-by: Kees Cook <keescook@chromium.org>

Reviewed-by: Eugenio Pérez <eperezma@redhat.com>

> ---
>  drivers/virtio/virtio_pci_modern_dev.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c
> index 0d3dbfaf4b23..710d3bd45b4f 100644
> --- a/drivers/virtio/virtio_pci_modern_dev.c
> +++ b/drivers/virtio/virtio_pci_modern_dev.c
> @@ -59,7 +59,7 @@ vp_modern_map_capability(struct virtio_pci_modern_device *mdev, int off,
>
>         length -= start;
>
> -       if (start + offset < offset) {
> +       if (add_would_overflow(offset, start)) {
>                 dev_err(&dev->dev,
>                         "virtio_pci: map wrap-around %u+%u\n",
>                         start, offset);
> @@ -81,7 +81,7 @@ vp_modern_map_capability(struct virtio_pci_modern_device *mdev, int off,
>         if (len)
>                 *len = length;
>
> -       if (minlen + offset < minlen ||
> +       if (add_would_overflow(minlen, offset) ||
>             minlen + offset > pci_resource_len(dev, bar)) {
>                 dev_err(&dev->dev,
>                         "virtio_pci: map virtio %zu@%u "
> --
> 2.34.1
>
>


^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 32/82] vringh: Refactor intentional wrap-around calculation
  2024-01-26 19:31   ` Eugenio Perez Martin
@ 2024-01-26 19:42     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-26 19:42 UTC (permalink / raw)
  To: Eugenio Perez Martin
  Cc: linux-hardening, Michael S. Tsirkin, Jason Wang, kvm,
	virtualization, netdev, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Fri, Jan 26, 2024 at 08:31:04PM +0100, Eugenio Perez Martin wrote:
> On Tue, Jan 23, 2024 at 2:42 AM Kees Cook <keescook@chromium.org> wrote:
> >
> > In an effort to separate intentional arithmetic wrap-around from
> > unexpected wrap-around, we need to refactor places that depend on this
> > kind of math. One of the most common code patterns of this is:
> >
> >         VAR + value < VAR
> >
> > Notably, this is considered "undefined behavior" for signed and pointer
> > types, which the kernel works around by using the -fno-strict-overflow
> > option in the build[1] (which used to just be -fwrapv). Regardless, we
> > want to get the kernel source to the position where we can meaningfully
> > instrument arithmetic wrap-around conditions and catch them when they
> > are unexpected, regardless of whether they are signed[2], unsigned[3],
> > or pointer[4] types.
> >
> > Refactor open-coded unsigned wrap-around addition test to use
> > check_add_overflow(), retaining the result for later usage (which removes
> > the redundant open-coded addition). This paves the way to enabling the
> > unsigned wrap-around sanitizer[2] in the future.
> >
> > Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> > Link: https://github.com/KSPP/linux/issues/26 [2]
> > Link: https://github.com/KSPP/linux/issues/27 [3]
> > Link: https://github.com/KSPP/linux/issues/344 [4]
> > Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > Cc: Jason Wang <jasowang@redhat.com>
> > Cc: kvm@vger.kernel.org
> > Cc: virtualization@lists.linux.dev
> > Cc: netdev@vger.kernel.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  drivers/vhost/vringh.c | 8 +++++---
> >  1 file changed, 5 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
> > index 7b8fd977f71c..07442f0a52bd 100644
> > --- a/drivers/vhost/vringh.c
> > +++ b/drivers/vhost/vringh.c
> > @@ -145,6 +145,8 @@ static inline bool range_check(struct vringh *vrh, u64 addr, size_t *len,
> >                                bool (*getrange)(struct vringh *,
> >                                                 u64, struct vringh_range *))
> >  {
> > +       u64 sum;
> 
> I understand this is part of a bulk change so little time to think
> about names :). But what about "end" or similar?
> 
> Either way,
> Acked-by: Eugenio Pérez <eperezma@redhat.com>

Thanks! Yeah, you are not alone in suggesting "end" in a several of
these patches. :)

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition
  2024-01-23  0:26 ` [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition Kees Cook
@ 2024-01-26 22:52   ` Justin Stitt
  2024-01-26 22:57     ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Justin Stitt @ 2024-01-26 22:52 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Gustavo A. R. Silva, Andrew Morton,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, llvm,
	linux-kernel

Hi,

On Mon, Jan 22, 2024 at 04:26:36PM -0800, Kees Cook wrote:
> The check_add_overflow() helper is mostly a wrapper around
> __builtin_add_overflow(), but GCC and Clang refuse to operate on pointer
> arguments that would normally be allowed if the addition were open-coded.
>
> For example, we have many places where pointer overflow is tested:
>
> 	struct foo *ptr;
> 	...
> 	/* Check for overflow */
> 	if (ptr + count < ptr) ...
>
> And in order to avoid running into the overflow sanitizers in the
> future, we need to rewrite these "intended" overflow checks:
>
> 	if (check_add_overflow(ptr, count, &result)) ...
>
> Frustratingly the argument type validation for __builtin_add_overflow()
> is done before evaluating __builtin_choose_expr(), so for arguments to
> be valid simultaneously for sizeof(*p) (when p may not be a pointer),
> and __builtin_add_overflow(a, ...) (when a may be a pointer), we must
> introduce wrappers that always produce a specific type (but they are
> only used in the places where the bogus arguments will be ignored).
>
> To test whether a variable is a pointer or not, introduce the __is_ptr()
> helper, which uses __builtin_classify_type() to find arrays and pointers
> (via the new __is_ptr_or_array() helper), and then decays arrays into
> pointers (via the new __decay() helper), to distinguish pointers from
> arrays.
>
> Additionally update the unit tests to cover pointer addition.
>
> Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Cc: Nick Desaulniers <ndesaulniers@google.com>
> Cc: Bill Wendling <morbo@google.com>
> Cc: Justin Stitt <justinstitt@google.com>
> Cc: llvm@lists.linux.dev
> Cc: linux-hardening@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  include/linux/compiler_types.h | 10 +++++
>  include/linux/overflow.h       | 44 ++++++++++++++++++-
>  lib/overflow_kunit.c           | 77 ++++++++++++++++++++++++++++++----
>  3 files changed, 121 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
> index 6f1ca49306d2..d27b58fddfaa 100644
> --- a/include/linux/compiler_types.h
> +++ b/include/linux/compiler_types.h
> @@ -375,6 +375,16 @@ struct ftrace_likely_data {
>  /* Are two types/vars the same type (ignoring qualifiers)? */
>  #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
>
> +/* Is variable addressable? */
> +#define __is_ptr_or_array(p)	(__builtin_classify_type(p) == 5)
> +
> +/* Return an array decayed to a pointer. */
> +#define __decay(p)		\
> +	(&*__builtin_choose_expr(__is_ptr_or_array(p), p, NULL))

Initially, I thought this __decay could dereference a NULL which would
be UB.

According to the C std 6.5.3.2 (4):
| The unary * operator denotes indirection. If the operand points to a
| function, the result is a function designator; if it points to an
| object, the result is an lvalue designating the object. If the operand
| has type ‘‘pointer to type’’, the result has type ‘‘type’’. If an
| invalid value has been assigned to the pointer, the behavior of the
| unary * operator is undefined^(84)

With footnote 84 mentioning NULL:
| Among the invalid values for dereferencing a pointer by the unary *
| operator are a null pointer, an address inappropriately aligned for the
| type of object pointed to, and the address of an object after the end of
| its lifetime.

However, in this very same footnote it mentions:
| &*E is equivalent to E (even if E is a null pointer)

So, yeah this is OK ( and new to me :>] )

> +
> +/* Report if variable is a pointer type. */
> +#define __is_ptr(p)		__same_type(p, __decay(p))
> +
>  /*
>   * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
>   *			       non-scalar types unchanged.
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index 7b5cf4a5cd19..099f2e559aa8 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -51,6 +51,45 @@ static inline bool __must_check __must_check_overflow(bool overflow)
>  	return unlikely(overflow);
>  }
>
> +/* Always produce an integral variable expression. */
> +#define __filter_integral(x)		\
> +	__builtin_choose_expr(!__is_ptr(x), (x), 0)
> +
> +/* Always produce a pointer value. */
> +#define __filter_ptr(x)			\
> +	__builtin_choose_expr(__is_ptr(x), (x), NULL)
> +
> +/* Always produce a pointer to an integral value. */
> +#define __filter_ptrint(x)		\
> +	__builtin_choose_expr(!__is_ptr(*(x)), x, &(int){ 0 })
> +
> +/**
> + * __check_ptr_add_overflow() - Calculate pointer addition with overflow checking
> + * @a: pointer addend
> + * @b: numeric addend
> + * @d: pointer to store sum
> + *
> + * Returns 0 on success.
> + *
> + * Do not use this function directly, use check_add_overflow() instead.
> + *
> + * *@d holds the results of the attempted addition, but is not considered
> + * "safe for use" on a non-zero return value, which indicates that the
> + * sum has overflowed or been truncated.
> + */
> +#define __check_ptr_add_overflow(a, b, d)		\
> +	({						\
> +		typeof(a) __a = (a);			\
> +		typeof(b) __b = (b);			\
> +		size_t __bytes;				\
> +		bool __overflow;			\
> +							\
> +		/* we want to perform the wrap-around, but retain the result */ \
> +		__overflow = __builtin_mul_overflow(sizeof(*(__a)), __b, &__bytes); \
> +		__builtin_add_overflow((unsigned long)(__a), __bytes, (unsigned long *)(d)) || \
> +		__overflow;				\
> +	})
> +
>  /**
>   * check_add_overflow() - Calculate addition with overflow checking
>   * @a: first addend
> @@ -64,7 +103,10 @@ static inline bool __must_check __must_check_overflow(bool overflow)
>   * sum has overflowed or been truncated.
>   */
>  #define check_add_overflow(a, b, d)	\
> -	__must_check_overflow(__builtin_add_overflow(a, b, d))
> +	__must_check_overflow(__builtin_choose_expr(__is_ptr(a),	\
> +		__check_ptr_add_overflow(__filter_ptr(a), b, d),	\
> +		__builtin_add_overflow(__filter_integral(a), b,		\
> +				       __filter_ptrint(d))))
>
>  /**
>   * check_sub_overflow() - Calculate subtraction with overflow checking

Does check_sub_overflow() deserve some more love in the future? I
imagine "under"-flowing pointers is not at all common, though.

Nonetheless, this all looks good to me.

Reviewed-by: Justin Stitt <justinstitt@google.com>

> diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c
> index c527f6b75789..2d106e880956 100644
> --- a/lib/overflow_kunit.c
> +++ b/lib/overflow_kunit.c
> @@ -45,13 +45,18 @@
>  # define SKIP_64_ON_32(t)	do { } while (0)
>  #endif
>
> -#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t)			\
> -	static const struct test_ ## t1 ## _ ## t2 ## __ ## t {	\
> +#define DEFINE_TEST_ARRAY_NAMED_TYPED(n1, n2, n, t1, t2, t)	\
> +	static const struct test_ ## n1 ## _ ## n2 ## __ ## n {	\
>  		t1 a;						\
>  		t2 b;						\
> -		t sum, diff, prod;				\
> +		t sum;						\
> +		t diff;						\
> +		t prod;						\
>  		bool s_of, d_of, p_of;				\
> -	} t1 ## _ ## t2 ## __ ## t ## _tests[]
> +	} n1 ## _ ## n2 ## __ ## n ## _tests[]
> +
> +#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t)			\
> +	DEFINE_TEST_ARRAY_NAMED_TYPED(t1, t2, t, t1, t2, t)
>
>  #define DEFINE_TEST_ARRAY(t)	DEFINE_TEST_ARRAY_TYPED(t, t, t)
>
> @@ -251,8 +256,10 @@ DEFINE_TEST_ARRAY(s64) = {
>  };
>
>  #define check_one_op(t, fmt, op, sym, a, b, r, of) do {			\
> -	int _a_orig = a, _a_bump = a + 1;				\
> -	int _b_orig = b, _b_bump = b + 1;				\
> +	typeof(a + 0) _a_orig = a;					\
> +	typeof(a + 0) _a_bump = a + 1;					\
> +	typeof(b + 0) _b_orig = b;					\
> +	typeof(b + 0) _b_bump = b + 1;					\
>  	bool _of;							\
>  	t _r;								\
>  									\
> @@ -260,13 +267,13 @@ DEFINE_TEST_ARRAY(s64) = {
>  	KUNIT_EXPECT_EQ_MSG(test, _of, of,				\
>  		"expected "fmt" "sym" "fmt" to%s overflow (type %s)\n",	\
>  		a, b, of ? "" : " not", #t);				\
> -	KUNIT_EXPECT_EQ_MSG(test, _r, r,				\
> +	KUNIT_EXPECT_TRUE_MSG(test, _r == r,				\
>  		"expected "fmt" "sym" "fmt" == "fmt", got "fmt" (type %s)\n", \
>  		a, b, r, _r, #t);					\
>  	/* Check for internal macro side-effects. */			\
>  	_of = check_ ## op ## _overflow(_a_orig++, _b_orig++, &_r);	\
> -	KUNIT_EXPECT_EQ_MSG(test, _a_orig, _a_bump, "Unexpected " #op " macro side-effect!\n"); \
> -	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump, "Unexpected " #op " macro side-effect!\n"); \
> +	KUNIT_EXPECT_TRUE_MSG(test, _a_orig == _a_bump, "Unexpected " #op " macro side-effect!\n"); \
> +	KUNIT_EXPECT_TRUE_MSG(test, _b_orig == _b_bump, "Unexpected " #op " macro side-effect!\n"); \
>  } while (0)
>
>  #define DEFINE_TEST_FUNC_TYPED(n, t, fmt)				\
> @@ -333,6 +340,55 @@ DEFINE_TEST_ARRAY_TYPED(int, int, u8) = {
>  };
>  DEFINE_TEST_FUNC_TYPED(int_int__u8, u8, "%d");
>
> +#define DEFINE_TEST_PTR_FUNC_TYPED(n, t, fmt)				\
> +static void do_ptr_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
> +{									\
> +	/* we're only doing single-direction sums, no product or division */ \
> +	check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of);\
> +}									\
> +									\
> +static void n ## _overflow_test(struct kunit *test) {			\
> +	unsigned i;							\
> +									\
> +	for (i = 0; i < ARRAY_SIZE(n ## _tests); ++i)			\
> +		do_ptr_test_ ## n(test, &n ## _tests[i]);		\
> +	kunit_info(test, "%zu %s arithmetic tests finished\n",		\
> +		ARRAY_SIZE(n ## _tests), #n);				\
> +}
> +
> +DEFINE_TEST_ARRAY_NAMED_TYPED(void, int, void, void *, int, void *) = {
> +	{NULL, 0, NULL, NULL, NULL, false, false, false},
> +	{(void *)0x30, 0x10, (void *)0x40, NULL, NULL, false, false, false},
> +	{(void *)ULONG_MAX, 0, (void *)ULONG_MAX, NULL, NULL, false, false, false},
> +	{(void *)ULONG_MAX, 1, NULL, NULL, NULL, true, false, false},
> +	{(void *)ULONG_MAX, INT_MAX, (void *)(INT_MAX - 1), NULL, NULL, true, false, false},
> +};
> +DEFINE_TEST_PTR_FUNC_TYPED(void_int__void, void *, "%lx");
> +
> +struct _sized {
> +	int a;
> +	char b;
> +};
> +
> +DEFINE_TEST_ARRAY_NAMED_TYPED(sized, int, sized, struct _sized *, int, struct _sized *) = {
> +	{NULL, 0, NULL, NULL, NULL, false, false, false},
> +	{NULL, 1, (struct _sized *)(sizeof(struct _sized)), NULL, NULL, false, false, false},
> +	{NULL, 0x10, (struct _sized *)(sizeof(struct _sized) * 0x10), NULL, NULL, false, false, false},
> +	{(void *)(ULONG_MAX - sizeof(struct _sized)), 1, (struct _sized *)ULONG_MAX, NULL, NULL, false, false, false},
> +	{(void *)(ULONG_MAX - sizeof(struct _sized) + 1), 1, NULL, NULL, NULL, true, false, false},
> +	{(void *)(ULONG_MAX - sizeof(struct _sized) + 1), 2, (struct _sized *)(sizeof(struct _sized)), NULL, NULL, true, false, false},
> +	{(void *)(ULONG_MAX - sizeof(struct _sized) + 1), 3, (struct _sized *)(sizeof(struct _sized) * 2), NULL, NULL, true, false, false},
> +};
> +DEFINE_TEST_PTR_FUNC_TYPED(sized_int__sized, struct _sized *, "%lx");
> +
> +DEFINE_TEST_ARRAY_NAMED_TYPED(sized, size_t, sized, struct _sized *, size_t, struct _sized *) = {
> +	{NULL, 0, NULL, NULL, NULL, false, false, false},
> +	{NULL, 1, (struct _sized *)(sizeof(struct _sized)), NULL, NULL, false, false, false},
> +	{NULL, 0x10, (struct _sized *)(sizeof(struct _sized) * 0x10), NULL, NULL, false, false, false},
> +	{NULL, SIZE_MAX - 10, (struct _sized *)18446744073709551528UL, NULL, NULL, true, false, false},
> +};
> +DEFINE_TEST_PTR_FUNC_TYPED(sized_size_t__sized, struct _sized *, "%zu");
> +
>  /* Args are: value, shift, type, expected result, overflow expected */
>  #define TEST_ONE_SHIFT(a, s, t, expect, of)	do {			\
>  	typeof(a) __a = (a);						\
> @@ -1122,6 +1178,9 @@ static struct kunit_case overflow_test_cases[] = {
>  	KUNIT_CASE(s32_s32__s32_overflow_test),
>  	KUNIT_CASE(u64_u64__u64_overflow_test),
>  	KUNIT_CASE(s64_s64__s64_overflow_test),
> +	KUNIT_CASE(void_int__void_overflow_test),
> +	KUNIT_CASE(sized_int__sized_overflow_test),
> +	KUNIT_CASE(sized_size_t__sized_overflow_test),
>  	KUNIT_CASE(u32_u32__int_overflow_test),
>  	KUNIT_CASE(u32_u32__u8_overflow_test),
>  	KUNIT_CASE(u8_u8__int_overflow_test),
> --
> 2.34.1
>
Thanks
Justin

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition
  2024-01-26 22:52   ` Justin Stitt
@ 2024-01-26 22:57     ` Kees Cook
  0 siblings, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-26 22:57 UTC (permalink / raw)
  To: Justin Stitt
  Cc: linux-hardening, Gustavo A. R. Silva, Andrew Morton,
	Nathan Chancellor, Nick Desaulniers, Bill Wendling, llvm,
	linux-kernel

On Fri, Jan 26, 2024 at 10:52:57PM +0000, Justin Stitt wrote:
> [...]
> >  /**
> >   * check_sub_overflow() - Calculate subtraction with overflow checking
> 
> Does check_sub_overflow() deserve some more love in the future? I
> imagine "under"-flowing pointers is not at all common, though.

Yes, though I hadn't found any cases of it yet in the code, so I didn't
want to add a helper that would go unused. :)

> Nonetheless, this all looks good to me.
> 
> Reviewed-by: Justin Stitt <justinstitt@google.com>

Thanks!

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around
  2024-01-23  9:46 ` Mark Rutland
  2024-01-23 21:56   ` Kees Cook
@ 2024-01-29  6:27   ` Kees Cook
  1 sibling, 0 replies; 163+ messages in thread
From: Kees Cook @ 2024-01-29  6:27 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-hardening, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 23, 2024 at 09:46:35AM +0000, Mark Rutland wrote:
> This also misses the include/linux/atomic/atomic-arch-fallback.h
> implementations. Those are generated from the scripts/atomic/fallbacks/*
> templates, and you'll need to adjust at least fetch_add_unless and
> inc_unless_negative. As noted on other patches, my preference is to use
> add_wrap() in those.

How do I regenerate the header files using the templates? I found a
script, but its use eluded me, and it doesn't seem wired up to the
top-level Makefile? Maybe I missed something obvious...

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 33/82] mm/vmalloc: Refactor intentional wrap-around calculation
  2024-01-23  0:27 ` [PATCH 33/82] mm/vmalloc: " Kees Cook
@ 2024-01-30 18:55   ` Lorenzo Stoakes
  2024-01-30 19:54     ` Uladzislau Rezki
  0 siblings, 1 reply; 163+ messages in thread
From: Lorenzo Stoakes @ 2024-01-30 18:55 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, linux-mm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:08PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded unsigned wrap-around addition test to use
> check_add_overflow(), retaining the result for later usage (which removes
> the redundant open-coded addition). This paves the way to enabling the
> unsigned wrap-around sanitizer[2] in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Uladzislau Rezki <urezki@gmail.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> Cc: Lorenzo Stoakes <lstoakes@gmail.com>
> Cc: linux-mm@kvack.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  mm/vmalloc.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index d12a17fc0c17..7932ac99e9d3 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -1223,6 +1223,7 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
>  	unsigned long align, unsigned long vstart)
>  {
>  	unsigned long nva_start_addr;
> +	unsigned long sum;
>
>  	if (va->va_start > vstart)
>  		nva_start_addr = ALIGN(va->va_start, align);
> @@ -1230,11 +1231,11 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
>  		nva_start_addr = ALIGN(vstart, align);
>
>  	/* Can be overflowed due to big size or alignment. */
> -	if (nva_start_addr + size < nva_start_addr ||
> +	if (check_add_overflow(nva_start_addr, size, &sum) ||
>  			nva_start_addr < vstart)
>  		return false;
>
> -	return (nva_start_addr + size <= va->va_end);
> +	return (sum <= va->va_end);
>  }
>
>  /*
> --
> 2.34.1
>

Looks good to me,

Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 78/82] mm/vmalloc: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 78/82] mm/vmalloc: " Kees Cook
@ 2024-01-30 18:56   ` Lorenzo Stoakes
  0 siblings, 0 replies; 163+ messages in thread
From: Lorenzo Stoakes @ 2024-01-30 18:56 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, linux-mm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:53PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Uladzislau Rezki <urezki@gmail.com>
> Cc: Christoph Hellwig <hch@infradead.org>
> Cc: Lorenzo Stoakes <lstoakes@gmail.com>
> Cc: linux-mm@kvack.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  mm/vmalloc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 7932ac99e9d3..3d73f2ac6957 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -3750,7 +3750,7 @@ long vread_iter(struct iov_iter *iter, const char *addr, size_t count)
>  	addr = kasan_reset_tag(addr);
>
>  	/* Don't allow overflow */
> -	if ((unsigned long) addr + count < count)
> +	if (add_would_overflow(count, (unsigned long)addr))
>  		count = -(unsigned long) addr;
>
>  	remains = count;
> --
> 2.34.1
>

Looks good to me,

Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 47/82] dm verity: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 47/82] dm verity: " Kees Cook
@ 2024-01-30 18:58   ` Mike Snitzer
  0 siblings, 0 replies; 163+ messages in thread
From: Mike Snitzer @ 2024-01-30 18:58 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Alasdair Kergon, Mikulas Patocka, dm-devel,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22 2024 at  7:27P -0500,
Kees Cook <keescook@chromium.org> wrote:

> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Alasdair Kergon <agk@redhat.com>
> Cc: Mike Snitzer <snitzer@kernel.org>
> Cc: Mikulas Patocka <mpatocka@redhat.com>
> Cc: dm-devel@lists.linux.dev
> Signed-off-by: Kees Cook <keescook@chromium.org>

Please change subject to:
"dm: Refactor intentional wrap-around test in a few targets"

Reviewed-by: Mike Snitzer <snitzer@kernel.org>

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 33/82] mm/vmalloc: Refactor intentional wrap-around calculation
  2024-01-30 18:55   ` Lorenzo Stoakes
@ 2024-01-30 19:54     ` Uladzislau Rezki
  2024-01-30 21:57       ` Kees Cook
  0 siblings, 1 reply; 163+ messages in thread
From: Uladzislau Rezki @ 2024-01-30 19:54 UTC (permalink / raw)
  To: Lorenzo Stoakes, Kees Cook
  Cc: Kees Cook, linux-hardening, Andrew Morton, Uladzislau Rezki,
	Christoph Hellwig, linux-mm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 30, 2024 at 06:55:57PM +0000, Lorenzo Stoakes wrote:
> On Mon, Jan 22, 2024 at 04:27:08PM -0800, Kees Cook wrote:
> > In an effort to separate intentional arithmetic wrap-around from
> > unexpected wrap-around, we need to refactor places that depend on this
> > kind of math. One of the most common code patterns of this is:
> >
> > 	VAR + value < VAR
> >
> > Notably, this is considered "undefined behavior" for signed and pointer
> > types, which the kernel works around by using the -fno-strict-overflow
> > option in the build[1] (which used to just be -fwrapv). Regardless, we
> > want to get the kernel source to the position where we can meaningfully
> > instrument arithmetic wrap-around conditions and catch them when they
> > are unexpected, regardless of whether they are signed[2], unsigned[3],
> > or pointer[4] types.
> >
> > Refactor open-coded unsigned wrap-around addition test to use
> > check_add_overflow(), retaining the result for later usage (which removes
> > the redundant open-coded addition). This paves the way to enabling the
> > unsigned wrap-around sanitizer[2] in the future.
> >
> > Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> > Link: https://github.com/KSPP/linux/issues/26 [2]
> > Link: https://github.com/KSPP/linux/issues/27 [3]
> > Link: https://github.com/KSPP/linux/issues/344 [4]
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Uladzislau Rezki <urezki@gmail.com>
> > Cc: Christoph Hellwig <hch@infradead.org>
> > Cc: Lorenzo Stoakes <lstoakes@gmail.com>
> > Cc: linux-mm@kvack.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> >  mm/vmalloc.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > index d12a17fc0c17..7932ac99e9d3 100644
> > --- a/mm/vmalloc.c
> > +++ b/mm/vmalloc.c
> > @@ -1223,6 +1223,7 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
> >  	unsigned long align, unsigned long vstart)
> >  {
> >  	unsigned long nva_start_addr;
> > +	unsigned long sum;
> >
> >  	if (va->va_start > vstart)
> >  		nva_start_addr = ALIGN(va->va_start, align);
> > @@ -1230,11 +1231,11 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
> >  		nva_start_addr = ALIGN(vstart, align);
> >
> >  	/* Can be overflowed due to big size or alignment. */
> > -	if (nva_start_addr + size < nva_start_addr ||
> > +	if (check_add_overflow(nva_start_addr, size, &sum) ||
> >  			nva_start_addr < vstart)
> >  		return false;
> >
> > -	return (nva_start_addr + size <= va->va_end);
> > +	return (sum <= va->va_end);
> >  }
> >
> >  /*
> > --
> > 2.34.1
> >
> 
> Looks good to me,
> 
> Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>
>
Same here. One small nit though. The "sum" variable is not something
that it suits for. IMO, we should use a better name and replace it:

"nva_offset"?

--
Uladzislau Rezki

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 33/82] mm/vmalloc: Refactor intentional wrap-around calculation
  2024-01-30 19:54     ` Uladzislau Rezki
@ 2024-01-30 21:57       ` Kees Cook
  2024-01-31  9:44         ` Uladzislau Rezki
  0 siblings, 1 reply; 163+ messages in thread
From: Kees Cook @ 2024-01-30 21:57 UTC (permalink / raw)
  To: Uladzislau Rezki
  Cc: Lorenzo Stoakes, linux-hardening, Andrew Morton,
	Christoph Hellwig, linux-mm, Gustavo A. R. Silva, Bill Wendling,
	Justin Stitt, linux-kernel

On Tue, Jan 30, 2024 at 08:54:00PM +0100, Uladzislau Rezki wrote:
> On Tue, Jan 30, 2024 at 06:55:57PM +0000, Lorenzo Stoakes wrote:
> > On Mon, Jan 22, 2024 at 04:27:08PM -0800, Kees Cook wrote:
> > > In an effort to separate intentional arithmetic wrap-around from
> > > unexpected wrap-around, we need to refactor places that depend on this
> > > kind of math. One of the most common code patterns of this is:
> > >
> > > 	VAR + value < VAR
> > >
> > > Notably, this is considered "undefined behavior" for signed and pointer
> > > types, which the kernel works around by using the -fno-strict-overflow
> > > option in the build[1] (which used to just be -fwrapv). Regardless, we
> > > want to get the kernel source to the position where we can meaningfully
> > > instrument arithmetic wrap-around conditions and catch them when they
> > > are unexpected, regardless of whether they are signed[2], unsigned[3],
> > > or pointer[4] types.
> > >
> > > Refactor open-coded unsigned wrap-around addition test to use
> > > check_add_overflow(), retaining the result for later usage (which removes
> > > the redundant open-coded addition). This paves the way to enabling the
> > > unsigned wrap-around sanitizer[2] in the future.
> > >
> > > Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> > > Link: https://github.com/KSPP/linux/issues/26 [2]
> > > Link: https://github.com/KSPP/linux/issues/27 [3]
> > > Link: https://github.com/KSPP/linux/issues/344 [4]
> > > Cc: Andrew Morton <akpm@linux-foundation.org>
> > > Cc: Uladzislau Rezki <urezki@gmail.com>
> > > Cc: Christoph Hellwig <hch@infradead.org>
> > > Cc: Lorenzo Stoakes <lstoakes@gmail.com>
> > > Cc: linux-mm@kvack.org
> > > Signed-off-by: Kees Cook <keescook@chromium.org>
> > > ---
> > >  mm/vmalloc.c | 5 +++--
> > >  1 file changed, 3 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > > index d12a17fc0c17..7932ac99e9d3 100644
> > > --- a/mm/vmalloc.c
> > > +++ b/mm/vmalloc.c
> > > @@ -1223,6 +1223,7 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
> > >  	unsigned long align, unsigned long vstart)
> > >  {
> > >  	unsigned long nva_start_addr;
> > > +	unsigned long sum;
> > >
> > >  	if (va->va_start > vstart)
> > >  		nva_start_addr = ALIGN(va->va_start, align);
> > > @@ -1230,11 +1231,11 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
> > >  		nva_start_addr = ALIGN(vstart, align);
> > >
> > >  	/* Can be overflowed due to big size or alignment. */
> > > -	if (nva_start_addr + size < nva_start_addr ||
> > > +	if (check_add_overflow(nva_start_addr, size, &sum) ||
> > >  			nva_start_addr < vstart)
> > >  		return false;
> > >
> > > -	return (nva_start_addr + size <= va->va_end);
> > > +	return (sum <= va->va_end);
> > >  }
> > >
> > >  /*
> > > --
> > > 2.34.1
> > >
> > 
> > Looks good to me,
> > 
> > Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>
> >
> Same here. One small nit though. The "sum" variable is not something
> that it suits for. IMO, we should use a better name and replace it:
> 
> "nva_offset"?

Sure, I can use that. Other folks in other patches have suggested "end",
so maybe nva_end or nva_end_addr ?

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 33/82] mm/vmalloc: Refactor intentional wrap-around calculation
  2024-01-30 21:57       ` Kees Cook
@ 2024-01-31  9:44         ` Uladzislau Rezki
  0 siblings, 0 replies; 163+ messages in thread
From: Uladzislau Rezki @ 2024-01-31  9:44 UTC (permalink / raw)
  To: Kees Cook
  Cc: Uladzislau Rezki, Lorenzo Stoakes, linux-hardening,
	Andrew Morton, Christoph Hellwig, linux-mm, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

On Tue, Jan 30, 2024 at 01:57:12PM -0800, Kees Cook wrote:
> On Tue, Jan 30, 2024 at 08:54:00PM +0100, Uladzislau Rezki wrote:
> > On Tue, Jan 30, 2024 at 06:55:57PM +0000, Lorenzo Stoakes wrote:
> > > On Mon, Jan 22, 2024 at 04:27:08PM -0800, Kees Cook wrote:
> > > > In an effort to separate intentional arithmetic wrap-around from
> > > > unexpected wrap-around, we need to refactor places that depend on this
> > > > kind of math. One of the most common code patterns of this is:
> > > >
> > > > 	VAR + value < VAR
> > > >
> > > > Notably, this is considered "undefined behavior" for signed and pointer
> > > > types, which the kernel works around by using the -fno-strict-overflow
> > > > option in the build[1] (which used to just be -fwrapv). Regardless, we
> > > > want to get the kernel source to the position where we can meaningfully
> > > > instrument arithmetic wrap-around conditions and catch them when they
> > > > are unexpected, regardless of whether they are signed[2], unsigned[3],
> > > > or pointer[4] types.
> > > >
> > > > Refactor open-coded unsigned wrap-around addition test to use
> > > > check_add_overflow(), retaining the result for later usage (which removes
> > > > the redundant open-coded addition). This paves the way to enabling the
> > > > unsigned wrap-around sanitizer[2] in the future.
> > > >
> > > > Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> > > > Link: https://github.com/KSPP/linux/issues/26 [2]
> > > > Link: https://github.com/KSPP/linux/issues/27 [3]
> > > > Link: https://github.com/KSPP/linux/issues/344 [4]
> > > > Cc: Andrew Morton <akpm@linux-foundation.org>
> > > > Cc: Uladzislau Rezki <urezki@gmail.com>
> > > > Cc: Christoph Hellwig <hch@infradead.org>
> > > > Cc: Lorenzo Stoakes <lstoakes@gmail.com>
> > > > Cc: linux-mm@kvack.org
> > > > Signed-off-by: Kees Cook <keescook@chromium.org>
> > > > ---
> > > >  mm/vmalloc.c | 5 +++--
> > > >  1 file changed, 3 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > > > index d12a17fc0c17..7932ac99e9d3 100644
> > > > --- a/mm/vmalloc.c
> > > > +++ b/mm/vmalloc.c
> > > > @@ -1223,6 +1223,7 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
> > > >  	unsigned long align, unsigned long vstart)
> > > >  {
> > > >  	unsigned long nva_start_addr;
> > > > +	unsigned long sum;
> > > >
> > > >  	if (va->va_start > vstart)
> > > >  		nva_start_addr = ALIGN(va->va_start, align);
> > > > @@ -1230,11 +1231,11 @@ is_within_this_va(struct vmap_area *va, unsigned long size,
> > > >  		nva_start_addr = ALIGN(vstart, align);
> > > >
> > > >  	/* Can be overflowed due to big size or alignment. */
> > > > -	if (nva_start_addr + size < nva_start_addr ||
> > > > +	if (check_add_overflow(nva_start_addr, size, &sum) ||
> > > >  			nva_start_addr < vstart)
> > > >  		return false;
> > > >
> > > > -	return (nva_start_addr + size <= va->va_end);
> > > > +	return (sum <= va->va_end);
> > > >  }
> > > >
> > > >  /*
> > > > --
> > > > 2.34.1
> > > >
> > > 
> > > Looks good to me,
> > > 
> > > Reviewed-by: Lorenzo Stoakes <lstoakes@gmail.com>
> > >
> > Same here. One small nit though. The "sum" variable is not something
> > that it suits for. IMO, we should use a better name and replace it:
> > 
> > "nva_offset"?
> 
> Sure, I can use that. Other folks in other patches have suggested "end",
> so maybe nva_end or nva_end_addr ?
> 
nva_end_addr is probably the best fit.

--
Uladzislau Rezki

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 30/82] s390/kexec_file: Refactor intentional wrap-around calculation
  2024-01-23  0:27 ` [PATCH 30/82] s390/kexec_file: " Kees Cook
@ 2024-01-31 14:22   ` Alexander Gordeev
  2024-01-31 14:40     ` Sven Schnelle
  0 siblings, 1 reply; 163+ messages in thread
From: Alexander Gordeev @ 2024-01-31 14:22 UTC (permalink / raw)
  To: Kees Cook, Sven Schnelle
  Cc: linux-hardening, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Nico Boehr, Philipp Rudo, Baoquan He,
	Tao Liu, Alexander Egorenkov, linux-s390, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:05PM -0800, Kees Cook wrote:

Hi Kees,

...
>  arch/s390/include/asm/stacktrace.h    | 6 ++++--
>  arch/s390/kernel/machine_kexec_file.c | 5 +++--

Subject does not match. These need to be two separate commits.

>  2 files changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/s390/include/asm/stacktrace.h b/arch/s390/include/asm/stacktrace.h
> index 31ec4f545e03..3ce08d32a8ad 100644
> --- a/arch/s390/include/asm/stacktrace.h
> +++ b/arch/s390/include/asm/stacktrace.h
> @@ -34,11 +34,13 @@ int get_stack_info(unsigned long sp, struct task_struct *task,
>  static inline bool on_stack(struct stack_info *info,
>  			    unsigned long addr, size_t len)
>  {
> +	unsigned long sum;
> +
>  	if (info->type == STACK_TYPE_UNKNOWN)
>  		return false;
> -	if (addr + len < addr)
> +	if (check_add_overflow(addr, len, &sum))

Why not add_would_overflow()?

>  		return false;
> -	return addr >= info->begin && addr + len <= info->end;
> +	return addr >= info->begin && sum <= info->end;
>  }
>  
>  /*
> diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
> index 8d207b82d9fe..e5e925423061 100644
> --- a/arch/s390/kernel/machine_kexec_file.c
> +++ b/arch/s390/kernel/machine_kexec_file.c
> @@ -238,6 +238,7 @@ void *kexec_file_add_components(struct kimage *image,
>  	unsigned long max_command_line_size = LEGACY_COMMAND_LINE_SIZE;
>  	struct s390_load_data data = {0};
>  	unsigned long minsize;
> +	unsigned long sum;

Please, use min_kernel_buf_len instead of sum.

@Sven, could you please correct me if (minsize + max_command_line_size)
means something else.

>  	int ret;
>  
>  	data.report = ipl_report_init(&ipl_block);
> @@ -256,10 +257,10 @@ void *kexec_file_add_components(struct kimage *image,
>  	if (data.parm->max_command_line_size)
>  		max_command_line_size = data.parm->max_command_line_size;
>  
> -	if (minsize + max_command_line_size < minsize)
> +	if (check_add_overflow(minsize, max_command_line_size, &sum))
>  		goto out;
>  
> -	if (image->kernel_buf_len < minsize + max_command_line_size)
> +	if (image->kernel_buf_len < sum)
>  		goto out;
>  
>  	if (image->cmdline_buf_len >= max_command_line_size)

Thanks!

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 30/82] s390/kexec_file: Refactor intentional wrap-around calculation
  2024-01-31 14:22   ` Alexander Gordeev
@ 2024-01-31 14:40     ` Sven Schnelle
  0 siblings, 0 replies; 163+ messages in thread
From: Sven Schnelle @ 2024-01-31 14:40 UTC (permalink / raw)
  To: Alexander Gordeev
  Cc: Kees Cook, linux-hardening, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Nico Boehr, Philipp Rudo, Baoquan He,
	Tao Liu, Alexander Egorenkov, linux-s390, Gustavo A. R. Silva,
	Bill Wendling, Justin Stitt, linux-kernel

Alexander Gordeev <agordeev@linux.ibm.com> writes:

> On Mon, Jan 22, 2024 at 04:27:05PM -0800, Kees Cook wrote:
>> diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
>> index 8d207b82d9fe..e5e925423061 100644
>> --- a/arch/s390/kernel/machine_kexec_file.c
>> +++ b/arch/s390/kernel/machine_kexec_file.c
>> @@ -238,6 +238,7 @@ void *kexec_file_add_components(struct kimage *image,
>>  	unsigned long max_command_line_size = LEGACY_COMMAND_LINE_SIZE;
>>  	struct s390_load_data data = {0};
>>  	unsigned long minsize;
>> +	unsigned long sum;
>
> Please, use min_kernel_buf_len instead of sum.
>
> @Sven, could you please correct me if (minsize + max_command_line_size)
> means something else.

Your understanding is correct, minsize + max_command_line_size is the
minimum required size of the kernel image.

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 70/82] remoteproc: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 70/82] remoteproc: " Kees Cook
@ 2024-02-06 18:55   ` Bjorn Andersson
  0 siblings, 0 replies; 163+ messages in thread
From: Bjorn Andersson @ 2024-02-06 18:55 UTC (permalink / raw)
  To: Kees Cook
  Cc: linux-hardening, Mathieu Poirier, linux-remoteproc,
	Gustavo A. R. Silva, Bill Wendling, Justin Stitt, linux-kernel

On Mon, Jan 22, 2024 at 04:27:45PM -0800, Kees Cook wrote:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
> 
> 	VAR + value < VAR
> 
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
> 
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
> 
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Bjorn Andersson <andersson@kernel.org>

Acked-by: Bjorn Andersson <andersson@kernel.org>

Regards,
Bjorn


> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: linux-remoteproc@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  drivers/remoteproc/pru_rproc.c             | 2 +-
>  drivers/remoteproc/remoteproc_elf_loader.c | 2 +-
>  drivers/remoteproc/remoteproc_virtio.c     | 4 ++--
>  3 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/remoteproc/pru_rproc.c b/drivers/remoteproc/pru_rproc.c
> index 327f0c7ee3d6..834249ee3dd3 100644
> --- a/drivers/remoteproc/pru_rproc.c
> +++ b/drivers/remoteproc/pru_rproc.c
> @@ -893,7 +893,7 @@ pru_rproc_find_interrupt_map(struct device *dev, const struct firmware *fw)
>  			continue;
>  
>  		/* make sure we have the entire irq map */
> -		if (offset + size > fw->size || offset + size < size) {
> +		if (offset + size > fw->size || add_would_overflow(size, offset)) {
>  			dev_err(dev, ".pru_irq_map section truncated\n");
>  			return ERR_PTR(-EINVAL);
>  		}
> diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c
> index 94177e416047..b9231cf46d68 100644
> --- a/drivers/remoteproc/remoteproc_elf_loader.c
> +++ b/drivers/remoteproc/remoteproc_elf_loader.c
> @@ -278,7 +278,7 @@ find_table(struct device *dev, const struct firmware *fw)
>  		table = (struct resource_table *)(elf_data + offset);
>  
>  		/* make sure we have the entire table */
> -		if (offset + size > fw_size || offset + size < size) {
> +		if (offset + size > fw_size || add_would_overflow(size, offset)) {
>  			dev_err(dev, "resource table truncated\n");
>  			return NULL;
>  		}
> diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c
> index 83d76915a6ad..58742c666e35 100644
> --- a/drivers/remoteproc/remoteproc_virtio.c
> +++ b/drivers/remoteproc/remoteproc_virtio.c
> @@ -298,7 +298,7 @@ static void rproc_virtio_get(struct virtio_device *vdev, unsigned int offset,
>  	rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;
>  	cfg = &rsc->vring[rsc->num_of_vrings];
>  
> -	if (offset + len > rsc->config_len || offset + len < len) {
> +	if (offset + len > rsc->config_len || add_would_overflow(len, offset)) {
>  		dev_err(&vdev->dev, "rproc_virtio_get: access out of bounds\n");
>  		return;
>  	}
> @@ -316,7 +316,7 @@ static void rproc_virtio_set(struct virtio_device *vdev, unsigned int offset,
>  	rsc = (void *)rvdev->rproc->table_ptr + rvdev->rsc_offset;
>  	cfg = &rsc->vring[rsc->num_of_vrings];
>  
> -	if (offset + len > rsc->config_len || offset + len < len) {
> +	if (offset + len > rsc->config_len || add_would_overflow(len, offset)) {
>  		dev_err(&vdev->dev, "rproc_virtio_set: access out of bounds\n");
>  		return;
>  	}
> -- 
> 2.34.1
> 

^ permalink raw reply	[flat|nested] 163+ messages in thread

* Re: [PATCH 60/82] powerpc: Refactor intentional wrap-around test
  2024-01-23  0:27 ` [PATCH 60/82] powerpc: " Kees Cook
@ 2024-02-12  5:38   ` Michael Ellerman
  0 siblings, 0 replies; 163+ messages in thread
From: Michael Ellerman @ 2024-02-12  5:38 UTC (permalink / raw)
  To: Kees Cook, linux-hardening
  Cc: Kees Cook, Nicholas Piggin, Christophe Leroy, Aneesh Kumar K.V,
	Naveen N. Rao, Mahesh Salgaonkar, Vasant Hegde, dingsenjie,
	linuxppc-dev, Gustavo A. R. Silva, Bill Wendling, Justin Stitt,
	linux-kernel

Kees Cook <keescook@chromium.org> writes:
> In an effort to separate intentional arithmetic wrap-around from
> unexpected wrap-around, we need to refactor places that depend on this
> kind of math. One of the most common code patterns of this is:
>
> 	VAR + value < VAR
>
> Notably, this is considered "undefined behavior" for signed and pointer
> types, which the kernel works around by using the -fno-strict-overflow
> option in the build[1] (which used to just be -fwrapv). Regardless, we
> want to get the kernel source to the position where we can meaningfully
> instrument arithmetic wrap-around conditions and catch them when they
> are unexpected, regardless of whether they are signed[2], unsigned[3],
> or pointer[4] types.
>
> Refactor open-coded wrap-around addition test to use add_would_overflow().
> This paves the way to enabling the wrap-around sanitizers in the future.
>
> Link: https://git.kernel.org/linus/68df3755e383e6fecf2354a67b08f92f18536594 [1]
> Link: https://github.com/KSPP/linux/issues/26 [2]
> Link: https://github.com/KSPP/linux/issues/27 [3]
> Link: https://github.com/KSPP/linux/issues/344 [4]
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Nicholas Piggin <npiggin@gmail.com>
> Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
> Cc: "Aneesh Kumar K.V" <aneesh.kumar@kernel.org>
> Cc: "Naveen N. Rao" <naveen.n.rao@linux.ibm.com>
> Cc: Mahesh Salgaonkar <mahesh@linux.ibm.com>
> Cc: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
> Cc: dingsenjie <dingsenjie@yulong.com>
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
> Cc: Naveen N. Rao <naveen.n.rao@linux.ibm.com>
> Signed-off-by: Kees Cook <keescook@chromium.org>
> ---
>  arch/powerpc/platforms/powernv/opal-prd.c | 2 +-
>  arch/powerpc/xmon/xmon.c                  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)

Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)

cheers

^ permalink raw reply	[flat|nested] 163+ messages in thread

end of thread, other threads:[~2024-02-12  5:38 UTC | newest]

Thread overview: 163+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-23  0:26 [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kees Cook
2024-01-23  0:26 ` [PATCH 01/82] overflow: Expand check_add_overflow() for pointer addition Kees Cook
2024-01-26 22:52   ` Justin Stitt
2024-01-26 22:57     ` Kees Cook
2024-01-23  0:26 ` [PATCH 02/82] overflow: Introduce add_would_overflow() Kees Cook
2024-01-23  8:03   ` Rasmus Villemoes
2024-01-23 21:38     ` Kees Cook
2024-01-23  0:26 ` [PATCH 03/82] overflow: Introduce add_wrap() Kees Cook
2024-01-23  8:14   ` Rasmus Villemoes
2024-01-23 21:51     ` Kees Cook
2024-01-23  9:22   ` Mark Rutland
2024-01-23 21:52     ` Kees Cook
2024-01-23  0:26 ` [PATCH 04/82] docs: deprecated.rst: deprecate open-coded arithmetic wrap-around Kees Cook
2024-01-23  0:26 ` [PATCH 05/82] cocci: Refactor " Kees Cook
2024-01-23  0:26 ` [PATCH 06/82] overflow: Reintroduce signed and unsigned overflow sanitizers Kees Cook
2024-01-23  2:24   ` Miguel Ojeda
2024-01-23  4:45     ` Kees Cook
2024-01-23 11:20       ` Miguel Ojeda
2024-01-23  0:26 ` [PATCH 07/82] overflow: Introduce CONFIG_UBSAN_POINTER_WRAP Kees Cook
2024-01-23  0:26 ` [PATCH 08/82] iov_iter: Avoid wrap-around instrumentation in copy_compat_iovec_from_user Kees Cook
2024-01-23  0:26 ` [PATCH 09/82] select: Avoid wrap-around instrumentation in do_sys_poll() Kees Cook
2024-01-23 18:00   ` Jan Kara
2024-01-23  0:26 ` [PATCH 10/82] locking/atomic/x86: Silence intentional wrapping addition Kees Cook
2024-01-23  9:27   ` Mark Rutland
2024-01-23 21:54     ` Kees Cook
2024-01-23  0:26 ` [PATCH 11/82] arm64: atomics: lse: " Kees Cook
2024-01-23  9:53   ` Mark Rutland
2024-01-23  0:26 ` [PATCH 12/82] ipv4: " Kees Cook
2024-01-23  0:26 ` [PATCH 13/82] btrfs: Refactor intentional wrap-around calculation Kees Cook
2024-01-23  1:45   ` David Sterba
2024-01-23  0:26 ` [PATCH 14/82] smb: client: " Kees Cook
2024-01-23  0:26 ` [PATCH 15/82] dma-buf: " Kees Cook
2024-01-23  0:26 ` [PATCH 16/82] drm/nouveau/mmu: " Kees Cook
2024-01-23  0:26 ` [PATCH 17/82] drm/vc4: " Kees Cook
2024-01-23  0:26 ` [PATCH 18/82] ext4: " Kees Cook
2024-01-23  0:26 ` [PATCH 19/82] fs: " Kees Cook
2024-01-23 18:01   ` Jan Kara
2024-01-23  0:26 ` [PATCH 20/82] fpga: dfl: " Kees Cook
2024-01-23  0:26 ` [PATCH 21/82] drivers/fsi: " Kees Cook
2024-01-23  0:26 ` [PATCH 22/82] x86/sgx: " Kees Cook
2024-01-23  9:15   ` Jarkko Sakkinen
2024-01-23  0:26 ` [PATCH 23/82] KVM: " Kees Cook
2024-01-24 16:25   ` Sean Christopherson
2024-01-23  0:26 ` [PATCH 24/82] KVM: arm64: vgic: " Kees Cook
2024-01-23 10:49   ` Marc Zyngier
2024-01-24 15:13     ` Eric Auger
2024-01-23  0:27 ` [PATCH 25/82] KVM: SVM: " Kees Cook
2024-01-24 16:15   ` Sean Christopherson
2024-01-23  0:27 ` [PATCH 26/82] buildid: " Kees Cook
2024-01-23  0:27 ` [PATCH 27/82] m68k: " Kees Cook
2024-01-23  2:29   ` Liam R. Howlett
2024-01-23  8:13   ` Geert Uytterhoeven
2024-01-23 13:29     ` Eero Tamminen
2024-01-23 13:42       ` Geert Uytterhoeven
2024-01-23  0:27 ` [PATCH 28/82] niu: " Kees Cook
2024-01-23  0:27 ` [PATCH 29/82] rds: " Kees Cook
2024-01-23  0:27 ` [PATCH 30/82] s390/kexec_file: " Kees Cook
2024-01-31 14:22   ` Alexander Gordeev
2024-01-31 14:40     ` Sven Schnelle
2024-01-23  0:27 ` [PATCH 31/82] ARC: dw2 unwind: " Kees Cook
2024-01-23  0:27 ` [PATCH 32/82] vringh: " Kees Cook
2024-01-26 19:31   ` Eugenio Perez Martin
2024-01-26 19:42     ` Kees Cook
2024-01-23  0:27 ` [PATCH 33/82] mm/vmalloc: " Kees Cook
2024-01-30 18:55   ` Lorenzo Stoakes
2024-01-30 19:54     ` Uladzislau Rezki
2024-01-30 21:57       ` Kees Cook
2024-01-31  9:44         ` Uladzislau Rezki
2024-01-23  0:27 ` [PATCH 34/82] ipc: " Kees Cook
2024-01-23  1:07   ` Linus Torvalds
2024-01-23  1:38     ` Kees Cook
2024-01-23 18:06       ` Linus Torvalds
2024-01-23 19:00         ` Kees Cook
2024-01-23  0:27 ` [PATCH 35/82] ACPI: custom_method: Refactor intentional wrap-around test Kees Cook
2024-01-24 19:52   ` Rafael J. Wysocki
2024-01-24 20:16     ` Kees Cook
2024-01-23  0:27 ` [PATCH 36/82] agp: " Kees Cook
2024-01-23  0:27 ` [PATCH 37/82] aio: " Kees Cook
2024-01-23 15:30   ` Christian Brauner
2024-01-23 18:03   ` Jan Kara
2024-01-23  0:27 ` [PATCH 38/82] arm: 3117/1: " Kees Cook
2024-01-23  9:56   ` Mark Rutland
2024-01-23 22:41     ` Kees Cook
2024-01-23  0:27 ` [PATCH 39/82] crypto: " Kees Cook
2024-01-23  0:27 ` [PATCH 40/82] arm64: stacktrace: " Kees Cook
2024-01-23  9:58   ` Mark Rutland
2024-01-23  0:27 ` [PATCH 41/82] wil6210: " Kees Cook
2024-01-23  6:36   ` Kalle Valo
2024-01-23 11:50   ` Kalle Valo
2024-01-23 22:52     ` Kees Cook
2024-01-23  0:27 ` [PATCH 42/82] bcachefs: " Kees Cook
2024-01-23  6:36   ` Kent Overstreet
2024-01-23  0:27 ` [PATCH 43/82] bpf: " Kees Cook
2024-01-23  4:00   ` Yonghong Song
2024-01-23  4:07     ` Kees Cook
2024-01-23  5:13       ` Yonghong Song
2024-01-23  0:27 ` [PATCH 44/82] btrfs: " Kees Cook
2024-01-23 18:00   ` David Sterba
2024-01-23  0:27 ` [PATCH 45/82] cifs: " Kees Cook
2024-01-23  0:27 ` [PATCH 46/82] crypto: " Kees Cook
2024-01-23  3:07   ` Eric Biggers
2024-01-23  3:29     ` Kees Cook
2024-01-23  0:27 ` [PATCH 47/82] dm verity: " Kees Cook
2024-01-30 18:58   ` Mike Snitzer
2024-01-23  0:27 ` [PATCH 48/82] drm/nouveau/mmu: " Kees Cook
2024-01-23  0:27 ` [PATCH 49/82] drm/i915: " Kees Cook
2024-01-23  0:27 ` [PATCH 50/82] drm/vc4: " Kees Cook
2024-01-23  0:27 ` [PATCH 51/82] ext4: " Kees Cook
2024-01-23  0:27 ` [PATCH 52/82] f2fs: " Kees Cook
2024-01-23  0:27 ` [PATCH 53/82] fs: " Kees Cook
2024-01-23 18:02   ` Jan Kara
2024-01-23  0:27 ` [PATCH 54/82] hpfs: " Kees Cook
2024-01-23  0:27 ` [PATCH 55/82] kasan: " Kees Cook
2024-01-25 22:35   ` Andrey Konovalov
2024-01-23  0:27 ` [PATCH 56/82] usercopy: " Kees Cook
2024-01-23  0:27 ` [PATCH 57/82] KVM: arm64: vgic-v3: " Kees Cook
2024-01-23 10:50   ` Marc Zyngier
2024-01-24 15:12   ` Eric Auger
2024-01-23  0:27 ` [PATCH 58/82] s390/mm: " Kees Cook
2024-01-23  0:27 ` [PATCH 59/82] lib/scatterlist: " Kees Cook
2024-01-23  0:27 ` [PATCH 60/82] powerpc: " Kees Cook
2024-02-12  5:38   ` Michael Ellerman
2024-01-23  0:27 ` [PATCH 61/82] scsi: mpt3sas: " Kees Cook
2024-01-23  0:27 ` [PATCH 62/82] mwifiex: pcie: " Kees Cook
2024-01-23  6:36   ` Kalle Valo
2024-01-23  0:27 ` [PATCH 63/82] mm: " Kees Cook
2024-01-23  0:27 ` [PATCH 64/82] netfilter: " Kees Cook
2024-01-23 18:03   ` Florian Westphal
2024-01-23  0:27 ` [PATCH 65/82] nios2: " Kees Cook
2024-01-23 13:15   ` Dinh Nguyen
2024-01-23  0:27 ` [PATCH 66/82] fs/ntfs3: " Kees Cook
2024-01-23  0:27 ` [PATCH 67/82] ocfs2: " Kees Cook
2024-01-23  0:27 ` [PATCH 68/82] PCI: " Kees Cook
2024-01-23  0:27 ` [PATCH 69/82] perf tools: " Kees Cook
2024-01-23  6:21   ` Adrian Hunter
2024-01-23 21:31     ` Kees Cook
2024-01-23  0:27 ` [PATCH 70/82] remoteproc: " Kees Cook
2024-02-06 18:55   ` Bjorn Andersson
2024-01-23  0:27 ` [PATCH 71/82] s390/mm: " Kees Cook
2024-01-23  0:27 ` [PATCH 72/82] scsi: sd_zbc: " Kees Cook
2024-01-23  0:27 ` [PATCH 73/82] sh: " Kees Cook
2024-01-23  7:31   ` John Paul Adrian Glaubitz
2024-01-23  0:27 ` [PATCH 74/82] ARC: dw2 unwind: " Kees Cook
2024-01-23  0:27 ` [PATCH 75/82] timekeeping: " Kees Cook
2024-01-23  1:06   ` John Stultz
2024-01-24 19:34   ` Thomas Gleixner
2024-01-23  0:27 ` [PATCH 76/82] udf: " Kees Cook
2024-01-23 17:14   ` Jan Kara
2024-01-23  0:27 ` [PATCH 77/82] virtio: " Kees Cook
2024-01-26 19:33   ` Eugenio Perez Martin
2024-01-23  0:27 ` [PATCH 78/82] mm/vmalloc: " Kees Cook
2024-01-30 18:56   ` Lorenzo Stoakes
2024-01-23  0:27 ` [PATCH 79/82] staging: vme_user: " Kees Cook
2024-01-23  0:27 ` [PATCH 80/82] xen-netback: " Kees Cook
2024-01-23  7:55   ` Jan Beulich
2024-01-23 21:32     ` Kees Cook
2024-01-23  0:27 ` [PATCH 81/82] lib: zstd: " Kees Cook
2024-01-23  0:27 ` [PATCH 82/82] mqueue: " Kees Cook
2024-01-23  2:22 ` [PATCH 00/82] overflow: Refactor open-coded arithmetic wrap-around Kent Overstreet
2024-01-23  2:51   ` Kees Cook
2024-01-23  9:46 ` Mark Rutland
2024-01-23 21:56   ` Kees Cook
2024-01-29  6:27   ` Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).