[PATCH 0/2] MIPS: memset.S: Fix 2 issues with __clear_user

From: Matt Redfearn
Date: Thu Mar 29 2018 - 08:23:59 EST


This series addresses 2 issues that have been present in memset.S since
the initial git import(!).
The first patch addresses an issue when memset is called with a size
less than the size of a long (4 bytes on 32bit, 8 bytes on 64bit). There
is no fixup handler provided for the byte store loop, meaning that if
the access triggers a page fault, rather than being fixup up, the kernel
OOPS'. A secondary issue is also addressed here, that when EVA support
was added by commit fd9720e96e85 ("MIPS: lib: memset: Add EVA support
for the __bzero function."), this small memset was not changed. Hence
kernel mode addressing is always used and if the userspace address being
stored to overlaps kernel, then some potentially critical kernel data is
overwritten.

The second patch addresses an issue found while debugging the first.
clear_user() is specified to return the number of bytes that could not be
cleared. After the first patch, this is now done for sizes 0-3, but
sizes 4-63 would return garbage. This was tracked down to an error in
reusing the t1 register meaning it no longer contained the expected
value in the fault handler, and the fault handler erroneously masking
off the lower bits of the result.

The following test code was used to verify the behavior.

int j, k;
for (j = 0; j < 512; j++) {
if ((k = clear_user(NULL, j)) != j) {
pr_err("clear_user (NULL %d) returned %d\n", j, k);
}
}

Without patch 1, an OOPS is triggered by the first iteration. Without
the second patch, j = 4..63 returns garbage.

Applies on v4.16-rc7
Tested on MIPS creator ci40 (MIPS32) and Cavium Octeon II (MIPS64).



Matt Redfearn (2):
MIPS: memset.S: EVA & fault support for small_memset
MIPS: memset.S: Fix return of __clear_user from Lpartial_fixup

arch/mips/lib/memset.S | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)

--
2.7.4