Date: Fri, 30 Mar 2012 19:15:49 -0700 From: Peter Wemm <peter@wemm.org> To: Richard Yao <ryao@cs.stonybrook.edu> Cc: Konstantin Belousov <kostikbel@gmail.com>, freebsd-stable@freebsd.org Subject: Re: Text relocations in kernel modules Message-ID: <CAGE5yCpuvsVrc-%2BDTVas-W4fjuP2s%2B6PQONMOTyEbGnj2CY3ig@mail.gmail.com> In-Reply-To: <4F7637F3.2060502@cs.stonybrook.edu> References: <4F75E404.8000104@cs.stonybrook.edu> <4F75EF86.6090909@cs.stonybrook.edu> <20120330190713.GG2358@deviant.kiev.zoral.com.ua> <4F760C9E.6060405@cs.stonybrook.edu> <20120330194649.GH2358@deviant.kiev.zoral.com.ua> <4F761371.7020606@cs.stonybrook.edu> <20120330203605.GI2358@deviant.kiev.zoral.com.ua> <4F76350F.8000708@cs.stonybrook.edu> <20120330224631.GJ2358@deviant.kiev.zoral.com.ua> <4F7637F3.2060502@cs.stonybrook.edu>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Mar 30, 2012 at 3:47 PM, Richard Yao <ryao@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. 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. 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. 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. -- Peter Wemm - peter@wemm.org; peter@FreeBSD.org; peter@yahoo-inc.com; KI6FJV "All of this is for nothing if we don't go to the stars" - JMS/B5 "If Java had true garbage collection, most programs would delete themselves upon execution." -- Robert Sewell
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGE5yCpuvsVrc-%2BDTVas-W4fjuP2s%2B6PQONMOTyEbGnj2CY3ig>