kernel: backport and include linux/overflow.h
authorFelix Fietkau <nbd@nbd.name>
Wed, 12 Sep 2018 14:58:32 +0000 (16:58 +0200)
committerFelix Fietkau <nbd@nbd.name>
Fri, 9 Nov 2018 14:06:08 +0000 (15:06 +0100)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/011-backport-overflow_h.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/011-backport-overflow_h.patch b/package/kernel/mac80211/patches/011-backport-overflow_h.patch
new file mode 100644 (file)
index 0000000..169d3ba
--- /dev/null
@@ -0,0 +1,322 @@
+--- a/backport-include/linux/slab.h
++++ b/backport-include/linux/slab.h
+@@ -1,6 +1,7 @@
+ #ifndef __BACKPORT_SLAB_H
+ #define __BACKPORT_SLAB_H
+ #include_next <linux/slab.h>
++#include <linux/overflow.h>
+ #include <linux/version.h>
+ #if LINUX_VERSION_IS_LESS(3,4,0)
+--- /dev/null
++++ b/include/linux/overflow.h
+@@ -0,0 +1,309 @@
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */
++#ifndef __LINUX_OVERFLOW_H
++#define __LINUX_OVERFLOW_H
++
++#include <linux/compiler.h>
++
++/*
++ * In the fallback code below, we need to compute the minimum and
++ * maximum values representable in a given type. These macros may also
++ * be useful elsewhere, so we provide them outside the
++ * COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW block.
++ *
++ * It would seem more obvious to do something like
++ *
++ * #define type_min(T) (T)(is_signed_type(T) ? (T)1 << (8*sizeof(T)-1) : 0)
++ * #define type_max(T) (T)(is_signed_type(T) ? ((T)1 << (8*sizeof(T)-1)) - 1 : ~(T)0)
++ *
++ * Unfortunately, the middle expressions, strictly speaking, have
++ * undefined behaviour, and at least some versions of gcc warn about
++ * the type_max expression (but not if -fsanitize=undefined is in
++ * effect; in that case, the warning is deferred to runtime...).
++ *
++ * The slightly excessive casting in type_min is to make sure the
++ * macros also produce sensible values for the exotic type _Bool. [The
++ * overflow checkers only almost work for _Bool, but that's
++ * a-feature-not-a-bug, since people shouldn't be doing arithmetic on
++ * _Bools. Besides, the gcc builtins don't allow _Bool* as third
++ * argument.]
++ *
++ * Idea stolen from
++ * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html -
++ * credit to Christian Biere.
++ */
++#define is_signed_type(type)       (((type)(-1)) < (type)1)
++#define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type)))
++#define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T)))
++#define type_min(T) ((T)((T)-type_max(T)-(T)1))
++
++
++#ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW
++/*
++ * For simplicity and code hygiene, the fallback code below insists on
++ * a, b and *d having the same type (similar to the min() and max()
++ * macros), whereas gcc's type-generic overflow checkers accept
++ * different types. Hence we don't just make check_add_overflow an
++ * alias for __builtin_add_overflow, but add type checks similar to
++ * below.
++ */
++#define check_add_overflow(a, b, d) ({                \
++      typeof(a) __a = (a);                    \
++      typeof(b) __b = (b);                    \
++      typeof(d) __d = (d);                    \
++      (void) (&__a == &__b);                  \
++      (void) (&__a == __d);                   \
++      __builtin_add_overflow(__a, __b, __d);  \
++})
++
++#define check_sub_overflow(a, b, d) ({                \
++      typeof(a) __a = (a);                    \
++      typeof(b) __b = (b);                    \
++      typeof(d) __d = (d);                    \
++      (void) (&__a == &__b);                  \
++      (void) (&__a == __d);                   \
++      __builtin_sub_overflow(__a, __b, __d);  \
++})
++
++#define check_mul_overflow(a, b, d) ({                \
++      typeof(a) __a = (a);                    \
++      typeof(b) __b = (b);                    \
++      typeof(d) __d = (d);                    \
++      (void) (&__a == &__b);                  \
++      (void) (&__a == __d);                   \
++      __builtin_mul_overflow(__a, __b, __d);  \
++})
++
++#else
++
++
++/* Checking for unsigned overflow is relatively easy without causing UB. */
++#define __unsigned_add_overflow(a, b, d) ({   \
++      typeof(a) __a = (a);                    \
++      typeof(b) __b = (b);                    \
++      typeof(d) __d = (d);                    \
++      (void) (&__a == &__b);                  \
++      (void) (&__a == __d);                   \
++      *__d = __a + __b;                       \
++      *__d < __a;                             \
++})
++#define __unsigned_sub_overflow(a, b, d) ({   \
++      typeof(a) __a = (a);                    \
++      typeof(b) __b = (b);                    \
++      typeof(d) __d = (d);                    \
++      (void) (&__a == &__b);                  \
++      (void) (&__a == __d);                   \
++      *__d = __a - __b;                       \
++      __a < __b;                              \
++})
++/*
++ * If one of a or b is a compile-time constant, this avoids a division.
++ */
++#define __unsigned_mul_overflow(a, b, d) ({           \
++      typeof(a) __a = (a);                            \
++      typeof(b) __b = (b);                            \
++      typeof(d) __d = (d);                            \
++      (void) (&__a == &__b);                          \
++      (void) (&__a == __d);                           \
++      *__d = __a * __b;                               \
++      __builtin_constant_p(__b) ?                     \
++        __b > 0 && __a > type_max(typeof(__a)) / __b : \
++        __a > 0 && __b > type_max(typeof(__b)) / __a;  \
++})
++
++/*
++ * For signed types, detecting overflow is much harder, especially if
++ * we want to avoid UB. But the interface of these macros is such that
++ * we must provide a result in *d, and in fact we must produce the
++ * result promised by gcc's builtins, which is simply the possibly
++ * wrapped-around value. Fortunately, we can just formally do the
++ * operations in the widest relevant unsigned type (u64) and then
++ * truncate the result - gcc is smart enough to generate the same code
++ * with and without the (u64) casts.
++ */
++
++/*
++ * Adding two signed integers can overflow only if they have the same
++ * sign, and overflow has happened iff the result has the opposite
++ * sign.
++ */
++#define __signed_add_overflow(a, b, d) ({     \
++      typeof(a) __a = (a);                    \
++      typeof(b) __b = (b);                    \
++      typeof(d) __d = (d);                    \
++      (void) (&__a == &__b);                  \
++      (void) (&__a == __d);                   \
++      *__d = (u64)__a + (u64)__b;             \
++      (((~(__a ^ __b)) & (*__d ^ __a))        \
++              & type_min(typeof(__a))) != 0;  \
++})
++
++/*
++ * Subtraction is similar, except that overflow can now happen only
++ * when the signs are opposite. In this case, overflow has happened if
++ * the result has the opposite sign of a.
++ */
++#define __signed_sub_overflow(a, b, d) ({     \
++      typeof(a) __a = (a);                    \
++      typeof(b) __b = (b);                    \
++      typeof(d) __d = (d);                    \
++      (void) (&__a == &__b);                  \
++      (void) (&__a == __d);                   \
++      *__d = (u64)__a - (u64)__b;             \
++      ((((__a ^ __b)) & (*__d ^ __a))         \
++              & type_min(typeof(__a))) != 0;  \
++})
++
++/*
++ * Signed multiplication is rather hard. gcc always follows C99, so
++ * division is truncated towards 0. This means that we can write the
++ * overflow check like this:
++ *
++ * (a > 0 && (b > MAX/a || b < MIN/a)) ||
++ * (a < -1 && (b > MIN/a || b < MAX/a) ||
++ * (a == -1 && b == MIN)
++ *
++ * The redundant casts of -1 are to silence an annoying -Wtype-limits
++ * (included in -Wextra) warning: When the type is u8 or u16, the
++ * __b_c_e in check_mul_overflow obviously selects
++ * __unsigned_mul_overflow, but unfortunately gcc still parses this
++ * code and warns about the limited range of __b.
++ */
++
++#define __signed_mul_overflow(a, b, d) ({                             \
++      typeof(a) __a = (a);                                            \
++      typeof(b) __b = (b);                                            \
++      typeof(d) __d = (d);                                            \
++      typeof(a) __tmax = type_max(typeof(a));                         \
++      typeof(a) __tmin = type_min(typeof(a));                         \
++      (void) (&__a == &__b);                                          \
++      (void) (&__a == __d);                                           \
++      *__d = (u64)__a * (u64)__b;                                     \
++      (__b > 0   && (__a > __tmax/__b || __a < __tmin/__b)) ||        \
++      (__b < (typeof(__b))-1  && (__a > __tmin/__b || __a < __tmax/__b)) || \
++      (__b == (typeof(__b))-1 && __a == __tmin);                      \
++})
++
++
++#define check_add_overflow(a, b, d)                                   \
++      __builtin_choose_expr(is_signed_type(typeof(a)),                \
++                      __signed_add_overflow(a, b, d),                 \
++                      __unsigned_add_overflow(a, b, d))
++
++#define check_sub_overflow(a, b, d)                                   \
++      __builtin_choose_expr(is_signed_type(typeof(a)),                \
++                      __signed_sub_overflow(a, b, d),                 \
++                      __unsigned_sub_overflow(a, b, d))
++
++#define check_mul_overflow(a, b, d)                                   \
++      __builtin_choose_expr(is_signed_type(typeof(a)),                \
++                      __signed_mul_overflow(a, b, d),                 \
++                      __unsigned_mul_overflow(a, b, d))
++
++
++#endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */
++
++/** check_shl_overflow() - Calculate a left-shifted value and check overflow
++ *
++ * @a: Value to be shifted
++ * @s: How many bits left to shift
++ * @d: Pointer to where to store the result
++ *
++ * Computes *@d = (@a << @s)
++ *
++ * Returns true if '*d' cannot hold the result or when 'a << s' doesn't
++ * make sense. Example conditions:
++ * - 'a << s' causes bits to be lost when stored in *d.
++ * - 's' is garbage (e.g. negative) or so large that the result of
++ *   'a << s' is guaranteed to be 0.
++ * - 'a' is negative.
++ * - 'a << s' sets the sign bit, if any, in '*d'.
++ *
++ * '*d' will hold the results of the attempted shift, but is not
++ * considered "safe for use" if false is returned.
++ */
++#define check_shl_overflow(a, s, d) ({                                        \
++      typeof(a) _a = a;                                               \
++      typeof(s) _s = s;                                               \
++      typeof(d) _d = d;                                               \
++      u64 _a_full = _a;                                               \
++      unsigned int _to_shift =                                        \
++              _s >= 0 && _s < 8 * sizeof(*d) ? _s : 0;                \
++      *_d = (_a_full << _to_shift);                                   \
++      (_to_shift != _s || *_d < 0 || _a < 0 ||                        \
++              (*_d >> _to_shift) != _a);                              \
++})
++
++/**
++ * array_size() - Calculate size of 2-dimensional array.
++ *
++ * @a: dimension one
++ * @b: dimension two
++ *
++ * Calculates size of 2-dimensional array: @a * @b.
++ *
++ * Returns: number of bytes needed to represent the array or SIZE_MAX on
++ * overflow.
++ */
++static inline __must_check size_t array_size(size_t a, size_t b)
++{
++      size_t bytes;
++
++      if (check_mul_overflow(a, b, &bytes))
++              return SIZE_MAX;
++
++      return bytes;
++}
++
++/**
++ * array3_size() - Calculate size of 3-dimensional array.
++ *
++ * @a: dimension one
++ * @b: dimension two
++ * @c: dimension three
++ *
++ * Calculates size of 3-dimensional array: @a * @b * @c.
++ *
++ * Returns: number of bytes needed to represent the array or SIZE_MAX on
++ * overflow.
++ */
++static inline __must_check size_t array3_size(size_t a, size_t b, size_t c)
++{
++      size_t bytes;
++
++      if (check_mul_overflow(a, b, &bytes))
++              return SIZE_MAX;
++      if (check_mul_overflow(bytes, c, &bytes))
++              return SIZE_MAX;
++
++      return bytes;
++}
++
++static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c)
++{
++      size_t bytes;
++
++      if (check_mul_overflow(n, size, &bytes))
++              return SIZE_MAX;
++      if (check_add_overflow(bytes, c, &bytes))
++              return SIZE_MAX;
++
++      return bytes;
++}
++
++/**
++ * struct_size() - Calculate size of structure with trailing array.
++ * @p: Pointer to the structure.
++ * @member: Name of the array member.
++ * @n: Number of elements in the array.
++ *
++ * Calculates size of memory needed for structure @p followed by an
++ * array of @n @member elements.
++ *
++ * Return: number of bytes needed or SIZE_MAX on overflow.
++ */
++#define struct_size(p, member, n)                                     \
++      __ab_c_size(n,                                                  \
++                  sizeof(*(p)->member) + __must_be_array((p)->member),\
++                  sizeof(*(p)))
++
++#endif /* __LINUX_OVERFLOW_H */