bugfix: ARM: memset.S: use unsigned comparisons
commite3848e3dd64a8d6437531488fe341354bc02eaed
authorLucian Cojocar <lucian.cojocar@vu.nl>
Fri, 10 Jun 2016 16:44:44 +0000 (10 18:44 +0200)
committerWaldemar Brodkorb <wbx@uclibc-ng.org>
Sun, 19 Jun 2016 21:34:02 +0000 (19 23:34 +0200)
treec72a7d20027421f46721fe067df3acc426943af1
parent040632792e9f19ccf49149e4ae3ddac351a98b5a
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 <memset>:     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 <memset+116>: 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 <memset>:     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 <memset+64>:  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 <lucian.cojocar@vu.nl>
libc/string/arm/memset.S