Execution possible in non-executable mappings in recent 2.6 kernels

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dave & list:

I'm writing to report a bug in recent vanilla kernels regarding the
ability to execute in non-executable pages on SPARC.  I'm no SPARC
expert, but I'll try to explain as best I can the problem and make
myself available for debugging/testing any fixes.

I have 4 sparc systems currently, a Netra T1, an Ultra 10, a Sunfire
V210, and a Blade 2500.  The first two systems run the latest 2.4
kernels and experience no problems.  The second two systems run recent
2.6 kernels (2.6.31 and 2.6.32) and both utilize the Cheetah+ MMU.  Both
of these systems running the recent 2.6 kernels exhibit the problem.

I've provided two simple testcases that illustrate the problem.  Either
run them in a loop or just multiple times -- eventually instead of
receiving a segfault (as it should every time for attempting to execute
on the stack, which is non-executable by default per ABI) the shellcode
I've set up on the stack will execute without problems.  In the first
testcase I haven't set up enough code to perform a return from the
function pointer, so you see the varied signals when an instruction
fetch is attempted on the 2nd instruction (made up of whatever
happened to be located on the stack).  In the second case I set up the
proper ret/restore and the program is able to exit cleanly.

I'm willing to do anything to help debug the problem, but I thought it 
would
be wiser to report it first in case anyone had any immediate ideas on
what the problem could be.  I figured it would also help in being able
to debug the issue more effectively, given its seemingly somewhat-random
nature.

Please keep the PaX team and myself CC'd as we're not subscribed to the
list.

Thanks for your help,
-Brad

cat /proc/self/maps output (showing the stack non-executable):
00010000-00014000 r-xp 00000000 08:02 1769474   /bin/cat
00024000-00026000 rwxp 00004000 08:02 1769474   /bin/cat
00026000-00048000 rwxp 00000000 00:00 0         [heap]
f7cf0000-f7e2a000 r--p 00000000 08:02 295830    /usr/lib/locale/locale-archive
f7e2c000-f7fa4000 r-xp 00000000 08:02 1277958   /lib/ultra3/libc-2.7.so
f7fa4000-f7fb4000 ---p 00178000 08:02 1277958   /lib/ultra3/libc-2.7.so
f7fb4000-f7fba000 rwxp 00178000 08:02 1277958   /lib/ultra3/libc-2.7.so
f7fba000-f7fbc000 rwxp 00000000 00:00 0
f7fbc000-f7fde000 r-xp 00000000 08:02 1270085   /lib/ld-2.7.so
f7fec000-f7ff0000 rwxp 00020000 08:02 1270085   /lib/ld-2.7.so
f7ff0000-f7ff2000 rw-p 00000000 00:00 0
ffdb6000-ffde0000 rw-p 00000000 00:00 0         [stack]

First test case:
#include <stdio.h>

typedef int (* _wee)(void);

int main(void)
{
        char buf[4] = { '\x81', '\xc7', '\xe0', '\x08'};
        _wee wee;
        printf("%p\n", &buf);
        wee = (_wee)&buf;
        wee();

        return 0;
}

gdb output in 90-95% of the cases:
Program received signal SIGSEGV, Segmentation fault.
0xff9d9cb0 in ?? ()

gdb output in the other 5-10% of cases:
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/test
0xff811cb0

Program received signal SIGBUS, Bus error.
0xff811cb4 in ?? ()
(gdb) x/x 0xff811cb0
0xff811cb0:     0x81c7e008
(gdb) x/i 0xff811cb0
0xff811cb0:     ret
0xff811cb4:     lda  [ %g4 + %l0 ] (229), %f31

(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/test
0xff97dcb0

Program received signal SIGILL, Illegal instruction.
0xff97dcb4 in ?? ()
(gdb) x/8x $pc-4
0xff97dcb0:     0x81c7e008      0xff97dcb0      0xf7f3af00
0x00000000
0xff97dcc0:     0x00000000      0x00000000      0xfffffffc
0x00000000
(gdb) x/i $pc-4
0xff97dcb0:     ret
0xff97dcb4:     ldqa  [ %i7 + %l0 ] (229), %f62

modified code so it executed a ret / restore:
#include <stdio.h>

typedef int (* _wee)(void);

int main(void)
{
        char buf[8] = { '\x81', '\xc7', '\xe0', '\x08', '\x81', '\xe8',
                        '\x00', '\x00' };
        _wee wee;
        printf("%p\n", &buf);
        wee = (_wee)&buf;
        wee();

        return 0;
}


gdb output in the 5-10% case:
Starting program: /root/test
0xffb4fca8

Program exited with code 01.

Attachment: signature.asc
Description: Digital signature


[Index of Archives]     [Kernel Development]     [DCCP]     [Linux ARM Development]     [Linux]     [Photo]     [Yosemite Help]     [Linux ARM Kernel]     [Linux SCSI]     [Linux x86_64]     [Linux Hams]

  Powered by Linux