On Thu, 28 Jan 2016 02:49:46 +0100
"PaX Team" <pagee...@freemail.hu> wrote:

> because it's a useless security measure. for a non-executable .rodata
> section to make any sense, the following condition would have to hold:
> 
>   a bug (or set of bugs) is exploitable if and only if .rodata is
> executable.
> 
> nobody has ever shown that there exists such a bug (or set of bugs)
> and in fact there's ample evidence that already executable code
> contains all the necessary gadgets an exploit would need. 

With a dirty one-liner run in my `/usr/bin` I've found 956 MiB of .text
and 444 MiB of .rodata, this means about a third of the opportunities
of finding the right gadget.

I wanted to run a ROP-gadget finder to be able to do a more precise
evaluation (maybe also in terms of type of gadgets found in various
sections) but the two gadget finder I usually use apparently look for
executable *sections*, not segments. But I could work on it.

In any case, in my experience finding the right gadget is not always
that easy, depending on what you want to do. Depending on the
architecture, syscalls have been proven not that hard to find, but
stealthy attacks might want to avoid unexpected syscalls completely
(SELinux? AppArmor?), maybe they just want to corrupt some data
structure, and then finding the right gadgets might become
challenging, in particular if your target library/program is small.

> on the other hand breaking .rodata out into its own PT_LOAD segment
> will waste disk space, kernel memory, virtual address space, slow
> down vma lookup time, etc, for exactly zero gain in security. why
> bother?

While trying to evaluate the cost of the thing in terms of disk and
memory space I realized that `--rosegment` is only partially effective.

Take a look at the following `readelf -l` of a `--rosegment` hello world
program:

    Program Headers:
      Type  Offset   VirtAddr           FileSiz  MemSiz   Flg Align
      LOAD  0x000000 0x0000000000400000 0x00040d 0x00040d R E 0x1000
      LOAD  0x000410 0x0000000000401410 0x000318 0x000318 R   0x1000
      LOAD  0x000728 0x0000000000402728 0x000228 0x000229 RW  0x1000

The wasted disk space is practically zero, and there are 0x410 wasted
bytes of memory due to `--rosegment` (the second `PT_LOAD` is mapped at
0x401410), in addition to the 0x728 which are wasted due to the RW
segment. But the real problem is that the kernel is going to `mmap`
0x1000 bytes for the first `PT_LOAD`, no matter what, and all that data
will be +x, including data which is supposed to be in the second and
third `PT_LOAD`.

This means that `--rosegment` is a fully effective countermeasure only
if the `+x` segment is 0x1000 bytes large. Or from another POV,
`--rosegment` should force the `+x` segment to have page-sized dedicated
area *in the file*.

I'll try to come up with a patch for `ld.gold`.

--
Alessandro Di Federico

Reply via email to