1

One modern Linux security hardening tactic is to compile & link code with the option -Wl,-z-noexecstack, this marks the DLL or binary as not needing an executable stack. This condition can be checked using readelf or other means.

I have been working with uClibc and noticed that it produces objects (.so files) that do not have this flag set. Yet uClibc has a configuration option UCLIBC_BUILD_NOEXECSTACK which according to the help means:

  Mark all assembler files as noexecstack, which will mark uClibc
  as not requiring an executable stack.  (This doesn't prevent other
  files you link against from claiming to need an executable stack, it
  just won't cause uClibc to request it unnecessarily.)

  This is a security thing to make buffer overflows harder to exploit.
  ...etc...

On some digging into the Makefiles this is correct - the flag is only applied to the assembler.

Because the flag is only passed to the assembler does this mean that the uClibc devs have missed an important hardening flag? There are other options, for example UCLIBC_BUILD_RELRO which do result in the equivalent flag being added to the linker (as -Wl,-z,relro)

However a casual observer could easily misread this and assume, as I originally did, that UCLIBC_BUILD_NOEXECSTACK is actually marking the .so file when it is in fact not. OpenWRT for example ensures that that flag is set when it builds uClibc.

Why would uClibc not do things the 'usual' way? What am I missing here? Are the libraries (e.g. librt.so, libpthread.so, etc) actually not NX?

EDIT I was able to play with the Makefiles and get the noexecstack bit by using the -Wl,-z,noexecstack argument. So why would they not use that as well?

6EQUJ5
  • 3,142
  • 1
  • 21
  • 29
  • Note: I even tried adding ``-Wl,-z,noexecstack`` to UCLIB_EXTRA_LDFLAGS and it didn't help, seeming to get stripped out somewhere. Although I need to start everything from scratch again and make sure nothing in my environment, or ccache or something is interfering – 6EQUJ5 Aug 23 '14 at 10:41
  • Helpfully not, it turns out that ``UCLIBC_EXTRA_LDFLAGS`` is referenced by ``Rules.mak`` but dropped by ``make oldconfig``. My original question still stands however. – 6EQUJ5 Aug 23 '14 at 11:03
  • Surely there's a mailing list you should bring this up on ;) – davmac Aug 24 '14 at 21:08
  • Yes there is, and I just posted there. But I am also interested in alternative perspectives, which might be gleaned from other sources like SO: and if others ever have a similar question SO sometimes floats higher up a google result than mailing lists... – 6EQUJ5 Aug 25 '14 at 01:07

1 Answers1

1

OK, it turns out after list conversation and further research that:

  • the GNU linker sets the DLL / executable stack state based on the 'lowest common denominator' i.e. if any linked or referenced part has an exec stack then the whole object is set this way

  • the 'correct' way to resolve this problem is actually to find and fix assembly / object files that use an exec stack when they dont need to.

Using the linker to 'fix' things is a workaround if you can't otherwise fix the root cause.

So for uClibc solution is to submit a bug so that the underlying objects get fixed. Otherwise anything linked with static libraries wont get a non-exec stack.

For my own question, if building a custom firmware not using any static libraries it is possibly sufficient to use the linker flag.

References:

6EQUJ5
  • 3,142
  • 1
  • 21
  • 29