1 |
On Thu, 28 Jan 2016 02:49:46 +0100 |
2 |
"PaX Team" <pageexec@××××××××.hu> wrote: |
3 |
|
4 |
> because it's a useless security measure. for a non-executable .rodata |
5 |
> section to make any sense, the following condition would have to hold: |
6 |
> |
7 |
> a bug (or set of bugs) is exploitable if and only if .rodata is |
8 |
> executable. |
9 |
> |
10 |
> nobody has ever shown that there exists such a bug (or set of bugs) |
11 |
> and in fact there's ample evidence that already executable code |
12 |
> contains all the necessary gadgets an exploit would need. |
13 |
|
14 |
With a dirty one-liner run in my `/usr/bin` I've found 956 MiB of .text |
15 |
and 444 MiB of .rodata, this means about a third of the opportunities |
16 |
of finding the right gadget. |
17 |
|
18 |
I wanted to run a ROP-gadget finder to be able to do a more precise |
19 |
evaluation (maybe also in terms of type of gadgets found in various |
20 |
sections) but the two gadget finder I usually use apparently look for |
21 |
executable *sections*, not segments. But I could work on it. |
22 |
|
23 |
In any case, in my experience finding the right gadget is not always |
24 |
that easy, depending on what you want to do. Depending on the |
25 |
architecture, syscalls have been proven not that hard to find, but |
26 |
stealthy attacks might want to avoid unexpected syscalls completely |
27 |
(SELinux? AppArmor?), maybe they just want to corrupt some data |
28 |
structure, and then finding the right gadgets might become |
29 |
challenging, in particular if your target library/program is small. |
30 |
|
31 |
> on the other hand breaking .rodata out into its own PT_LOAD segment |
32 |
> will waste disk space, kernel memory, virtual address space, slow |
33 |
> down vma lookup time, etc, for exactly zero gain in security. why |
34 |
> bother? |
35 |
|
36 |
While trying to evaluate the cost of the thing in terms of disk and |
37 |
memory space I realized that `--rosegment` is only partially effective. |
38 |
|
39 |
Take a look at the following `readelf -l` of a `--rosegment` hello world |
40 |
program: |
41 |
|
42 |
Program Headers: |
43 |
Type Offset VirtAddr FileSiz MemSiz Flg Align |
44 |
LOAD 0x000000 0x0000000000400000 0x00040d 0x00040d R E 0x1000 |
45 |
LOAD 0x000410 0x0000000000401410 0x000318 0x000318 R 0x1000 |
46 |
LOAD 0x000728 0x0000000000402728 0x000228 0x000229 RW 0x1000 |
47 |
|
48 |
The wasted disk space is practically zero, and there are 0x410 wasted |
49 |
bytes of memory due to `--rosegment` (the second `PT_LOAD` is mapped at |
50 |
0x401410), in addition to the 0x728 which are wasted due to the RW |
51 |
segment. But the real problem is that the kernel is going to `mmap` |
52 |
0x1000 bytes for the first `PT_LOAD`, no matter what, and all that data |
53 |
will be +x, including data which is supposed to be in the second and |
54 |
third `PT_LOAD`. |
55 |
|
56 |
This means that `--rosegment` is a fully effective countermeasure only |
57 |
if the `+x` segment is 0x1000 bytes large. Or from another POV, |
58 |
`--rosegment` should force the `+x` segment to have page-sized dedicated |
59 |
area *in the file*. |
60 |
|
61 |
I'll try to come up with a patch for `ld.gold`. |
62 |
|
63 |
-- |
64 |
Alessandro Di Federico |