uClibc-ng and uClibc memset bug, ARM

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

uClibc-ng and uClibc memset bug, ARM

Lucian Cojocar
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
[hidden email]
http://lists.busybox.net/mailman/listinfo/uclibc

qemu.log (3K) Download Attachment
disas.S (2K) Download Attachment
signature.asc (484 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: uClibc-ng and uClibc memset bug, ARM

Rich Felker-2
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
_______________________________________________
uClibc mailing list
[hidden email]
http://lists.busybox.net/mailman/listinfo/uclibc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Spam] Re: uClibc-ng and uClibc memset bug, ARM

Lucian Cojocar
On 05/26/2016 01:45 AM, Rich Felker wrote:

> 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.).
>
Is this defined by some standard (i.e. objects should be no larger than
than PTRDIFF_MAX)?

Lucian
_______________________________________________
uClibc mailing list
[hidden email]
http://lists.busybox.net/mailman/listinfo/uclibc
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Spam] Re: uClibc-ng and uClibc memset bug, ARM

Rich Felker-2
On Thu, May 26, 2016 at 11:07:33AM +0200, Lucian Cojocar wrote:

> On 05/26/2016 01:45 AM, Rich Felker wrote:
> > 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.).
> >
> Is this defined by some standard (i.e. objects should be no larger than
> than PTRDIFF_MAX)?

No; but it's very hard to make an implementation that supports such
objects and conforms to other requirements of the standard. All
existing compilers I'm aware of have numerous serious problems with
trying to support such objets. It's also very hard for application
code to safely use implementations that support such objects; it
becomes unsafe to subtract pointers unless you know ahead of time that
the difference won't overflow, since pointer differences that overflow
produce undefined behavior.

As I said, a lot has been written on this topic recently -- GCC and
LLVM bug reports, blog posts, papers, twitter threads, etc. The
details are way too big for me to cover extensively in an email reply,
but the information is out there if you search for it.

Rich
_______________________________________________
uClibc mailing list
[hidden email]
http://lists.busybox.net/mailman/listinfo/uclibc
Loading...