linux/include/asm-generic/bitops
Benjamin Marzinski 1c61b0a6e5 bitops: make the *_bit_le functions use unsigned long
The *_bit_le functions use a signed integer for the bit number.
However, the *_bit functions can use an unsigned long. This causes
problems if there is a large bitmap and a bit number > 0x80000000 is
passed in. Since that is a negative int, it will get sign extended to a
long when getting passed to the *_bit function, turning it into a huge
bit number. This usually ends up with the memory address wrapping around
and the function accessing memory before the start of the bitmap.

Avoid this by making the *_bit_le functions take an unsigned long.

This can be triggered by faking an almost 4TB dm-mirror device, which
uses bitmaps to track the mirror regions:

$ dmsetup create bigzero --table '0 8589934590 zero'
$ dmsetup create mymirror --table '0 8589934590 mirror core 2 2 nosync 2 /dev/mapper/bigzero 0 /dev/mapper/bigzero 0'

This will access memory before the start of the sync_bits bitmap, and
likely hit the guard page of the previously allocated clean_bits bitmap,
causing a kernel panic with the old code.

I looked and didn't see any crazy code using the signed int to
intentionally try and access bits before some address within the bitmap.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Yury Norov <ynorov@nvidia.com>
2026-07-22 15:38:37 -04:00
..
__bitrev.h
__ffs.h
__fls.h
arch_hweight.h
atomic.h
builtin-__ffs.h
builtin-__fls.h
builtin-ffs.h
builtin-fls.h
const_hweight.h
ext2-atomic-setbit.h
ext2-atomic.h
ffs.h
ffz.h
fls.h
fls64.h
generic-non-atomic.h
hweight.h
instrumented-atomic.h
instrumented-lock.h
instrumented-non-atomic.h
le.h
lock.h
non-atomic.h
non-instrumented-non-atomic.h
sched.h