]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
padata: use integer wrap around to prevent deadlock on seq_nr overflow
authorVanGiang Nguyen <vangiang.nguyen@rohde-schwarz.com>
Fri, 9 Aug 2024 06:21:42 +0000 (06:21 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Oct 2024 13:08:03 +0000 (15:08 +0200)
commit 9a22b2812393d93d84358a760c347c21939029a6 upstream.

When submitting more than 2^32 padata objects to padata_do_serial, the
current sorting implementation incorrectly sorts padata objects with
overflowed seq_nr, causing them to be placed before existing objects in
the reorder list. This leads to a deadlock in the serialization process
as padata_find_next cannot match padata->seq_nr and pd->processed
because the padata instance with overflowed seq_nr will be selected
next.

To fix this, we use an unsigned integer wrap around to correctly sort
padata objects in scenarios with integer overflow.

Fixes: bfde23ce200e ("padata: unbind parallel jobs from specific CPUs")
Cc: <stable@vger.kernel.org>
Co-developed-by: Christian Gafert <christian.gafert@rohde-schwarz.com>
Signed-off-by: Christian Gafert <christian.gafert@rohde-schwarz.com>
Co-developed-by: Max Ferger <max.ferger@rohde-schwarz.com>
Signed-off-by: Max Ferger <max.ferger@rohde-schwarz.com>
Signed-off-by: Van Giang Nguyen <vangiang.nguyen@rohde-schwarz.com>
Acked-by: Daniel Jordan <daniel.m.jordan@oracle.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/padata.c

index 41d5bf2fa2ad99449f93fefd989531c53f350e39..914a88d9cee145ec7365fd4de457b5744f184c01 100644 (file)
@@ -409,7 +409,8 @@ void padata_do_serial(struct padata_priv *padata)
        /* Sort in ascending order of sequence number. */
        list_for_each_prev(pos, &reorder->list) {
                cur = list_entry(pos, struct padata_priv, list);
-               if (cur->seq_nr < padata->seq_nr)
+               /* Compare by difference to consider integer wrap around */
+               if ((signed int)(cur->seq_nr - padata->seq_nr) < 0)
                        break;
        }
        list_add(&padata->list, pos);