[grsec] Text Relocations

pageexec at freemail.hu pageexec at freemail.hu
Mon Jan 3 19:01:45 EST 2005


> On Mon, Dec 13, 2004 at 03:35:14PM +0100, pageexec at freemail.hu wrote:
> > in general hunting down and fixing textrelocs requires some detective
> > work and quite a bit of understanding of how the toolchain works. if you
> > want to do it yourself, let me know and i'll try to dig up what i wrote
> > to some gentoo hardened people a while ago. you should also enter this
> > and other cases into the gentoo bugzilla so that the devs are aware of
> > it.

since some people asked off-list, so i dug it up finally:

1. readelf -l app -> note down the read-only PT_LOAD segment info,
   in particular VirtAddr and FileSiz, these provide the boundaries
   for the next step.

2. readelf -r app -> look for addresses under the Offset column that
   fall into the above determined range, not all types are interesting,
   only R_386_RELATIVE, R_386_32 and R_386_PC32 (all those are specific
   to i386 of course and i hope i didn't miss anything).

3. objdump -d app -> in the disassembly find the instructions around
   the addresses obtained in the previous step, on i386 they will never
   be the same exactly because a relocation falls into an instruction,
   e.g., if there's a reloc item on 0804c74c then in the disassembly
   you will find that the instruction that will be relocated is at
   0804c74b or 0804c74a or something a few bytes lower. in any case,
   what matters is the function name in which this relocation is, you
   can just scroll up in the disasm and see which function appears first,
   that's the guy that wasn't compiled properly or has some issues (e.g.,
   it comes from a .S file). of course you must have debug info for this
   to work, so have nostrip enabled.

4. grep function_name src_tree -> find the .c/.S/etc file that defines
   the given function and then try to find out why it was badly compiled.
   keeping the compile log also helps to find the exact gcc/as/etc command
   that was used. note that your bad function may come from a static library
   instead (.a) so be ready to grep them as well.

------------------------------------------------------------------------

now, this above was my original mail, it doesn't tell you how you actually
fix the textreloc however. there's not generic receipt for that, it depends
on how the textreloc occured. some cases:

1. .c wasn't compiled with -fPIC -> resulting .o when linked into a shared
   library will get textrels. this can occur also when object files from a
   static library (.a) get linked into a shared library since .a libs are
   supposed to hold non-PIC code since they are meant for static linking
   into the main executable, which is also non-PIC.

   the solution here is of course to ensure that the .c is compiled with
   -fPIC, but it may not be trivial depending on how the package make
   system works.

2. .c was compiled with -fPIC however it contained inline assembly which
   is not written as PIC, or .S was assembled that contained non-PIC
   snippets. i saw this in multimedia related libraries so far.

   here the fix is even less trivial, it requires assembly knowledge to
   rewrite the non-PIC parts as PIC. it's easier to do for inline asm in
   a .c, more work in a pure .S because we don't have the luxury of the
   C compiler setting up the PIC base register for us. i also saw problems
   where the .S did have a PIC version already however it didn't get
   enabled because some define wasn't set (in xfree, the make system
   didn't propagate __PIC__ or some other define to the assembler).

3. .c was compiled with -fPIE (official gcc 3.3+ feature to create ET_DYN
   executables) but the .o ended up in a normal shared library instead.

   the solution is to carefully sort out what .c files are compiled with
   -fPIC (stuff that goes into shared libs only) or -fPIE (stuff that goes
   into the ET_DYN executables only) or neither (stuff that goes into the
   ET_EXEC executables only). this may mean that certain .c files have
   to be compiled 3 times and collected into separate .a libraries (and
   afaik, there's no established infrastructure for this in the toolchain
   yet).



More information about the grsecurity mailing list