--- a/package/uclibc/0004-avm-memset-cve-2016-6264.patch 2017-06-19 12:57:01.342125307 +0200 +++ b/package/uclibc/0004-avm-memset-cve-2016-6264.patch 2017-06-19 12:57:01.342125307 +0200 @@ -0,0 +1,125 @@ +commit e3848e3dd64a8d6437531488fe341354bc02eaed +Author: Lucian Cojocar +Date: Fri Jun 10 18:44:44 2016 +0200 + + bugfix: ARM: memset.S: use unsigned comparisons + + The 'BLT' instruction checks for *signed* values. So if a3, length + parameter of memset, is negative, then value added to the PC will be + large. + + memset(buf, 0xaa, 0xffff0000) triggers the bug. + + GDB session without the patch: + + """ + $ gdb ./main-buggy-memset.elf -q + Reading symbols from ./main-buggy-memset.elf...done. + (gdb) x/i memset + 0x8770 : mov r3, r0 + (gdb) r + Starting program: /root/memset/main-buggy-memset.elf + + Program received signal SIGSEGV, Segmentation fault. + 0x00048808 in ?? () + """ + + The $pc is outside of the memset function because: + + """ + (gdb) x/i $pc + => 0x87e4 : add pc, pc, r2, lsl #2 + (gdb) info reg $r2 + r2 0x10007 65543 + """ + + GDB session with the bug fixed (patch applied): + + """ + $ gdb ./main-fixed-memset.elf -q + Reading symbols from ./main-fixed-memset.elf...done. + (gdb) x/i memset + 0x8770 : mov r3, r0 + (gdb) r + Starting program: /root/memset/main-fixed-memset.elf + + Program received signal SIGSEGV, Segmentation fault. + memset () at libc/string/arm/memset.S:92 + 92 libc/string/arm/memset.S: No such file or directory. + (gdb) x/i $pc + => 0x87b0 : stmia r3!, {r1, r12} + (gdb) info reg $r3 + r3 0x15000 86016 + (gdb) info proc mappings + process 5822 + Mapped address spaces: + + Start Addr End Addr Size Offset objfile + 0x8000 0xb000 0x3000 0x0 + /root/memset/main-fixed-memset.elf + 0x12000 0x15000 0x3000 0x2000 + /root/memset/main-fixed-memset.elf + 0xb6fff000 0xb7000000 0x1000 0x0 [sigpage] + 0xbefdf000 0xbf000000 0x21000 0x0 + 0xffff0000 0xffff1000 0x1000 0x0 [vectors] + (gdb) info reg $sp + sp 0x14d78 0x14d78 + """ + + GDB crashes inside the memset function, on the store instruction. This + time the crash is (as expected) because of a memory access imediately + after the memory region that contains the stack -- the buffer that's + being memset'd is allocated on the stack. + + Signed-off-by: Lucian Cojocar + +diff --git a/libc/string/arm/memset.S b/libc/string/arm/memset.S +index 2be4850e4..412270f50 100644 +--- a/libc/string/arm/memset.S ++++ b/libc/string/arm/memset.S +@@ -67,7 +67,7 @@ memset: + memset: + mov a4, a1 + cmp a3, $8 @ at least 8 bytes to do? +- blt 2f ++ blo 2f + orr a2, a2, a2, lsl $8 + orr a2, a2, a2, lsl $16 + 1: +@@ -84,27 +84,27 @@ memset: + mov ip, a2 + 1: + cmp a3, $8 @ 8 bytes still to do? +- blt 2f ++ blo 2f + stmia a4!, {a2, ip} + sub a3, a3, $8 + cmp a3, $8 @ 8 bytes still to do? +- blt 2f ++ blo 2f + stmia a4!, {a2, ip} + sub a3, a3, $8 + cmp a3, $8 @ 8 bytes still to do? +- blt 2f ++ blo 2f + stmia a4!, {a2, ip} + sub a3, a3, $8 + cmp a3, $8 @ 8 bytes still to do? + #if defined(__thumb2__) +- itt ge +- stmiage a4!, {a2, ip} +- subge a3, a3, $8 ++ itt hs ++ stmiahs a4!, {a2, ip} ++ subhs a3, a3, $8 + #else +- stmgeia a4!, {a2, ip} +- subge a3, a3, $8 ++ stmhsia a4!, {a2, ip} ++ subhs a3, a3, $8 + #endif +- bge 1b ++ bhs 1b + 2: + movs a3, a3 @ anything left? + IT(t, eq)