|
|
d5c737 |
From 73635c7e096eb36b52c1e874f9b76856c6a41228 Mon Sep 17 00:00:00 2001
|
|
|
d5c737 |
From: Peter Jones <pjones@redhat.com>
|
|
|
d5c737 |
Date: Mon, 17 Jun 2019 16:37:29 -0400
|
|
|
d5c737 |
Subject: [PATCH 36/63] util.h: implement add()/mul()/sub() for more integer
|
|
|
d5c737 |
types.
|
|
|
d5c737 |
|
|
|
d5c737 |
This adds the following:
|
|
|
d5c737 |
uint_add()
|
|
|
d5c737 |
uint_mul()
|
|
|
d5c737 |
uint_sub()
|
|
|
d5c737 |
long_sub()
|
|
|
d5c737 |
ulong_sub()
|
|
|
d5c737 |
|
|
|
d5c737 |
Additionally it renames ulong_mult() to ulong_mul() and long_mult() to
|
|
|
d5c737 |
long_mul().
|
|
|
d5c737 |
|
|
|
d5c737 |
As before, all of these are available without caring about the types,
|
|
|
d5c737 |
as if declared:
|
|
|
d5c737 |
|
|
|
d5c737 |
bool add(TYPE addend, TYPE addend, TYPE *sum);
|
|
|
d5c737 |
bool mul(TYPE factor, TYPE factor, TYPE *product);
|
|
|
d5c737 |
bool sub(TYPE minuend, TYPE subtractahend, TYPE *difference);
|
|
|
d5c737 |
|
|
|
d5c737 |
If overflow would occur, the pointer target for the result is not
|
|
|
d5c737 |
changed and the function returns true, otherwise it returns false.
|
|
|
d5c737 |
|
|
|
d5c737 |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
d5c737 |
---
|
|
|
d5c737 |
src/efivar.h | 1 +
|
|
|
d5c737 |
src/safemath.h | 208 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
d5c737 |
src/util.h | 96 -----------------------
|
|
|
d5c737 |
3 files changed, 209 insertions(+), 96 deletions(-)
|
|
|
d5c737 |
create mode 100644 src/safemath.h
|
|
|
d5c737 |
|
|
|
d5c737 |
diff --git a/src/efivar.h b/src/efivar.h
|
|
|
d5c737 |
index 3d4b429631e..646863d14c5 100644
|
|
|
d5c737 |
--- a/src/efivar.h
|
|
|
d5c737 |
+++ b/src/efivar.h
|
|
|
d5c737 |
@@ -23,6 +23,7 @@
|
|
|
d5c737 |
#include <efivar/efivar.h>
|
|
|
d5c737 |
|
|
|
d5c737 |
#include "util.h"
|
|
|
d5c737 |
+#include "safemath.h"
|
|
|
d5c737 |
#include "efivar_endian.h"
|
|
|
d5c737 |
#include "lib.h"
|
|
|
d5c737 |
#include "guid.h"
|
|
|
d5c737 |
diff --git a/src/safemath.h b/src/safemath.h
|
|
|
d5c737 |
new file mode 100644
|
|
|
d5c737 |
index 00000000000..08dfef7ec0b
|
|
|
d5c737 |
--- /dev/null
|
|
|
d5c737 |
+++ b/src/safemath.h
|
|
|
d5c737 |
@@ -0,0 +1,208 @@
|
|
|
d5c737 |
+/*
|
|
|
d5c737 |
+ * safemath.h
|
|
|
d5c737 |
+ * Copyright 2016-2019 Peter Jones <pjones@redhat.com>
|
|
|
d5c737 |
+ *
|
|
|
d5c737 |
+ * This library is free software; you can redistribute it and/or
|
|
|
d5c737 |
+ * modify it under the terms of the GNU Lesser General Public License as
|
|
|
d5c737 |
+ * published by the Free Software Foundation; either version 2.1 of the
|
|
|
d5c737 |
+ * License, or (at your option) any later version.
|
|
|
d5c737 |
+ *
|
|
|
d5c737 |
+ * This library is distributed in the hope that it will be useful,
|
|
|
d5c737 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d5c737 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
d5c737 |
+ * Lesser General Public License for more details.
|
|
|
d5c737 |
+ *
|
|
|
d5c737 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
d5c737 |
+ * License along with this library; if not, see
|
|
|
d5c737 |
+ * <http://www.gnu.org/licenses/>.
|
|
|
d5c737 |
+ *
|
|
|
d5c737 |
+ */
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef SAFEMATH_H_
|
|
|
d5c737 |
+#define SAFEMATH_H_
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+/*
|
|
|
d5c737 |
+ * I'm not actually sure when these appear, but they're present in the
|
|
|
d5c737 |
+ * version in front of me.
|
|
|
d5c737 |
+ */
|
|
|
d5c737 |
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
|
|
d5c737 |
+#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
|
|
|
d5c737 |
+#define int_add(a, b, c) __builtin_add_overflow(a, b, c)
|
|
|
d5c737 |
+#define uint_add(a, b, c) __builtin_add_overflow(a, b, c)
|
|
|
d5c737 |
+#define long_add(a, b, c) __builtin_add_overflow(a, b, c)
|
|
|
d5c737 |
+#define ulong_add(a, b, c) __builtin_add_overflow(a, b, c)
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#define int_mul(a, b, c) __builtin_mul_overflow(a, b, c)
|
|
|
d5c737 |
+#define uint_mul(a, b, c) __builtin_mul_overflow(a, b, c)
|
|
|
d5c737 |
+#define long_mul(a, b, c) __builtin_mul_overflow(a, b, c)
|
|
|
d5c737 |
+#define ulong_mul(a, b, c) __builtin_mul_overflow(a, b, c)
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#define int_sub(a, b, c) __builtin_sub_overflow(a, b, c)
|
|
|
d5c737 |
+#define uint_sub(a, b, c) __builtin_sub_overflow(a, b, c)
|
|
|
d5c737 |
+#define long_sub(a, b, c) __builtin_sub_overflow(a, b, c)
|
|
|
d5c737 |
+#define ulong_sub(a, b, c) __builtin_sub_overflow(a, b, c)
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef int_add
|
|
|
d5c737 |
+#define int_add(a, b, c) ({ \
|
|
|
d5c737 |
+ const int _limit = INT_MAX; \
|
|
|
d5c737 |
+ long int _ret = _limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) + (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef uint_add
|
|
|
d5c737 |
+#define uint_add(a, b, c) ({ \
|
|
|
d5c737 |
+ const unsigned int _limit = UINT_MAX; \
|
|
|
d5c737 |
+ unsigned int _ret = _limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) + (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef long_add
|
|
|
d5c737 |
+#define long_add(a, b, c) ({ \
|
|
|
d5c737 |
+ const long _limit = LONG_MAX; \
|
|
|
d5c737 |
+ long _ret = _limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) + (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef ulong_add
|
|
|
d5c737 |
+#define ulong_add(a, b, c) ({ \
|
|
|
d5c737 |
+ const unsigned long _limit = ULONG_MAX; \
|
|
|
d5c737 |
+ unsigned long _ret = _limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) + (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef int_mul
|
|
|
d5c737 |
+#define int_mul(a, b, c) ({ \
|
|
|
d5c737 |
+ int _ret; \
|
|
|
d5c737 |
+ _ret = __builtin_popcount(a) + __builtin_popcount(b); \
|
|
|
d5c737 |
+ _ret = _ret < ((sizeof(a) + sizeof(b)) << 4); \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) * (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef uint_mul
|
|
|
d5c737 |
+#define uint_mul(a, b, c) int_mul(a, b, c)
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef long_mul
|
|
|
d5c737 |
+#define long_mul(a, b, c) int_mul(a, b, c)
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef ulong_mul
|
|
|
d5c737 |
+#define ulong_mul(a, b, c) int_mul(a, b, c)
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef int_sub
|
|
|
d5c737 |
+#define int_sub(a, b, c) ({ \
|
|
|
d5c737 |
+ const long _min_limit = INT_MIN; \
|
|
|
d5c737 |
+ const long _max_limit = INT_MAX; \
|
|
|
d5c737 |
+ int _ret; \
|
|
|
d5c737 |
+ _ret = _min_limit + (b); \
|
|
|
d5c737 |
+ _ret = !(_ret < (a)); \
|
|
|
d5c737 |
+ if (!_ret) { \
|
|
|
d5c737 |
+ _ret = _max_limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ } \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) - (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef uint_sub
|
|
|
d5c737 |
+#define uint_sub(a, b, c) ({ \
|
|
|
d5c737 |
+ const unsigned int _limit = UINT_MAX; \
|
|
|
d5c737 |
+ unsigned int _ret = _limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) - (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef long_sub
|
|
|
d5c737 |
+#define long_sub(a, b, c) ({ \
|
|
|
d5c737 |
+ const long _min_limit = LONG_MIN; \
|
|
|
d5c737 |
+ const long _max_limit = LONG_MAX; \
|
|
|
d5c737 |
+ int _ret; \
|
|
|
d5c737 |
+ _ret = _min_limit + (b); \
|
|
|
d5c737 |
+ _ret = !(_ret < (a)); \
|
|
|
d5c737 |
+ if (!_ret) { \
|
|
|
d5c737 |
+ _ret = _max_limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ } \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) - (b)); \
|
|
|
d5c737 |
+ (bool)_ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef ulong_sub
|
|
|
d5c737 |
+#define ulong_sub(a, b, c) ({ \
|
|
|
d5c737 |
+ const unsigned long _limit = ULONG_MAX; \
|
|
|
d5c737 |
+ unsigned long _ret = _limit - (a); \
|
|
|
d5c737 |
+ _ret = _ret > (b); \
|
|
|
d5c737 |
+ if (!_ret) \
|
|
|
d5c737 |
+ *(c) = ((a) - (b)); \
|
|
|
d5c737 |
+ _ret; \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
|
|
d5c737 |
+#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
|
|
|
d5c737 |
+#define add(a, b, c) _Generic((c), \
|
|
|
d5c737 |
+ int *: int_add(a, b, c), \
|
|
|
d5c737 |
+ unsigned int *: uint_add(a, b, c), \
|
|
|
d5c737 |
+ long *: long_add(a, b, c), \
|
|
|
d5c737 |
+ unsigned long *: ulong_add(a, b, c))
|
|
|
d5c737 |
+#define sub(a, b, c) _Generic((c), \
|
|
|
d5c737 |
+ int *: int_sub(a, b, c), \
|
|
|
d5c737 |
+ unsigned int *: uint_sub(a, b, c), \
|
|
|
d5c737 |
+ long *: long_sub(a, b, c), \
|
|
|
d5c737 |
+ unsigned long *: ulong_sub(a, b, c))
|
|
|
d5c737 |
+#define mul(a, b, c) _Generic((c), \
|
|
|
d5c737 |
+ int *: int_sub(a, b, c), \
|
|
|
d5c737 |
+ unsigned int *: uint_mul(a, b, c), \
|
|
|
d5c737 |
+ long *: long_mul(a, b, c), \
|
|
|
d5c737 |
+ unsigned long *: ulong_mul(a, b, c))
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#ifndef add
|
|
|
d5c737 |
+#define add(a, b, c) ({ \
|
|
|
d5c737 |
+ (*(c)) = ((a) + (b)); \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+#ifndef mul
|
|
|
d5c737 |
+#define mul(a, b, c) ({ \
|
|
|
d5c737 |
+ (*(c)) = ((a) * (b)); \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+#ifndef sub
|
|
|
d5c737 |
+#define sub(a, b, c) ({ \
|
|
|
d5c737 |
+ (*(c)) = ((a) - (b)); \
|
|
|
d5c737 |
+ })
|
|
|
d5c737 |
+#endif
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+
|
|
|
d5c737 |
+#endif /* !SAFEMATH_H_ */
|
|
|
d5c737 |
+// vim:fenc=utf-8:tw=75:noet
|
|
|
d5c737 |
diff --git a/src/util.h b/src/util.h
|
|
|
d5c737 |
index 712abea2d42..3f68d812700 100644
|
|
|
d5c737 |
--- a/src/util.h
|
|
|
d5c737 |
+++ b/src/util.h
|
|
|
d5c737 |
@@ -61,102 +61,6 @@
|
|
|
d5c737 |
#define unlikely(x) (__branch_check__(x, 0, __builtin_constant_p(x)))
|
|
|
d5c737 |
#endif
|
|
|
d5c737 |
|
|
|
d5c737 |
-/*
|
|
|
d5c737 |
- * I'm not actually sure when these appear, but they're present in the
|
|
|
d5c737 |
- * version in front of me.
|
|
|
d5c737 |
- */
|
|
|
d5c737 |
-#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
|
|
d5c737 |
-#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
|
|
|
d5c737 |
-#define int_add(a, b, c) __builtin_add_overflow(a, b, c)
|
|
|
d5c737 |
-#define long_add(a, b, c) __builtin_add_overflow(a, b, c)
|
|
|
d5c737 |
-#define long_mult(a, b, c) __builtin_mul_overflow(a, b, c)
|
|
|
d5c737 |
-#define ulong_add(a, b, c) __builtin_add_overflow(a, b, c)
|
|
|
d5c737 |
-#define ulong_mult(a, b, c) __builtin_mul_overflow(a, b, c)
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#ifndef int_add
|
|
|
d5c737 |
-#define int_add(a, b, c) ({ \
|
|
|
d5c737 |
- const int _limit = INT_MAX; \
|
|
|
d5c737 |
- int _ret; \
|
|
|
d5c737 |
- _ret = _limit - ((unsigned long long)a) > \
|
|
|
d5c737 |
- ((unsigned long long)b); \
|
|
|
d5c737 |
- if (!_ret) \
|
|
|
d5c737 |
- *(c) = ((a) + (b)); \
|
|
|
d5c737 |
- _ret; \
|
|
|
d5c737 |
- })
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#ifndef long_add
|
|
|
d5c737 |
-#define long_add(a, b, c) ({ \
|
|
|
d5c737 |
- const long _limit = LONG_MAX; \
|
|
|
d5c737 |
- int _ret; \
|
|
|
d5c737 |
- _ret = _limit - ((unsigned long long)a) > \
|
|
|
d5c737 |
- ((unsigned long long)b); \
|
|
|
d5c737 |
- if (!_ret) \
|
|
|
d5c737 |
- *(c) = ((a) + (b)); \
|
|
|
d5c737 |
- _ret; \
|
|
|
d5c737 |
- })
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#ifndef long_mult
|
|
|
d5c737 |
-#define long_mult(a, b, c) ({ \
|
|
|
d5c737 |
- const long _limit = LONG_MAX; \
|
|
|
d5c737 |
- int _ret = 1; \
|
|
|
d5c737 |
- if ((a) == 0 || (b) == 0) \
|
|
|
d5c737 |
- _ret = 0; \
|
|
|
d5c737 |
- else \
|
|
|
d5c737 |
- _ret = _limit / (a) < (b); \
|
|
|
d5c737 |
- if (!_ret) \
|
|
|
d5c737 |
- *(c) = ((a) * (b)); \
|
|
|
d5c737 |
- _ret; \
|
|
|
d5c737 |
- })
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#ifndef ulong_add
|
|
|
d5c737 |
-#define ulong_add(a, b, c) ({ \
|
|
|
d5c737 |
- const unsigned long _limit = ULONG_MAX; \
|
|
|
d5c737 |
- int _ret; \
|
|
|
d5c737 |
- _ret = _limit - ((unsigned long long)a) > \
|
|
|
d5c737 |
- ((unsigned long long)b); \
|
|
|
d5c737 |
- if (!_ret) \
|
|
|
d5c737 |
- *(c) = ((a) + (b)); \
|
|
|
d5c737 |
- _ret; \
|
|
|
d5c737 |
- })
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#ifndef ulong_mult
|
|
|
d5c737 |
-#define ulong_mult(a, b, c) ({ \
|
|
|
d5c737 |
- const unsigned long _limit = ULONG_MAX; \
|
|
|
d5c737 |
- int _ret = 1; \
|
|
|
d5c737 |
- if ((a) == 0 || (b) == 0) \
|
|
|
d5c737 |
- _ret = 0; \
|
|
|
d5c737 |
- else \
|
|
|
d5c737 |
- _ret = _limit / (a) < (b); \
|
|
|
d5c737 |
- if (!_ret) \
|
|
|
d5c737 |
- *(c) = ((a) * (b)); \
|
|
|
d5c737 |
- _ret; \
|
|
|
d5c737 |
- })
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-
|
|
|
d5c737 |
-#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
|
|
d5c737 |
-#if __GNUC__ >= 5 && __GNUC_MINOR__ >= 1
|
|
|
d5c737 |
-#define add(a, b, c) _Generic((c), \
|
|
|
d5c737 |
- int *: int_add(a,b,c), \
|
|
|
d5c737 |
- long *: long_add(a,b,c), \
|
|
|
d5c737 |
- unsigned long *: ulong_add(a,b,c))
|
|
|
d5c737 |
-#define mult(a, b, c) _Generic((c), \
|
|
|
d5c737 |
- long *: long_mult(a,b,c), \
|
|
|
d5c737 |
- unsigned long *: ulong_mult(a,b,c))
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-
|
|
|
d5c737 |
-#ifndef add
|
|
|
d5c737 |
-#define add(a, b, c) ({ \
|
|
|
d5c737 |
- (*(c)) = ((a) + (b)); \
|
|
|
d5c737 |
- })
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-#ifndef mult
|
|
|
d5c737 |
-#define mult(a, b, c) ({ \
|
|
|
d5c737 |
- (*(c)) = ((a) * (b)); \
|
|
|
d5c737 |
- })
|
|
|
d5c737 |
-#endif
|
|
|
d5c737 |
-
|
|
|
d5c737 |
static inline int UNUSED
|
|
|
d5c737 |
read_file(int fd, uint8_t **result, size_t *bufsize)
|
|
|
d5c737 |
{
|
|
|
d5c737 |
--
|
|
|
d5c737 |
2.26.2
|
|
|
d5c737 |
|