Re: [PATCH 05/10] x86/fpu: Fix potential underflow in xstate_calculate_size()
Alexander Mikhalitsyn <[email protected]> Fri, 26 Jun 2026 16:32:31 +0200
| Newsgroups | dev.linux.lists.criu,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CAJqdLrrLmg1ROanhzR9F_PcGixvR_9WL8xzF98vh+dT7vr5xHw@mail.gmail.com> |
Am Mo., 15. Juni 2026 um 21:39 Uhr schrieb Andrei Vagin <[email protected]>: > > xstate_calculate_size() calculates the size required for a given set of > xfeatures. It determines the topmost feature by finding the most > significant bit in xfeatures using fls64(xfeatures) - 1. > > If xfeatures is 0, fls64(0) returns 0, and topmost becomes -1. > Previously, topmost was unsigned int, so -1 underflowed to UINT_MAX. > This caused the subsequent check `topmost <= XFEATURE_SSE` to fail, and > the code proceeded to access xstate arrays using topmost (UINT_MAX) as > an index, leading to an out-of-bounds access. > > Fix this by checking if xfeatures only contains legacy features (FP/SSE) > or is empty (xfeatures <= XFEATURE_MASK_FPSSE) before calculating > topmost. > > Fixes: d6d6d50f1e80 ("x86/fpu/xstate: Consolidate size calculations") > Signed-off-by: Andrei Vagin <[email protected]> Reviewed-by: Alexander Mikhalitsyn <[email protected]> > --- > arch/x86/kernel/fpu/xstate.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c > index a7b6524a9dea..ed39d7051d0d 100644 > --- a/arch/x86/kernel/fpu/xstate.c > +++ b/arch/x86/kernel/fpu/xstate.c > @@ -589,12 +589,13 @@ static bool __init check_xstate_against_struct(int nr) > > static unsigned int xstate_calculate_size(u64 xfeatures, bool compacted) > { > - unsigned int topmost = fls64(xfeatures) - 1; > - unsigned int offset, i; > + unsigned int topmost, offset, i; > > - if (topmost <= XFEATURE_SSE) > + if (xfeatures <= XFEATURE_MASK_FPSSE) > return sizeof(struct xregs_state); > > + topmost = fls64(xfeatures) - 1; > + > if (compacted) { > offset = xfeature_get_offset(xfeatures, topmost); > } else { > -- > 2.54.0.1189.g8c84645362-goog > >