| From 9a22b2812393d93d84358a760c347c21939029a6 Mon Sep 17 00:00:00 2001 |
| From: VanGiang Nguyen <vangiang.nguyen@rohde-schwarz.com> |
| Date: Fri, 9 Aug 2024 06:21:42 +0000 |
| Subject: padata: use integer wrap around to prevent deadlock on seq_nr overflow |
| |
| From: VanGiang Nguyen <vangiang.nguyen@rohde-schwarz.com> |
| |
| 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 | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/kernel/padata.c |
| +++ b/kernel/padata.c |
| @@ -404,7 +404,8 @@ void padata_do_serial(struct padata_priv |
| /* 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); |