Hacker News new | past | comments | ask | show | jobs | submit login

The linker trick has a problem. It doesn't set the non-executable stack bit, so as a result your whole binary will have an executable stack, and therefore be insecure against various stack smashing exploits.

Try running 'readelf -S blob.o' and you won't see any '.note.GNU-stack' in the output.

If you go via a C source file compiled with gcc (or clang), then the compiler sets the bit properly.

Edit: Also I tried to add a comment to the original posting to warn them, but blogger just eats my comment.




If you are right then this can be mitigated by two additional options passed to objcopy, namely --add-section to create an empty section and --set-section-flags to adjust the flags of this empty section. I'm just recreating the section/flags that I see in a normally compiled file.

    $ make
    cc -Wall -Wextra -ggdb -Os   -c -o testme.o testme.c
    objcopy -I binary -O elf64-x86-64 -B i386:x86-64 \
    	--rename-section .data=.rodata,alloc,load,readonly,data,contents \
    	--add-section ".note.GNU-stack"=/dev/null \
    	--set-section-flags ".note.GNU-stack"=contents,readonly \
    	/etc/passwd passwd.o || (rm -f passwd.o ; exit 1)
    cc   testme.o passwd.o   -o testme
(https://github.com/vogelchr/objcopy_to_carray)

Without --add.../--set section:

    $ readelf -lW testme
    ...
    GNU_STACK (...) RWE 0x10
With --add.../--set-section:

    $ readelf -lW testme
    ...
    GNU_STACK (...) RW  0x10


Looks good. The reason I know a bit about this is I had the same "bin2o" hacky script that used objcopy. It broke every time someone found a new architecture or platform (ie. having to choose the correct -O and -B flags is non-trivial if you want to support every architecture).

The solution (which is not really much better than yours) is a script that creates some assembler and assembles it:

https://github.com/libguestfs/supermin/blob/master/src/bin2s...

I think it's bad that such a simple thing is so hard to do.

Edit: In fact looking at the script now I can see we really should be using .rodata instead of .data. That bug has survived for at least 4 years. Patch posted: https://www.redhat.com/archives/libguestfs/2015-December/msg...


Why would a binary data object contain a stack section at all? Does the lack of NX-stack carry over to the executable?


No binary object file "has a stack" since it's created ephemerally for the executable at runtime. However the linker checks all objects and determines if any of them contain code that requires an executable stack. For backwards compat reasons, that check will say "executable stack needed" for objects that don't contain the special section flag.

In other words, the check is a logical && operation across all the objects, and therefore somewhat fragile. It's for this reason that in RHEL we have a separate check for all the RPMs we ship to make sure that none of them contain executable stack binaries (well, except in some rather exceptional circumstances).

I think you can argue this is a bug in the linker command that creates the binary blob object.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: