From f27182695d88350b48c8b9a6dce54bb513d7aa4e Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 27 Jul 2023 15:13:08 -0400
Subject: [PATCH] Add primitives for overflow-checked arithmetic operations.

We need to do arithmetic on untrusted values sometimes, so this patch
adds the following primitives as macros that wrap the compiler builtins.

  bool checked_add(TYPE addend0, TYPE addend1, TYPE *sum)
  bool checked_sub(TYPE minuend, TYPE subtrahend, TYPE *difference)
  bool checked_mul(TYPE factor0, TYPE factor1, TYPE *product)

And also the following primitive which returns True if divisor is 0 and
False otherwise:

  bool checked_div(TYPE dividend, TYPE divisor, TYPE *quotient)

Signed-off-by: Peter Jones <pjones@redhat.com>
---
 include/compiler.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/include/compiler.h b/include/compiler.h
index b0d595f..545a72e 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -198,5 +198,21 @@
 #error shim has no cache_invalidate() implementation for this compiler
 #endif /* __GNUC__ */
 
+#define checked_add(addend0, addend1, sum) \
+	__builtin_add_overflow(addend0, addend1, sum)
+#define checked_sub(minuend, subtrahend, difference) \
+	__builtin_sub_overflow(minuend, subtrahend, difference)
+#define checked_mul(factor0, factor1, product) \
+	__builtin_mul_overflow(factor0, factor1, product)
+#define checked_div(dividend, divisor, quotient)                \
+        ({                                                      \
+                bool _ret = True;                               \
+                if ((divisor) != 0) {                           \
+                        _ret = False;                           \
+                        (quotient) = (dividend) / (divisor);    \
+                }                                               \
+                _ret;                                           \
+        })
+
 #endif /* !COMPILER_H_ */
 // vim:fenc=utf-8:tw=75:et
-- 
2.33.0

