[PATCH] uapi: bitops: use UAPI-safe variant of BITS_PER_LONG again

Thomas Weißschuh posted 1 patch 6 months, 2 weeks ago
include/uapi/linux/bits.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] uapi: bitops: use UAPI-safe variant of BITS_PER_LONG again
Posted by Thomas Weißschuh 6 months, 2 weeks ago
Commit 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
did not take in account that the usage of BITS_PER_LONG in __GENMASK() was
changed to __BITS_PER_LONG for UAPI-safety in
commit 3c7a8e190bc5 ("uapi: introduce uapi-friendly macros for GENMASK").
BITS_PER_LONG can not be used in UAPI headers as it derives from the kernel
configuration and not from the current compiler invocation.
When building compat userspace code or a compat vDSO its value will be
incorrect.

Switch back to __BITS_PER_LONG.

Fixes: 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 include/uapi/linux/bits.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/bits.h b/include/uapi/linux/bits.h
index 682b406e10679dc8baa188830ab0811e7e3e13e3..a04afef9efca42f062e142fcb33f5d267512b1e5 100644
--- a/include/uapi/linux/bits.h
+++ b/include/uapi/linux/bits.h
@@ -4,9 +4,9 @@
 #ifndef _UAPI_LINUX_BITS_H
 #define _UAPI_LINUX_BITS_H
 
-#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (BITS_PER_LONG - 1 - (h))))
+#define __GENMASK(h, l) (((~_UL(0)) << (l)) & (~_UL(0) >> (__BITS_PER_LONG - 1 - (h))))
 
-#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
+#define __GENMASK_ULL(h, l) (((~_ULL(0)) << (l)) & (~_ULL(0) >> (__BITS_PER_LONG_LONG - 1 - (h))))
 
 #define __GENMASK_U128(h, l) \
 	((_BIT128((h)) << 1) - (_BIT128(l)))

---
base-commit: e271ed52b344ac02d4581286961d0c40acc54c03
change-id: 20250606-uapi-genmask-e07667de69ec

Best regards,
-- 
Thomas Weißschuh <thomas.weissschuh@linutronix.de>

Re: [PATCH] uapi: bitops: use UAPI-safe variant of BITS_PER_LONG again
Posted by Yury Norov 6 months, 2 weeks ago
On Fri, Jun 06, 2025 at 10:23:57AM +0200, Thomas Weißschuh wrote:
> Commit 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> did not take in account that the usage of BITS_PER_LONG in __GENMASK() was
> changed to __BITS_PER_LONG for UAPI-safety in
> commit 3c7a8e190bc5 ("uapi: introduce uapi-friendly macros for GENMASK").
> BITS_PER_LONG can not be used in UAPI headers as it derives from the kernel
> configuration and not from the current compiler invocation.
> When building compat userspace code or a compat vDSO its value will be
> incorrect.
> 
> Switch back to __BITS_PER_LONG.
> 
> Fixes: 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> Cc: stable@vger.kernel.org
> Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>

Thanks Thomas. I applied it in bitmap-for-next. Is that issue critical
enough for you to send a pull request in -rc2?

Thanks,
Yury
Re: [PATCH] uapi: bitops: use UAPI-safe variant of BITS_PER_LONG again
Posted by Thomas Weißschuh 6 months, 2 weeks ago
On Fri, Jun 06, 2025 at 10:20:56AM -0400, Yury Norov wrote:
> On Fri, Jun 06, 2025 at 10:23:57AM +0200, Thomas Weißschuh wrote:
> > Commit 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> > did not take in account that the usage of BITS_PER_LONG in __GENMASK() was
> > changed to __BITS_PER_LONG for UAPI-safety in
> > commit 3c7a8e190bc5 ("uapi: introduce uapi-friendly macros for GENMASK").
> > BITS_PER_LONG can not be used in UAPI headers as it derives from the kernel
> > configuration and not from the current compiler invocation.
> > When building compat userspace code or a compat vDSO its value will be
> > incorrect.
> > 
> > Switch back to __BITS_PER_LONG.
> > 
> > Fixes: 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> 
> Thanks Thomas. I applied it in bitmap-for-next. Is that issue critical
> enough for you to send a pull request in -rc2?

I have some patches that depend on it. These will probably end up in linux-next
soonish and would then break there.

So having it in -rc2 would be nice.


Thanks
Re: [PATCH] uapi: bitops: use UAPI-safe variant of BITS_PER_LONG again
Posted by I Hsin Cheng 6 months, 1 week ago
On Fri, Jun 06, 2025 at 04:32:22PM +0200, Thomas Weißschuh wrote:
> On Fri, Jun 06, 2025 at 10:20:56AM -0400, Yury Norov wrote:
> > On Fri, Jun 06, 2025 at 10:23:57AM +0200, Thomas Weißschuh wrote:
> > > Commit 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> > > did not take in account that the usage of BITS_PER_LONG in __GENMASK() was
> > > changed to __BITS_PER_LONG for UAPI-safety in
> > > commit 3c7a8e190bc5 ("uapi: introduce uapi-friendly macros for GENMASK").
> > > BITS_PER_LONG can not be used in UAPI headers as it derives from the kernel
> > > configuration and not from the current compiler invocation.
> > > When building compat userspace code or a compat vDSO its value will be
> > > incorrect.
> > > 
> > > Switch back to __BITS_PER_LONG.
> > > 
> > > Fixes: 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> > > Cc: stable@vger.kernel.org
> > > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > 
> > Thanks Thomas. I applied it in bitmap-for-next. Is that issue critical
> > enough for you to send a pull request in -rc2?
> 
> I have some patches that depend on it. These will probably end up in linux-next
> soonish and would then break there.
> 
> So having it in -rc2 would be nice.
> 
> 
> Thanks

Hi Thomas,

Thanks for pointing out the problem, may I ask in what config would
cause "BITS_PER_LONG" to work incorrectly ?

I would love to test the difference between them and see what I can get,
thanks.

Best regards,
I Hsin Cheng

Re: [PATCH] uapi: bitops: use UAPI-safe variant of BITS_PER_LONG again
Posted by Thomas Weißschuh 6 months, 1 week ago
Hi I Hsin Cheng,

On Mon, Jun 09, 2025 at 03:47:49PM +0800, I Hsin Cheng wrote:
> On Fri, Jun 06, 2025 at 04:32:22PM +0200, Thomas Weißschuh wrote:
> > On Fri, Jun 06, 2025 at 10:20:56AM -0400, Yury Norov wrote:
> > > On Fri, Jun 06, 2025 at 10:23:57AM +0200, Thomas Weißschuh wrote:
> > > > Commit 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> > > > did not take in account that the usage of BITS_PER_LONG in __GENMASK() was
> > > > changed to __BITS_PER_LONG for UAPI-safety in
> > > > commit 3c7a8e190bc5 ("uapi: introduce uapi-friendly macros for GENMASK").
> > > > BITS_PER_LONG can not be used in UAPI headers as it derives from the kernel
> > > > configuration and not from the current compiler invocation.
> > > > When building compat userspace code or a compat vDSO its value will be
> > > > incorrect.
> > > > 
> > > > Switch back to __BITS_PER_LONG.
> > > > 
> > > > Fixes: 1e7933a575ed ("uapi: Revert "bitops: avoid integer overflow in GENMASK(_ULL)"")
> > > > Cc: stable@vger.kernel.org
> > > > Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > > 
> > > Thanks Thomas. I applied it in bitmap-for-next. Is that issue critical
> > > enough for you to send a pull request in -rc2?
> > 
> > I have some patches that depend on it. These will probably end up in linux-next
> > soonish and would then break there.
> > 
> > So having it in -rc2 would be nice.
> 
> Thanks for pointing out the problem, may I ask in what config would
> cause "BITS_PER_LONG" to work incorrectly ?

In my specific usecase it was when building the powerpc compat vDSO.
For an easy reproducer use:

diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 93ef801a97ef..948619848a3b 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -16,6 +16,9 @@
 # define VDSO_DELTA_MASK(vd)   (vd->mask)
 #endif
 
+_Static_assert(__BITS_PER_LONG == sizeof(long) * 8);
+_Static_assert(BITS_PER_LONG == sizeof(long) * 8);
+
 #ifdef CONFIG_GENERIC_VDSO_OVERFLOW_PROTECT
 static __always_inline bool vdso_delta_ok(const struct vdso_clock *vc, u64 delta)
 {

> I would love to test the difference between them and see what I can get,
> thanks.

Looking at this again, the UAPI headers don't even define BITS_PER_LONG.
The vDSO just incorrectly ends up also using the regular kernel headers.


Thomas