[PATCH 1/2] x86/fpu: move copyout_from_xsaves bounds check before the copy

From: riel
Date: Wed Jan 25 2017 - 21:05:44 EST

From: Rik van Riel <riel@xxxxxxxxxx>

Userspace may have programs, especially debuggers, that do not know
how large the full XSAVE area space is. They pass in a size argument,
and expect to not get more data than that.

Unfortunately, the current copyout_from_xsaves does the bounds check
after the copy out to userspace. This could theoretically result
in the kernel scribbling over userspace memory outside of the buffer,
before bailing out of the copy.

In practice, this is not likely to be an issue, since debuggers are
likely to specify the size they know about, and that size is likely
to exactly match the XSAVE fields they know about.

However, we could be a little more careful and do the bounds check
before committing ourselves with a copy to userspace.

Signed-off-by: Rik van Riel <riel@xxxxxxxxxx>
arch/x86/kernel/fpu/xstate.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/fpu/xstate.c b/arch/x86/kernel/fpu/xstate.c
index c24ac1efb12d..c1508d56ecfb 100644
--- a/arch/x86/kernel/fpu/xstate.c
+++ b/arch/x86/kernel/fpu/xstate.c
@@ -992,13 +992,13 @@ int copyout_from_xsaves(unsigned int pos, unsigned int count, void *kbuf,
offset = xstate_offsets[i];
size = xstate_sizes[i];

+ if (offset + size > count)
+ break;
ret = xstate_copyout(offset, size, kbuf, ubuf, src, 0, count);

if (ret)
return ret;
- if (offset + size >= count)
- break;