| From 9d7f29cdb4ca53506115cf1d7a02ce6013894df0 Mon Sep 17 00:00:00 2001 |
| From: James Hogan <james.hogan@imgtec.com> |
| Date: Wed, 5 Apr 2017 16:32:45 +0100 |
| Subject: [PATCH] MIPS: cevt-r4k: Fix out-of-bounds array access |
| |
| commit 9d7f29cdb4ca53506115cf1d7a02ce6013894df0 upstream. |
| |
| calculate_min_delta() may incorrectly access a 4th element of buf2[] |
| which only has 3 elements. This may trigger undefined behaviour and has |
| been reported to cause strange crashes in start_kernel() sometime after |
| timer initialization when built with GCC 5.3, possibly due to |
| register/stack corruption: |
| |
| sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 10737418237ns |
| CPU 0 Unable to handle kernel paging request at virtual address ffffb0aa, epc == 8067daa8, ra == 8067da84 |
| Oops[#1]: |
| CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.9.18 #51 |
| task: 8065e3e0 task.stack: 80644000 |
| $ 0 : 00000000 00000001 00000000 00000000 |
| $ 4 : 8065b4d0 00000000 805d0000 00000010 |
| $ 8 : 00000010 80321400 fffff000 812de408 |
| $12 : 00000000 00000000 00000000 ffffffff |
| $16 : 00000002 ffffffff 80660000 806a666c |
| $20 : 806c0000 00000000 00000000 00000000 |
| $24 : 00000000 00000010 |
| $28 : 80644000 80645ed0 00000000 8067da84 |
| Hi : 00000000 |
| Lo : 00000000 |
| epc : 8067daa8 start_kernel+0x33c/0x500 |
| ra : 8067da84 start_kernel+0x318/0x500 |
| Status: 11000402 KERNEL EXL |
| Cause : 4080040c (ExcCode 03) |
| BadVA : ffffb0aa |
| PrId : 0501992c (MIPS 1004Kc) |
| Modules linked in: |
| Process swapper/0 (pid: 0, threadinfo=80644000, task=8065e3e0, tls=00000000) |
| Call Trace: |
| [<8067daa8>] start_kernel+0x33c/0x500 |
| Code: 24050240 0c0131f9 24849c64 <a200b0a8> 41606020 000000c0 0c1a45e6 00000000 0c1a5f44 |
| |
| UBSAN also detects the same issue: |
| |
| ================================================================ |
| UBSAN: Undefined behaviour in arch/mips/kernel/cevt-r4k.c:85:41 |
| load of address 80647e4c with insufficient space |
| for an object of type 'unsigned int' |
| CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.9.18 #47 |
| Call Trace: |
| [<80028f70>] show_stack+0x88/0xa4 |
| [<80312654>] dump_stack+0x84/0xc0 |
| [<8034163c>] ubsan_epilogue+0x14/0x50 |
| [<803417d8>] __ubsan_handle_type_mismatch+0x160/0x168 |
| [<8002dab0>] r4k_clockevent_init+0x544/0x764 |
| [<80684d34>] time_init+0x18/0x90 |
| [<8067fa5c>] start_kernel+0x2f0/0x500 |
| ================================================================= |
| |
| buf2[] is intentionally only 3 elements so that the last element is the |
| median once 5 samples have been inserted, so explicitly prevent the |
| possibility of comparing against the 4th element rather than extending |
| the array. |
| |
| Fixes: 1fa405552e33f2 ("MIPS: cevt-r4k: Dynamically calculate min_delta_ns") |
| Reported-by: Rabin Vincent <rabinv@axis.com> |
| Signed-off-by: James Hogan <james.hogan@imgtec.com> |
| Tested-by: Rabin Vincent <rabinv@axis.com> |
| Cc: linux-mips@linux-mips.org |
| Cc: <stable@vger.kernel.org> # 4.7.x- |
| Patchwork: https://patchwork.linux-mips.org/patch/15892/ |
| Signed-off-by: Ralf Baechle <ralf@linux-mips.org> |
| |
| diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c |
| index 804d2a2a19fe..dd6a18bc10ab 100644 |
| --- a/arch/mips/kernel/cevt-r4k.c |
| +++ b/arch/mips/kernel/cevt-r4k.c |
| @@ -80,7 +80,7 @@ static unsigned int calculate_min_delta(void) |
| } |
| |
| /* Sorted insert of 75th percentile into buf2 */ |
| - for (k = 0; k < i; ++k) { |
| + for (k = 0; k < i && k < ARRAY_SIZE(buf2); ++k) { |
| if (buf1[ARRAY_SIZE(buf1) - 1] < buf2[k]) { |
| l = min_t(unsigned int, |
| i, ARRAY_SIZE(buf2) - 1); |
| -- |
| 2.12.0 |
| |