uClibc-ng and uClibc memset bug, ARM

Lucian Cojocar <[email protected]> Thu, 26 May 2016 01:06:40 +0200
Newsgroups gmane.comp.lib.uclibc.general
Message-ID <[email protected]>
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.

Thanks,
Lucian

[0]https://github.com/wbx-github/uclibc-ng/blob/master/libc/string/arm/memset.S#L70
[1]http://tomato.groov.pl/download/K26ARM/132/tomato-R7000-ARM--132-AIO-64K.zip
[2]disas.S (attached)
[3]qemu.log (attached)
[4]http://www.cvedetails.com/cve/CVE-2011-2702/
[5]http://old.sebug.net/paper/Exploits-Archives/2012-exploits/1208-exploits/eglibc-exec.txt

_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc
qemu.log (text/x-log, 3.2 KB)
----------------
IN: 
0x00000000:  e3a00000      mov	r0, #0	; 0x0
0x00000004:  e59f1004      ldr	r1, [pc, #4]	; 0x10
0x00000008:  e59f2004      ldr	r2, [pc, #4]	; 0x14
0x0000000c:  e59ff004      ldr	pc, [pc, #4]	; 0x18

R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=00000000 R14=00000000 R15=00000000
PSR=400001d3 -Z-- A svc32
----------------
IN: 
0x00010000:  e59fd004      ldr	sp, [pc, #4]	; 0x1000c
0x00010004:  eb000001      bl	0x10010

R00=00000000 R01=00000183 R02=00000100 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=00000000 R14=00000000 R15=00010000
PSR=400001d3 -Z-- A svc32
----------------
IN: 
0x00010010:  e92d4800      push	{fp, lr}
0x00010014:  e28db004      add	fp, sp, #4	; 0x4
0x00010018:  e24ddc02      sub	sp, sp, #512	; 0x200
0x0001001c:  e24b3f81      sub	r3, fp, #516	; 0x204
0x00010020:  e1a00003      mov	r0, r3
0x00010024:  e3a010aa      mov	r1, #170	; 0xaa
0x00010028:  e59f2004      ldr	r2, [pc, #4]	; 0x10034
0x0001002c:  eb000002      bl	0x1003c

R00=00000000 R01=00000183 R02=00000100 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=000200d8 R14=00010008 R15=00010010
PSR=400001d3 -Z-- A svc32
----------------
IN: 
0x0001003c:  e1a03000      mov	r3, r0
0x00010040:  e3520008      cmp	r2, #8	; 0x8
0x00010044:  ba000016      blt	0x100a4

R00=0001fed0 R01=000000aa R02=ffff0000 R03=0001fed0
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=000200d4
R12=00000000 R13=0001fed0 R14=00010030 R15=0001003c
PSR=400001d3 -Z-- A svc32
----------------
IN: 
0x000100a4:  e1b02002      movs	r2, r2
0x000100a8:  01a0f00e      moveq	pc, lr

R00=0001fed0 R01=000000aa R02=ffff0000 R03=0001fed0
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=000200d4
R12=00000000 R13=0001fed0 R14=00010030 R15=000100a4
PSR=a00001d3 N-C- A svc32
----------------
IN: 
0x000100ac:  e2622007      rsb	r2, r2, #7	; 0x7
0x000100b0:  e08ff102      add	pc, pc, r2, lsl #2

R00=0001fed0 R01=000000aa R02=ffff0000 R03=0001fed0
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=000200d4
R12=00000000 R13=0001fed0 R14=00010030 R15=000100ac
PSR=a00001d3 N-C- A svc32
----------------
IN: 
0x000500d4:  00000000      andeq	r0, r0, r0
0x000500d8:  00000000      andeq	r0, r0, r0
0x000500dc:  00000000      andeq	r0, r0, r0
0x000500e0:  00000000      andeq	r0, r0, r0
0x000500e4:  00000000      andeq	r0, r0, r0
0x000500e8:  00000000      andeq	r0, r0, r0
0x000500ec:  00000000      andeq	r0, r0, r0
0x000500f0:  00000000      andeq	r0, r0, r0
0x000500f4:  00000000      andeq	r0, r0, r0
0x000500f8:  00000000      andeq	r0, r0, r0
0x000500fc:  00000000      andeq	r0, r0, r0
0x00050100:  00000000      andeq	r0, r0, r0
0x00050104:  00000000      andeq	r0, r0, r0
0x00050108:  00000000      andeq	r0, r0, r0
0x0005010c:  00000000      andeq	r0, r0, r0
0x00050110:  00000000      andeq	r0, r0, r0
0x00050114:  00000000      andeq	r0, r0, r0
disas.S (text/plain, 1.7 KB)
0003df70 <memset>:
   3df70:	  e1a03000 	  mov	r3, r0
   3df74:	  e3520008 	  cmp	r2, #8
   3df78:	  ba000016 	  blt	3dfd8 <memset+0x68>
   3df7c:	  e1811401 	  orr	r1, r1, r1, lsl #8
   3df80:	  e1811801 	  orr	r1, r1, r1, lsl #16
   3df84:	  e3130003 	  tst	r3, #3
   3df88:	  14c31001 	  strbne	 r1, [r3], #1
   3df8c:	  12422001 	  subne	  r2, r2, #1
   3df90:	  1afffffb 	  bne	3df84 <memset+0x14>
   3df94:	  e1a0c001 	  mov	ip, r1
   3df98:	  e3520008 	  cmp	r2, #8
   3df9c:	  ba00000d 	  blt	3dfd8 <memset+0x68>
   3dfa0:	  e8a31002 	  stmia	  r3!, {r1, ip}
   3dfa4:	  e2422008 	  sub	r2, r2, #8
   3dfa8:	  e3520008 	  cmp	r2, #8
   3dfac:	  ba000009 	  blt	3dfd8 <memset+0x68>
   3dfb0:	  e8a31002 	  stmia	  r3!, {r1, ip}
   3dfb4:	  e2422008 	  sub	r2, r2, #8
   3dfb8:	  e3520008 	  cmp	r2, #8
   3dfbc:	  ba000005 	  blt	3dfd8 <memset+0x68>
   3dfc0:	  e8a31002 	  stmia	  r3!, {r1, ip}
   3dfc4:	  e2422008 	  sub	r2, r2, #8
   3dfc8:	  e3520008 	  cmp	r2, #8
   3dfcc:	  a8a31002 	  stmiage	r3!, {r1, ip}
   3dfd0:	  a2422008 	  subge	  r2, r2, #8
   3dfd4:	  aaffffef 	  bge	3df98 <memset+0x28>
   3dfd8:	  e1b02002 	  movs	   r2, r2
   3dfdc:	  01a0f00e 	  moveq	  pc, lr
   3dfe0:	  e2622007 	  rsb	r2, r2, #7
   3dfe4:	  e08ff102 	  add	pc, pc, r2, lsl #2
   3dfe8:	  e1a00000 	  nop		   	   ; (mov r0, r0)
   3dfec:	  e4c31001 	  strb	   r1, [r3], #1
   3dff0:	  e4c31001 	  strb	   r1, [r3], #1
   3dff4:	  e4c31001 	  strb	   r1, [r3], #1
   3dff8:	  e4c31001 	  strb	   r1, [r3], #1
   3dffc:	  e4c31001 	  strb	   r1, [r3], #1
   3e000:	  e4c31001 	  strb	   r1, [r3], #1
   3e004:	  e4c31001 	  strb	   r1, [r3], #1
   3e008:	  e1a0f00e 	  mov	pc, lr
   3e00c:	  e320f000 	  nop	{0}
signature.asc (application/pgp-signature, 473 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQEcBAEBCAAGBQJXRjAKAAoJEAGeS6TyNSLWKI8H/0TB8bm8mz9LLCcLr1Gj7naT
/ITJ+ynF2uRoopaos7mIk/xTWfROEjwHNt7hNAVbFJHfCed8BeErszUgAC5A1OXN
0DEXUYcY44wh+WPOH2ZtDO523iRRWMj5pqSuF2/m7OLI3sY8YEiHu/cvDc44ShDR
cQ2hctZn9uPlCU3BqgodXFJ4s8gPzp7VjPT4D6MSWITH+0mYSD1BGkPnt4RAHYCv
CuXr9Ndi4m3/HbSB8FdeQ/VW5StOl0AP7iE/iZtQZnvIp0YkoUR9U/c4krMwRvxG
wSA0G7+rTDbdCw3lwL6ZQcUAoJUUVzPeySiDj2archxp4a29CI1N7Y+8+t+g5rw=
=f3gT
-----END PGP SIGNATURE-----