linux/drivers/block
Alejandro Colomar 436debc9ca array_size.h: add ARRAY_END()
Patch series "Add ARRAY_END(), and use it to fix off-by-one bugs", v6.

Add ARRAY_END(), and use it to fix off-by-one bugs

ARRAY_END() is a macro to calculate a pointer to one past the last element
of an array argument.  This is a very common pointer, which is used to
iterate over all elements of an array:

        for (T *p = a; p < ARRAY_END(a); p++)
                ...

Of course, this pointer should never be dereferenced.  A pointer one past
the last element of an array should not be dereferenced; it's perfectly
fine to hold such a pointer --and a good thing to do--, but the only thing
it should be used for is comparing it with other pointers derived from the
same array.

Due to how special these pointers are, it would be good to use consistent
naming.  It's common to name such a pointer 'end' --in fact, we have many
such cases in the kernel--.  C++ even standardized this name with
std::end().  Let's try naming such pointers 'end', and try also avoid
using 'end' for pointers that are not the result of ARRAY_END().

It has been incorrectly suggested that these pointers are dangerous, and
that they should never be used, suggesting to use something like

	#define ARRAY_LAST(a)  ((a) + ARRAY_SIZE(a) - 1)

	for (T *p = a; p <= ARRAY_LAST(a); p++)
		...

This is bogus, as it doesn't scale down to arrays of 0 elements.  In the
case of an array of 0 elements, ARRAY_LAST() would underflow the pointer,
which not only it can't be dereferenced, it can't even be held (it
produces Undefined Behavior).  That would be a footgun.  Such arrays don't
exist per the ISO C standard; however, GCC supports them as an extension
(with partial support, though; GCC has a few bugs which need to be fixed).

This patch set fixes a few places where it was intended to use the array
end (that is, one past the last element), but accidentally a pointer to
the last element was used instead, thus wasting one byte.

It also replaces other places where the array end was correctly calculated
with ARRAY_SIZE(), by using the simpler ARRAY_END().

Also, there was one drivers/ file that already defined this macro.  We
remove that definition, to not conflict with this one.


This patch (of 4):

ARRAY_END() returns a pointer one past the end of the last element in the
array argument.  This pointer is useful for iterating over the elements of
an array:

	for (T *p = a, p < ARRAY_END(a); p++)
		...

Link: https://lkml.kernel.org/r/cover.1765449750.git.alx@kernel.org
Link: https://lkml.kernel.org/r/5973cfb674192bc8e533485dbfb54e3062896be1.1765449750.git.alx@kernel.org
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Christopher Bazley <chris.bazley.wg14@gmail.com>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Marco Elver <elver@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Alexander Potapenko <glider@google.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-01-20 19:44:19 -08:00
..
aoe Summary of significant series in this pull request: 2025-10-02 18:18:33 -07:00
drbd for-6.19/block-20251201 2025-12-03 19:26:18 -08:00
mtip32xx block: switch ->getgeo() to struct gendisk 2025-08-13 02:59:29 -04:00
null_blk null_blk: fix kmemleak by releasing references to fault configfs items 2026-01-13 07:24:37 -07:00
rnbd rnbd-clt: fix refcount underflow in device unmap path 2026-01-15 07:22:09 -07:00
rnull for-6.19/block-20251201 2025-12-03 19:26:18 -08:00
xen-blkback xen/blkback: convert timeouts to secs_to_jiffies() 2025-01-12 20:21:03 -08:00
zram zram: fix a spelling mistake 2025-11-29 10:41:08 -08:00
amiflop.c block: switch ->getgeo() to struct gendisk 2025-08-13 02:59:29 -04:00
ataflop.c treewide: Switch/rename to timer_delete[_sync]() 2025-04-05 10:30:12 +02:00
brd.c brd: use page reference to protect page lifetime 2025-09-01 08:37:29 -06:00
floppy.c array_size.h: add ARRAY_END() 2026-01-20 19:44:19 -08:00
Kconfig rbd: stop selecting CRC32, CRYPTO, and CRYPTO_AES 2025-12-10 11:50:54 +01:00
loop.c loop: add missing bd_abort_claiming in loop_set_status 2026-01-07 08:04:42 -07:00
Makefile rnull: move driver to separate directory 2025-09-02 05:23:56 -06:00
n64cart.c block: move the nonrot flag to queue_limits 2024-06-19 07:58:28 -06:00
nbd.c for-6.19/block-20251201 2025-12-03 19:26:18 -08:00
ps3disk.c ps3disk: use memcpy_{from,to}_bvec index 2025-11-14 09:10:16 -07:00
ps3vram.c block: pass a queue_limits argument to blk_alloc_disk 2024-02-19 16:58:23 -07:00
rbd.c drivers/block: WQ_PERCPU added to alloc_workqueue users 2025-09-09 09:11:31 -06:00
rbd_types.h libceph, rbd: replace zero-length array with flexible-array 2020-06-01 13:22:53 +02:00
sunvdc.c drivers/block: WQ_PERCPU added to alloc_workqueue users 2025-09-09 09:11:31 -06:00
swim.c block: switch ->getgeo() to struct gendisk 2025-08-13 02:59:29 -04:00
swim3.c treewide, timers: Rename from_timer() to timer_container_of() 2025-06-08 09:07:37 +02:00
swim_asm.S treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
ublk_drv.c ublk: fix use-after-free in ublk_partition_scan_work 2026-01-09 06:55:30 -07:00
virtio_blk.c virtio_blk: NULL out vqs to avoid double free on failed resume 2025-11-06 16:32:58 -07:00
xen-blkfront.c block: switch ->getgeo() to struct gendisk 2025-08-13 02:59:29 -04:00
z2ram.c block: remove BLK_MQ_F_SHOULD_MERGE 2024-12-23 08:17:23 -07:00
zloop.c zloop: use READ_ONCE() to read lo->lo_state in queue_rq path 2025-12-15 09:32:42 -07:00