uClibc-ng and uClibc memset bug, ARM

Rich Felker dalias at libc.org
Wed May 25 23:45:51 UTC 2016


On Thu, May 26, 2016 at 01:06:40AM +0200, Lucian Cojocar wrote:
> Hi all,
> 
> in libc/string/arm/memset.S[0]. If the code is compiled with #undef
> __thumb2__ and with #undef THUMB1_ONLY (this seems to be case for
> Tomato[1] at least and for buildroot) then the code looks like this[2]:
> 
> """
> memset:
> 	mov	a4, a1
> 	cmp	a3, $8		@ at least 8 bytes to do?
> 	blt	2f
> 	orr	a2, a2, a2, lsl $8
> 	orr	a2, a2, a2, lsl $16
> ...
> 2:
> 	movs	a3, a3		@ anything left?
> 	IT(t, eq)
> 	BXC(eq, lr)		@ nope
> 
> 
> 	rsb	a3, a3, $7
> 	add	pc, pc, a3, lsl $2    <--- a3 can be larger than $7 here
> 	mov	r0, r0
> 	strb	a2, [a4], $1
> 	strb	a2, [a4], $1
> ...
> """"
> 
> The problem is that 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.
> 
> In short, an attacker gains control of PC through the len parameter of
> memset. The attack is a bit unrealistic, as it requires that the
> application that uses uClibc allows a user to control a memory chunk
> larger than 2GB.
> 
> I only tested this on qemu-system-arm[3]. The code was just calling
> memset(buf, 0xaa, 0xffff0000), memset, in this example[3] is @0x1003c.
> 
> This bug is similar to CVE-2011-2702[4, 5]. Probably we should notify
> oss-security and get a CVE for this as the impact is unknown.

This is only one of a HUGE number of things that go hopelessly wrong
if an implementation allows single objects with sizes larger than
PTRDIFF_MAX. A lot has been written on this topic recently. Regardless
of how this one report is resolved, uClibc should ensure that no such
objects can arise (by checking sizes in malloc, mmap, etc.).

Rich


More information about the uClibc mailing list