Text relocations in kernel modules

Richard Yao ryao at cs.stonybrook.edu
Sat Mar 31 02:44:39 UTC 2012


On 03/30/12 22:15, Peter Wemm wrote:
> On Fri, Mar 30, 2012 at 3:47 PM, Richard Yao <ryao at cs.stonybrook.edu> wrote:
>> On 03/30/12 18:46, Konstantin Belousov wrote:
>>> Reread what I wrote to you. Also, it pays off learning how ELF works
>>> before making conclusion from the absence of the output of readelf -d.
>>> Amd64 modules _are not_ shared objects.
>>
>> Whether or not they are shared objects is irrelevant. The fact is that
>> they have text relocations, which interfere with ASLR. Do I need to
>> produce exploit code before you take me seriously?
>>
> 
> I am the person who wrote it and deliberately chose to cause text
> relocations to be generated on i386.  It is by design, not a bug.
> 
> All of your concerns are perfectly valid if they were for userland.
> 
> For the record, our amd64 modules ALSO do this, but your tools simply
> do not detect it.
> 
> Here is what happens, and here is why it is not a problem:
> 
> When you compile with -fpic on an architecture that doesn't support
> PC-relative addressing adequately, the compiler generates code to do
> indirect memory references via the global offset table.  This is so
> that all the relocations can be collected into a single location in
> order to not dirty the MAP_PRIVATE data pages.
> 
> example:
> if there is an function at 0x12345, and another function in a
> different .so file that wants to call it at 0x22345, then the call
> instruction would have to be relocated.  The asm instructions would
> look like:
> 0xE8FFEFFFFF  (offset is -0x10000)
> 
> If the same .so file was loaded in another user process at 0x32345,
> then the relocation would be different.  An entire page would be
> dirtied by the dynamic linker so that the second instance of the .so
> file had 0xE8FFDFFFFF (-0x20000).  This is a waste of memory and
> causes a storm of VM faults at startup.
> 
> Instead, the code is compiled with -fPIC, which causes an extra memory
> reference via the global offset table.  Instead of the relocations
> being spread over the text segment, the relocations are in a single
> page.  The dynamic linker has to dirty one page only in order to set
> up a whole host of relocations.
> 
> The cost is i386 doesn't have native pc-relative mode, so it has to
> waste an entire register.  We dedicate one of the 6 general purpose
> registers which costs a hefty performance hit.  This is why crypto
> code tends to be compiled without -fpic, for example.
> 
> For KERNEL modules, all this changes.
> 
> In userland, there is a dynamic linker. In the kernel, there is none.
> In userland, the .so files are mapped with mmap(MAP_PRIVATE), the
> kernel does not use mmap and always uses a private copy.
> In userland, the .so files are shared, the kernel NEVER shares them.
> In userland, doing a relocation causes a copy on write fault, this
> never happens to the kernel because its using private, exclusive
> malloc() pages.
> In userland, we make the performance tradeoff from -fpic in order to
> share memory pages, the kernel never shares pages so -fpic is a waste.
> In userland, ASLR has security benefits.  The kernel already does
> this.. if you load a module on one machine it'll ALWAYS be at
> different address space compared to another.
> 
> In FreeBSD/i386, we use 'ld -shared -o foo.ko *.o', to wrap the non
> pic .o files into a container that was more convenient at the time to
> parse.  There is no global-offset-table.
> In FreeBSD/amd64, we use 'ld -r -o foo.ko *.o' to wrap the same
> non-pic code into a less convenient form that we can feed back into
> the linker if we wish.  There is no global offset table.
> 
> Both i386 and amd64 use raw relocations, regardless of where the came
> from.  Text, data, anywhere.
> 
> This has nothing to do with ASLR, because they are kernel objects, not
> shared libraries.

Most people seem to think that I am unaware of these things, but I
already knew most of it. Note that this mostly applies to remarks people
are sending me privately.

With that said, thank you for the detailed explanation. It filled in a
few blanks that I had, specifically in how FreeBSD does things.

> You posted:
>  * QA Notice: The following files contain runtime text relocations
>  *  Text relocations force the dynamic linker to perform extra
>  *  work at startup, waste system resources, and may pose a security
>  *  risk.  On some architectures, the code may not even function
>  *  properly, if at all.
> The key here is "dynamic linker".  There is no dynamic linker to
> process this stuff.

> This is simply a tools problem on your end.  It's not a bug.

My tools are doing what they were supposed to do. However, people on the
list seem to think that the idea that they are checking for a problem to
be a matter of opinion.

> There are no security implications, no system resources to be wasted.
> 
> And if you think there are security implications, then lets see a
> proof-of-concept.

If I find time to write a proof-of-concept, I promise to publish it
publicly. Your security team will find out when everyone else does.

You can argue otherwise, but for all I know, exploit code that ASLR
breaks is already in the wild. I believe that nothing short of full
disclosure would be beneficial to your users' security.

> I have given you a detailed explanation of why it's not a problem.  If
> you want to continue, then reply with details, not hearsay or
> theories.

I asked why things were one way and certain people were rather rude.
There is no need to join them in that. Anyway, my question is answered.
Thanks.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 900 bytes
Desc: OpenPGP digital signature
Url : http://lists.freebsd.org/pipermail/freebsd-stable/attachments/20120331/3ce51f6b/signature.pgp


More information about the freebsd-stable mailing list