Re: [Intel-gfx] [PATCH v2] overflow: Introduce overflows_type() and castable_to_type()

2022-09-28 Thread kernel test robot
Hi Kees,

I love your patch! Yet something to improve:

[auto build test ERROR on kees/for-next/hardening]
[also build test ERROR on next-20220928]
[cannot apply to drm-tip/drm-tip drm-intel/for-linux-next 
drm-misc/drm-misc-next linus/master v6.0-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:
https://github.com/intel-lab-lkp/linux/commits/Kees-Cook/overflow-Introduce-overflows_type-and-castable_to_type/20220927-094847
base:   https://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git 
for-next/hardening
config: i386-defconfig
compiler: gcc-11 (Debian 11.3.0-5) 11.3.0
reproduce (this is a W=1 build):
# 
https://github.com/intel-lab-lkp/linux/commit/ffc9129a19eb65b2d20780558b0c1af24d66434a
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Kees-Cook/overflow-Introduce-overflows_type-and-castable_to_type/20220927-094847
git checkout ffc9129a19eb65b2d20780558b0c1af24d66434a
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/i915/i915_utils.h:29,
from drivers/gpu/drm/i915/i915_user_extensions.c:14:
   drivers/gpu/drm/i915/i915_user_extensions.c: In function 
'i915_user_extensions':
>> include/linux/overflow.h:33:40: error: invalid operands to binary << (have 
>> 'struct i915_user_extension *' and 'unsigned int')
  33 | #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - 
is_signed_type(type)))
 |^~ 
~~~
 |   |
 |   
unsigned int
   include/linux/overflow.h:34:27: note: in expansion of macro '__type_half_max'
  34 | #define type_max(T) ((T)((__type_half_max(T) - 1) + 
__type_half_max(T)))
 |   ^~~
   include/linux/overflow.h:132:23: note: in expansion of macro 'type_max'
 132 | (x) > type_max(typeof(T)) ? 1 : 0   \
 |   ^~~~
   include/linux/overflow.h:159:31: note: in expansion of macro 
'__overflows_type_constexpr'
 159 |   __overflows_type_constexpr(n, T), \
 |   ^~
   drivers/gpu/drm/i915/i915_user_extensions.c:54:21: note: in expansion of 
macro 'overflows_type'
  54 | overflows_type(next, ext))
 | ^~
>> include/linux/overflow.h:33:40: error: invalid operands to binary << (have 
>> 'struct i915_user_extension *' and 'unsigned int')
  33 | #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - 
is_signed_type(type)))
 |^~ 
~~~
 |   |
 |   
unsigned int
   include/linux/overflow.h:34:53: note: in expansion of macro '__type_half_max'
  34 | #define type_max(T) ((T)((__type_half_max(T) - 1) + 
__type_half_max(T)))
 | ^~~
   include/linux/overflow.h:132:23: note: in expansion of macro 'type_max'
 132 | (x) > type_max(typeof(T)) ? 1 : 0   \
 |   ^~~~
   include/linux/overflow.h:159:31: note: in expansion of macro 
'__overflows_type_constexpr'
 159 |   __overflows_type_constexpr(n, T), \
 |   ^~
   drivers/gpu/drm/i915/i915_user_extensions.c:54:21: note: in expansion of 
macro 'overflows_type'
  54 | overflows_type(next, ext))
 | ^~
>> include/linux/overflow.h:33:40: error: invalid operands to binary << (have 
>> 'struct i915_user_extension *' and 'unsigned int')
  33 | #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - 
is_signed_type(type)))
 |^~ 
~~~
 |   |
 |   
unsigned int
   include/linux/overflow.h:34:27: note: in expansion of macro '__type_half_max'
  34 | #define type_max(T) ((T)((__type_half_max(T) 

Re: [Intel-gfx] [PATCH v2] overflow: Introduce overflows_type() and castable_to_type()

2022-09-28 Thread Gwan-gyeong Mun

Hi Kees,

To check the intel-gfx ci results and test results from other mailing 
lists, I have rebased this patch and included it in this series [1].


[1] https://patchwork.freedesktop.org/series/109169/

G.G

On 9/26/22 10:11 PM, Kees Cook wrote:

Implement a robust overflows_type() macro to test if a variable or
constant value would overflow another variable or type. This can be
used as a constant expression for static_assert() (which requires a
constant expression[1][2]) when used on constant values. This must be
constructed manually, since __builtin_add_overflow() does not produce
a constant expression[3].

Additionally adds castable_to_type(), similar to __same_type(), but for
checking if a constant value would overflow if cast to a given type.

Add unit tests for overflows_type(), __same_type(), and castable_to_type()
to the existing KUnit "overflow" test.

[1] https://en.cppreference.com/w/c/language/_Static_assert
[2] C11 standard (ISO/IEC 9899:2011): 6.7.10 Static assertions
[3] https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
 6.56 Built-in Functions to Perform Arithmetic with Overflow Checking
 Built-in Function: bool __builtin_add_overflow (type1 a, type2 b,

Cc: Luc Van Oostenryck 
Cc: Nathan Chancellor 
Cc: Nick Desaulniers 
Cc: Tom Rix 
Cc: Daniel Latypov 
Cc: Vitor Massaru Iha 
Cc: "Gustavo A. R. Silva" 
Cc: linux-harden...@vger.kernel.org
Cc: l...@lists.linux.dev
Co-developed-by: Gwan-gyeong Mun 
Signed-off-by: Gwan-gyeong Mun 
Signed-off-by: Kees Cook 
---
v2:
  - fix comment typo
  - wrap clang pragma to avoid GCC warnings
  - style nit cleanups
  - rename __castable_to_type() to castable_to_type()
  - remove prior overflows_type() definition
v1: https://lore.kernel.org/lkml/20220926003743.409911-1-keesc...@chromium.org
---
  drivers/gpu/drm/i915/i915_utils.h |   4 -
  include/linux/compiler.h  |   1 +
  include/linux/overflow.h  |  48 
  lib/overflow_kunit.c  | 388 +-
  4 files changed, 436 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index c10d68cdc3ca..d14b7faee054 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -111,10 +111,6 @@ bool i915_error_injected(void);
  #define range_overflows_end_t(type, start, size, max) \
range_overflows_end((type)(start), (type)(size), (type)(max))
  
-/* Note we don't consider signbits :| */

-#define overflows_type(x, T) \
-   (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T))
-
  #define ptr_mask_bits(ptr, n) ({  \
unsigned long __v = (unsigned long)(ptr);   \
(typeof(ptr))(__v & -BIT(n));   \
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 7713d7bcdaea..c631107e93b1 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -244,6 +244,7 @@ static inline void *offset_to_ptr(const int *off)
   * bool and also pointer types.
   */
  #define is_signed_type(type) (((type)(-1)) < (__force type)1)
+#define is_unsigned_type(type) (!is_signed_type(type))
  
  /*

   * This is needed in functions which generate the stack canary, see
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 19dfdd74835e..58eb34aa2af9 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -127,6 +127,54 @@ static inline bool __must_check __must_check_overflow(bool 
overflow)
(*_d >> _to_shift) != _a);\
  }))
  
+#define __overflows_type_constexpr(x, T) (			\

+   is_unsigned_type(typeof(x)) ?   \
+   (x) > type_max(typeof(T)) ? 1 : 0\
+   : is_unsigned_type(typeof(T)) ? \
+   (x) < 0 || (x) > type_max(typeof(T)) ? 1 : 0  \
+   : (x) < type_min(typeof(T)) ||   \
+ (x) > type_max(typeof(T)) ? 1 : 0)
+
+#define __overflows_type(x, T) ({  \
+   typeof(T) v = 0;\
+   check_add_overflow((x), v, ); \
+})
+
+/**
+ * overflows_type - helper for checking the overflows between value, variables,
+ * or data type
+ *
+ * @n: source constant value or variable to be checked
+ * @T: destination variable or data type proposed to store @x
+ *
+ * Compares the @x expression for whether or not it can safely fit in
+ * the storage of the type in @T. @x and @T can have different types.
+ * If @x is a constant expression, this will also resolve to a constant
+ * expression.
+ *
+ * Returns: true if overflow can occur, false otherwise.
+ */
+#define overflows_type(n, T)   \
+   __builtin_choose_expr(__is_constexpr(n),\
+ __overflows_type_constexpr(n, T), \
+ 

Re: [Intel-gfx] [PATCH v2] overflow: Introduce overflows_type() and castable_to_type()

2022-09-27 Thread Gwan-gyeong Mun

Hi Kees,
Thanks for update it to v2.
I'm leaving a comment because the patches this patch depends on aren't 
part of one of the series.
If this patch alone is forwarded to the intel-gfx mailing, it will 
report a build issue.

If this patch is only for review, please ignore my comments.

In order to remove overflows_type() from the i915 gpu driver and add the 
updated overflows_type() to overflows.h, the following two patches must 
be applied first because of dependencies.


"overflow: Allow mixed type arguments" [1][2]
"overflow: Introduce check_assign() and check_assign_user_ptr()" [2]

https://www.spinics.net/lists/kernel/msg4495457.html [1]
https://patchwork.freedesktop.org/patch/504792/?series=109063=1 [2]
https://patchwork.freedesktop.org/patch/504791/?series=109063=1 [3]

br,
G.G

On 9/26/22 10:11 PM, Kees Cook wrote:

Implement a robust overflows_type() macro to test if a variable or
constant value would overflow another variable or type. This can be
used as a constant expression for static_assert() (which requires a
constant expression[1][2]) when used on constant values. This must be
constructed manually, since __builtin_add_overflow() does not produce
a constant expression[3].

Additionally adds castable_to_type(), similar to __same_type(), but for
checking if a constant value would overflow if cast to a given type.

Add unit tests for overflows_type(), __same_type(), and castable_to_type()
to the existing KUnit "overflow" test.

[1] https://en.cppreference.com/w/c/language/_Static_assert
[2] C11 standard (ISO/IEC 9899:2011): 6.7.10 Static assertions
[3] https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
 6.56 Built-in Functions to Perform Arithmetic with Overflow Checking
 Built-in Function: bool __builtin_add_overflow (type1 a, type2 b,

Cc: Luc Van Oostenryck 
Cc: Nathan Chancellor 
Cc: Nick Desaulniers 
Cc: Tom Rix 
Cc: Daniel Latypov 
Cc: Vitor Massaru Iha 
Cc: "Gustavo A. R. Silva" 
Cc: linux-harden...@vger.kernel.org
Cc: l...@lists.linux.dev
Co-developed-by: Gwan-gyeong Mun 
Signed-off-by: Gwan-gyeong Mun 
Signed-off-by: Kees Cook 
---
v2:
  - fix comment typo
  - wrap clang pragma to avoid GCC warnings
  - style nit cleanups
  - rename __castable_to_type() to castable_to_type()
  - remove prior overflows_type() definition
v1: https://lore.kernel.org/lkml/20220926003743.409911-1-keesc...@chromium.org
---
  drivers/gpu/drm/i915/i915_utils.h |   4 -
  include/linux/compiler.h  |   1 +
  include/linux/overflow.h  |  48 
  lib/overflow_kunit.c  | 388 +-
  4 files changed, 436 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index c10d68cdc3ca..d14b7faee054 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -111,10 +111,6 @@ bool i915_error_injected(void);
  #define range_overflows_end_t(type, start, size, max) \
range_overflows_end((type)(start), (type)(size), (type)(max))
  
-/* Note we don't consider signbits :| */

-#define overflows_type(x, T) \
-   (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T))
-
  #define ptr_mask_bits(ptr, n) ({  \
unsigned long __v = (unsigned long)(ptr);   \
(typeof(ptr))(__v & -BIT(n));   \
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 7713d7bcdaea..c631107e93b1 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -244,6 +244,7 @@ static inline void *offset_to_ptr(const int *off)
   * bool and also pointer types.
   */
  #define is_signed_type(type) (((type)(-1)) < (__force type)1)
+#define is_unsigned_type(type) (!is_signed_type(type))
  
  /*

   * This is needed in functions which generate the stack canary, see
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 19dfdd74835e..58eb34aa2af9 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -127,6 +127,54 @@ static inline bool __must_check __must_check_overflow(bool 
overflow)
(*_d >> _to_shift) != _a);\
  }))
  
+#define __overflows_type_constexpr(x, T) (			\

+   is_unsigned_type(typeof(x)) ?   \
+   (x) > type_max(typeof(T)) ? 1 : 0\
+   : is_unsigned_type(typeof(T)) ? \
+   (x) < 0 || (x) > type_max(typeof(T)) ? 1 : 0  \
+   : (x) < type_min(typeof(T)) ||   \
+ (x) > type_max(typeof(T)) ? 1 : 0)
+
+#define __overflows_type(x, T) ({  \
+   typeof(T) v = 0;\
+   check_add_overflow((x), v, ); \
+})
+
+/**
+ * overflows_type - helper for checking the overflows between value, variables,
+ * or data type
+ *
+ * @n: source constant value or variable to be checked
+ * 

Re: [Intel-gfx] [PATCH v2] overflow: Introduce overflows_type() and castable_to_type()

2022-09-27 Thread Arnd Bergmann
On Mon, Sep 26, 2022, at 11:07 PM, Kees Cook wrote:
> On Mon, Sep 26, 2022 at 01:17:18PM -0700, Nick Desaulniers wrote:
>> + Arnd
>> 
>> On Mon, Sep 26, 2022 at 12:11 PM Kees Cook  wrote:
>> > ---
>> > v2:
>> >  - fix comment typo
>> >  - wrap clang pragma to avoid GCC warnings
>> >  - style nit cleanups
>> >  - rename __castable_to_type() to castable_to_type()
>> >  - remove prior overflows_type() definition
>> > v1: 
>> > https://lore.kernel.org/lkml/20220926003743.409911-1-keesc...@chromium.org
>> > diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c
>> > index f385ca652b74..fffc3f86181d 100644
>> > --- a/lib/overflow_kunit.c
>> > +++ b/lib/overflow_kunit.c
>> > @@ -16,6 +16,11 @@
>> >  #include 
>> >  #include 
>> >
>> > +/* We're expecting to do a lot of "always true" or "always false" tests. 
>> > */
>> > +#ifdef CONFIG_CC_IS_CLANG
>> > +#pragma clang diagnostic ignored 
>> > "-Wtautological-constant-out-of-range-compare"
>> > +#endif
>> 
>> Any chance we can reuse parts of __diag_ignore or __diag_clang from
>> include/linux/compiler_types.h or include/linux/compiler-clang.h
>> respectively?
>
> Hm, I'm not sure how those are supposed to be used. Those defines don't
> seem to be used externally?

We use them in a couple of places. When I originally introduced
them, the idea was to add more infrastructure around these
to replace the various -Wno-... flags in local makefiles with
more targetted annotations, and then have a way to control
the warning levels (W=1 W=2 E=1 etc) per directory and per file,
but I never completed the work to add the interesting bits.

>> Those are needed for pragmas within preprocessor macros, which we
>> don't have here, but I suspect they may be more concise to use here.
>
> Yeah, I was surprised when I had to wrap it in #ifdef given "clang" is
> part of the string.
>
>> 
>> > +#define TEST_SAME_TYPE(t1, t2, same)   do {\
>> > +   typeof(t1) __t1h = type_max(t1);\
>> > +   typeof(t1) __t1l = type_min(t1);\
>> > +   typeof(t2) __t2h = type_max(t2);\
>> > +   typeof(t2) __t2l = type_min(t2);\
>> 
>> Can we use __auto_type here rather than typeof(macro expansion)?
>
> I'd rather it stay explicit -- otherwise we start to wander into "oops,
> we got lucky" territory for what should be a really distinct test case.

The idea  of __auto_type is to avoid the more deeply nested macros.
If the preprocessed file turns into an absolute mess, adding a temporary
variable may help. Not sure if that applies here.

 Arnd


Re: [Intel-gfx] [PATCH v2] overflow: Introduce overflows_type() and castable_to_type()

2022-09-26 Thread Kees Cook
On Mon, Sep 26, 2022 at 01:17:18PM -0700, Nick Desaulniers wrote:
> + Arnd
> 
> On Mon, Sep 26, 2022 at 12:11 PM Kees Cook  wrote:
> > ---
> > v2:
> >  - fix comment typo
> >  - wrap clang pragma to avoid GCC warnings
> >  - style nit cleanups
> >  - rename __castable_to_type() to castable_to_type()
> >  - remove prior overflows_type() definition
> > v1: 
> > https://lore.kernel.org/lkml/20220926003743.409911-1-keesc...@chromium.org
> > diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c
> > index f385ca652b74..fffc3f86181d 100644
> > --- a/lib/overflow_kunit.c
> > +++ b/lib/overflow_kunit.c
> > @@ -16,6 +16,11 @@
> >  #include 
> >  #include 
> >
> > +/* We're expecting to do a lot of "always true" or "always false" tests. */
> > +#ifdef CONFIG_CC_IS_CLANG
> > +#pragma clang diagnostic ignored 
> > "-Wtautological-constant-out-of-range-compare"
> > +#endif
> 
> Any chance we can reuse parts of __diag_ignore or __diag_clang from
> include/linux/compiler_types.h or include/linux/compiler-clang.h
> respectively?

Hm, I'm not sure how those are supposed to be used. Those defines don't
seem to be used externally?

> Those are needed for pragmas within preprocessor macros, which we
> don't have here, but I suspect they may be more concise to use here.

Yeah, I was surprised when I had to wrap it in #ifdef given "clang" is
part of the string.

> 
> > +#define TEST_SAME_TYPE(t1, t2, same)   do {\
> > +   typeof(t1) __t1h = type_max(t1);\
> > +   typeof(t1) __t1l = type_min(t1);\
> > +   typeof(t2) __t2h = type_max(t2);\
> > +   typeof(t2) __t2l = type_min(t2);\
> 
> Can we use __auto_type here rather than typeof(macro expansion)?

I'd rather it stay explicit -- otherwise we start to wander into "oops,
we got lucky" territory for what should be a really distinct test case.

-- 
Kees Cook


Re: [Intel-gfx] [PATCH v2] overflow: Introduce overflows_type() and castable_to_type()

2022-09-26 Thread Nick Desaulniers
+ Arnd

On Mon, Sep 26, 2022 at 12:11 PM Kees Cook  wrote:
> ---
> v2:
>  - fix comment typo
>  - wrap clang pragma to avoid GCC warnings
>  - style nit cleanups
>  - rename __castable_to_type() to castable_to_type()
>  - remove prior overflows_type() definition
> v1: https://lore.kernel.org/lkml/20220926003743.409911-1-keesc...@chromium.org
> diff --git a/lib/overflow_kunit.c b/lib/overflow_kunit.c
> index f385ca652b74..fffc3f86181d 100644
> --- a/lib/overflow_kunit.c
> +++ b/lib/overflow_kunit.c
> @@ -16,6 +16,11 @@
>  #include 
>  #include 
>
> +/* We're expecting to do a lot of "always true" or "always false" tests. */
> +#ifdef CONFIG_CC_IS_CLANG
> +#pragma clang diagnostic ignored 
> "-Wtautological-constant-out-of-range-compare"
> +#endif

Any chance we can reuse parts of __diag_ignore or __diag_clang from
include/linux/compiler_types.h or include/linux/compiler-clang.h
respectively?

Those are needed for pragmas within preprocessor macros, which we
don't have here, but I suspect they may be more concise to use here.

> +#define TEST_SAME_TYPE(t1, t2, same)   do {\
> +   typeof(t1) __t1h = type_max(t1);\
> +   typeof(t1) __t1l = type_min(t1);\
> +   typeof(t2) __t2h = type_max(t2);\
> +   typeof(t2) __t2l = type_min(t2);\

Can we use __auto_type here rather than typeof(macro expansion)?
-- 
Thanks,
~Nick Desaulniers


[Intel-gfx] [PATCH v2] overflow: Introduce overflows_type() and castable_to_type()

2022-09-26 Thread Kees Cook
Implement a robust overflows_type() macro to test if a variable or
constant value would overflow another variable or type. This can be
used as a constant expression for static_assert() (which requires a
constant expression[1][2]) when used on constant values. This must be
constructed manually, since __builtin_add_overflow() does not produce
a constant expression[3].

Additionally adds castable_to_type(), similar to __same_type(), but for
checking if a constant value would overflow if cast to a given type.

Add unit tests for overflows_type(), __same_type(), and castable_to_type()
to the existing KUnit "overflow" test.

[1] https://en.cppreference.com/w/c/language/_Static_assert
[2] C11 standard (ISO/IEC 9899:2011): 6.7.10 Static assertions
[3] https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
6.56 Built-in Functions to Perform Arithmetic with Overflow Checking
Built-in Function: bool __builtin_add_overflow (type1 a, type2 b,

Cc: Luc Van Oostenryck 
Cc: Nathan Chancellor 
Cc: Nick Desaulniers 
Cc: Tom Rix 
Cc: Daniel Latypov 
Cc: Vitor Massaru Iha 
Cc: "Gustavo A. R. Silva" 
Cc: linux-harden...@vger.kernel.org
Cc: l...@lists.linux.dev
Co-developed-by: Gwan-gyeong Mun 
Signed-off-by: Gwan-gyeong Mun 
Signed-off-by: Kees Cook 
---
v2:
 - fix comment typo
 - wrap clang pragma to avoid GCC warnings
 - style nit cleanups
 - rename __castable_to_type() to castable_to_type()
 - remove prior overflows_type() definition
v1: https://lore.kernel.org/lkml/20220926003743.409911-1-keesc...@chromium.org
---
 drivers/gpu/drm/i915/i915_utils.h |   4 -
 include/linux/compiler.h  |   1 +
 include/linux/overflow.h  |  48 
 lib/overflow_kunit.c  | 388 +-
 4 files changed, 436 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_utils.h 
b/drivers/gpu/drm/i915/i915_utils.h
index c10d68cdc3ca..d14b7faee054 100644
--- a/drivers/gpu/drm/i915/i915_utils.h
+++ b/drivers/gpu/drm/i915/i915_utils.h
@@ -111,10 +111,6 @@ bool i915_error_injected(void);
 #define range_overflows_end_t(type, start, size, max) \
range_overflows_end((type)(start), (type)(size), (type)(max))
 
-/* Note we don't consider signbits :| */
-#define overflows_type(x, T) \
-   (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T))
-
 #define ptr_mask_bits(ptr, n) ({   \
unsigned long __v = (unsigned long)(ptr);   \
(typeof(ptr))(__v & -BIT(n));   \
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 7713d7bcdaea..c631107e93b1 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -244,6 +244,7 @@ static inline void *offset_to_ptr(const int *off)
  * bool and also pointer types.
  */
 #define is_signed_type(type) (((type)(-1)) < (__force type)1)
+#define is_unsigned_type(type) (!is_signed_type(type))
 
 /*
  * This is needed in functions which generate the stack canary, see
diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index 19dfdd74835e..58eb34aa2af9 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -127,6 +127,54 @@ static inline bool __must_check __must_check_overflow(bool 
overflow)
(*_d >> _to_shift) != _a);  \
 }))
 
+#define __overflows_type_constexpr(x, T) ( \
+   is_unsigned_type(typeof(x)) ?   \
+   (x) > type_max(typeof(T)) ? 1 : 0   \
+   : is_unsigned_type(typeof(T)) ? \
+   (x) < 0 || (x) > type_max(typeof(T)) ? 1 : 0\
+   : (x) < type_min(typeof(T)) ||  \
+ (x) > type_max(typeof(T)) ? 1 : 0)
+
+#define __overflows_type(x, T) ({  \
+   typeof(T) v = 0;\
+   check_add_overflow((x), v, ); \
+})
+
+/**
+ * overflows_type - helper for checking the overflows between value, variables,
+ * or data type
+ *
+ * @n: source constant value or variable to be checked
+ * @T: destination variable or data type proposed to store @x
+ *
+ * Compares the @x expression for whether or not it can safely fit in
+ * the storage of the type in @T. @x and @T can have different types.
+ * If @x is a constant expression, this will also resolve to a constant
+ * expression.
+ *
+ * Returns: true if overflow can occur, false otherwise.
+ */
+#define overflows_type(n, T)   \
+   __builtin_choose_expr(__is_constexpr(n),\
+ __overflows_type_constexpr(n, T), \
+ __overflows_type(n, T))
+
+/**
+ * castable_to_type - like __same_type(), but also allows for casted literals
+ *
+ * @n: variable or constant value
+ * @T: variable or data type
+ *
+ * Unlike the __same_type() macro, this allows a constant value as the
+ * first