From d8312e4e081078f04bac79ec3c4e76bc9b1c2365 Mon Sep 17 00:00:00 2001 From: chenqiuhao Date: Thu, 29 Feb 2024 13:34:29 +0800 Subject: [PATCH] Type conversion for align type promotion in P2ALIGN In P2ALIGN, the result would be incorrect when align is unsigned integer and x is larger than max value of the type of align. In that case, -(align) would be a positive integer, which means high bits would be zero and finally stay zero after '&' when align is converted to a larger integer type. Signed-off-by: Qiuhao Chen --- include/os/freebsd/spl/sys/ccompile.h | 3 ++- include/os/freebsd/spl/sys/sysmacros.h | 3 ++- include/os/linux/spl/sys/sysmacros.h | 3 ++- lib/libspl/include/os/linux/sys/sysmacros.h | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/os/freebsd/spl/sys/ccompile.h b/include/os/freebsd/spl/sys/ccompile.h index 26cf4db87aea..1617d026ff8f 100644 --- a/include/os/freebsd/spl/sys/ccompile.h +++ b/include/os/freebsd/spl/sys/ccompile.h @@ -138,7 +138,8 @@ typedef int enum_t; #define readdir64 readdir #define dirent64 dirent #endif -#define P2ALIGN(x, align) ((x) & -(align)) +#define P2ALIGN(x, align) \ + ((x) & -((sizeof (x) > sizeof (align))?(typeof(x))(align):(align))) #define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1) #define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1) #define P2PHASE(x, align) ((x) & ((align) - 1)) diff --git a/include/os/freebsd/spl/sys/sysmacros.h b/include/os/freebsd/spl/sys/sysmacros.h index 3e8841ae66bd..fdc9202563c6 100644 --- a/include/os/freebsd/spl/sys/sysmacros.h +++ b/include/os/freebsd/spl/sys/sysmacros.h @@ -191,7 +191,8 @@ extern unsigned char bcd_to_byte[256]; * eg, P2ALIGN(0x1234, 0x100) == 0x1200 (0x12*align) * eg, P2ALIGN(0x5600, 0x100) == 0x5600 (0x56*align) */ -#define P2ALIGN(x, align) ((x) & -(align)) +#define P2ALIGN(x, align) \ + ((x) & -((sizeof (x) > sizeof (align))?(typeof(x))(align):(align))) /* * return x % (mod) align diff --git a/include/os/linux/spl/sys/sysmacros.h b/include/os/linux/spl/sys/sysmacros.h index 99e3a6fb41c6..3e0049bcfc6c 100644 --- a/include/os/linux/spl/sys/sysmacros.h +++ b/include/os/linux/spl/sys/sysmacros.h @@ -159,7 +159,8 @@ makedev(unsigned int major, unsigned int minor) /* * Compatibility macros/typedefs needed for Solaris -> Linux port */ -#define P2ALIGN(x, align) ((x) & -(align)) +#define P2ALIGN(x, align) \ + ((x) & -((sizeof (x) > sizeof (align))?(typeof(x))(align):(align))) #define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1) #define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1) #define P2PHASE(x, align) ((x) & ((align) - 1)) diff --git a/lib/libspl/include/os/linux/sys/sysmacros.h b/lib/libspl/include/os/linux/sys/sysmacros.h index 5765ee25c6cb..a98b232d2bc7 100644 --- a/lib/libspl/include/os/linux/sys/sysmacros.h +++ b/lib/libspl/include/os/linux/sys/sysmacros.h @@ -52,7 +52,8 @@ /* * Compatibility macros/typedefs needed for Solaris -> Linux port */ -#define P2ALIGN(x, align) ((x) & -(align)) +#define P2ALIGN(x, align) \ + ((x) & -((sizeof (x) > sizeof (align))?(typeof(x))(align):(align))) #define P2CROSS(x, y, align) (((x) ^ (y)) > (align) - 1) #define P2ROUNDUP(x, align) ((((x) - 1) | ((align) - 1)) + 1) #define P2BOUNDARY(off, len, align) \