From: Linus Torvalds torvalds@linux-foundation.org
[ Upstream commit ab9bb6318b0967671e0c9b6537c1537d51ca4f45 ]
Commit dfe2a77fd243 ("kfifo: fix kfifo_alloc() and kfifo_init()") made the kfifo code round the number of elements up. That was good for __kfifo_alloc(), but it's actually wrong for __kfifo_init().
The difference? __kfifo_alloc() will allocate the rounded-up number of elements, but __kfifo_init() uses an allocation done by the caller. We can't just say "use more elements than the caller allocated", and have to round down.
The good news? All the normal cases will be using power-of-two arrays anyway, and most users of kfifo's don't use kfifo_init() at all, but one of the helper macros to declare a KFIFO that enforce the proper power-of-two behavior. But it looks like at least ibmvscsis might be affected.
The bad news? Will Deacon refers to an old thread and points points out that the memory ordering in kfifo's is questionable. See
https://lore.kernel.org/lkml/20181211034032.32338-1-yuleixzhang@tencent.com/
for more.
Fixes: dfe2a77fd243 ("kfifo: fix kfifo_alloc() and kfifo_init()") Reported-by: laokz laokz@foxmail.com Cc: Stefani Seibold stefani@seibold.net Cc: Andrew Morton akpm@linux-foundation.org Cc: Dan Carpenter dan.carpenter@oracle.com Cc: Greg KH greg@kroah.com Cc: Kees Cook keescook@chromium.org Cc: Will Deacon will@kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/kfifo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/kfifo.c b/lib/kfifo.c index 90ba1eb1df06..a94227c55551 100644 --- a/lib/kfifo.c +++ b/lib/kfifo.c @@ -82,7 +82,8 @@ int __kfifo_init(struct __kfifo *fifo, void *buffer, { size /= esize;
- size = roundup_pow_of_two(size); + if (!is_power_of_2(size)) + size = rounddown_pow_of_two(size);
fifo->in = 0; fifo->out = 0;