* Execution possible in non-executable mappings in recent 2.6 kernels
@ 2010-02-19 22:57 Brad Spengler
2010-02-19 23:07 ` Execution possible in non-executable mappings in recent 2.6 David Miller
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Brad Spengler @ 2010-02-19 22:57 UTC (permalink / raw)
To: sparclinux
[-- Attachment #1: Type: text/plain, Size: 4270 bytes --]
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 #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Execution possible in non-executable mappings in recent 2.6
2010-02-19 22:57 Execution possible in non-executable mappings in recent 2.6 kernels Brad Spengler
@ 2010-02-19 23:07 ` David Miller
2010-02-19 23:20 ` David Miller
2010-02-19 23:54 ` Execution possible in non-executable mappings in recent 2.6 kernels Brad Spengler
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2010-02-19 23:07 UTC (permalink / raw)
To: sparclinux
The bug seems to be that the TSB ITLB loading code mistakenly
uses "andcc %reg, _PAGE_EXEC_4U..." instead of using
"sethi" to load _PAGE_EXEC_4U into a register then checking
the bit.
andcc only supports signed 13-bit values in the immediate
field. And _PAGE_EXEC_4U is bit 12.
I'll work on a fix, thanks for the test cases.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Execution possible in non-executable mappings in recent 2.6
2010-02-19 22:57 Execution possible in non-executable mappings in recent 2.6 kernels Brad Spengler
2010-02-19 23:07 ` Execution possible in non-executable mappings in recent 2.6 David Miller
@ 2010-02-19 23:20 ` David Miller
2010-02-19 23:54 ` Execution possible in non-executable mappings in recent 2.6 kernels Brad Spengler
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2010-02-19 23:20 UTC (permalink / raw)
To: sparclinux
Here's the fix, thanks again for the report:
sparc64: Fix sun4u execute bit check in TSB I-TLB load.
Thanks to testcase and report from Brad Spengler:
--------------------
#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;
}
--------------------
TSB I-tlb load code tries to use andcc to check the _PAGE_EXEC_4U bit,
but that's bit 12 so it gets sign extended all the way up to bit 63
and the test nearly always passes as a result.
Use sethi to fix the bug.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
arch/sparc/kernel/tsb.S | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
index 8c91d9b..db15d12 100644
--- a/arch/sparc/kernel/tsb.S
+++ b/arch/sparc/kernel/tsb.S
@@ -191,10 +191,12 @@ tsb_dtlb_load:
tsb_itlb_load:
/* Executable bit must be set. */
-661: andcc %g5, _PAGE_EXEC_4U, %g0
- .section .sun4v_1insn_patch, "ax"
+661: sethi %hi(_PAGE_EXEC_4U), %g4
+ andcc %g5, %g4, %g0
+ .section .sun4v_2insn_patch, "ax"
.word 661b
andcc %g5, _PAGE_EXEC_4V, %g0
+ nop
.previous
be,pn %xcc, tsb_do_fault
--
1.6.6.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: Execution possible in non-executable mappings in recent 2.6 kernels
2010-02-19 22:57 Execution possible in non-executable mappings in recent 2.6 kernels Brad Spengler
2010-02-19 23:07 ` Execution possible in non-executable mappings in recent 2.6 David Miller
2010-02-19 23:20 ` David Miller
@ 2010-02-19 23:54 ` Brad Spengler
2 siblings, 0 replies; 4+ messages in thread
From: Brad Spengler @ 2010-02-19 23:54 UTC (permalink / raw)
To: sparclinux
[-- Attachment #1: Type: text/plain, Size: 1756 bytes --]
I can confirm this resolved the problem. Thanks again for the
incredibly quick fix!
Tested-by: Brad Spengler <spender@grsecurity.net>
-Brad
On Fri, Feb 19, 2010 at 03:20:11PM -0800, David Miller wrote:
>
> Here's the fix, thanks again for the report:
>
> sparc64: Fix sun4u execute bit check in TSB I-TLB load.
>
> Thanks to testcase and report from Brad Spengler:
>
> --------------------
> #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;
> }
> --------------------
>
> TSB I-tlb load code tries to use andcc to check the _PAGE_EXEC_4U bit,
> but that's bit 12 so it gets sign extended all the way up to bit 63
> and the test nearly always passes as a result.
>
> Use sethi to fix the bug.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---
> arch/sparc/kernel/tsb.S | 6 ++++--
> 1 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
> index 8c91d9b..db15d12 100644
> --- a/arch/sparc/kernel/tsb.S
> +++ b/arch/sparc/kernel/tsb.S
> @@ -191,10 +191,12 @@ tsb_dtlb_load:
>
> tsb_itlb_load:
> /* Executable bit must be set. */
> -661: andcc %g5, _PAGE_EXEC_4U, %g0
> - .section .sun4v_1insn_patch, "ax"
> +661: sethi %hi(_PAGE_EXEC_4U), %g4
> + andcc %g5, %g4, %g0
> + .section .sun4v_2insn_patch, "ax"
> .word 661b
> andcc %g5, _PAGE_EXEC_4V, %g0
> + nop
> .previous
>
> be,pn %xcc, tsb_do_fault
> --
> 1.6.6.1
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-02-19 23:54 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-19 22:57 Execution possible in non-executable mappings in recent 2.6 kernels Brad Spengler
2010-02-19 23:07 ` Execution possible in non-executable mappings in recent 2.6 David Miller
2010-02-19 23:20 ` David Miller
2010-02-19 23:54 ` Execution possible in non-executable mappings in recent 2.6 kernels Brad Spengler
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.