[PATCH] Fix negative buffer overflow in copy_from_user

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If we passed an invalid _and_ unaligned source address to
copy_from_user(), the fault handling code miscalculates a length of
uncopied bytes and returns a value greater than original length.  This
also causes an negative buffer overflow and overwrites some bytes just
before the destination kernel buffer.

This can happen "src_unaligned" case in memcpy.S.  If the first load
from source buffer was a LDFIRST/LDREST (L[WD][RL]) instruction, it
raise an exception and the THREAD_BUADDR will be an aligned address so
it will _smaller_ than its real target address.

For all case "src" register is smaller than its target load address
(ie. the offset of load instruction is always greater then zero), and
on the first load instruction "src" is always start of uncopied source
buffer, so we can fix the faulted address using the "src" value.

Signed-off-by: Atsushi Nemoto <anemo@xxxxxxxxxxxxx>
---
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index a526c62..7b21bc9 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -434,6 +434,12 @@ l_exc:
 	 nop
 	LOAD	t0, THREAD_BUADDR(t0)	# t0 is just past last good address
 	 nop
+	/* If src was unaligned, t0 might be _smaller_ then src.  Fix it. */
+	slt	t1, t0, src
+	beqz	t1, 1f
+	 nop
+	move	t0, src
+1:
 	SUB	len, AT, t0		# len number of uncopied bytes
 	/*
 	 * Here's where we rely on src and dst being incremented in tandem,


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux