I want to restrict the execution of the binaries, in Linux, to those only compiled by myself. Lets say my system has gcc with version 4.8.4, I want to allow execution of ELF binaries that are compiled by gcc only installed on my system. Any ELF that is even compiled by same version 4.8.4, should not execute on my system.
.comment section contains the version and name of the compiler used to compile ELF. Can we use this information if yes how?
Any idea and suggestion is much appreciated
I want to restrict the execution of the binaries, in Linux, to those only compiled by myself.
Suppose you succeed in this. You do realize that your shell, your gcc, your ls will all immediately stop working (unless you've built them all yourself prior to turning on the restriction).
But suppose you have built the entire system, including the compiler, assembler and linker. In this case, you'll want to modify your linker and your kernel such that the linker signs the binaries it links, and your kernel verifies that a valid signature is present, and refuses to run the binary if the signature is invalid. You can read more about code signing here.
.comment section contains the version and name of the compiler used to compile ELF.
Normally, it does. However it is trivial to add a .comment section with arbitrary contents to an already-linked executable, so you can't base your restriction on the contents of .comment (unless you want your restriction to be trivial to bypass).
can objcopy ease my life without changing linker?
Yes.
I believe you are thinking about your problem in a wrong way (thinking about mechanics before thinking about the substance of your solution).
Assuming you do want to do code signing, you'll need to generate a signature for every binary, and then:
Have some means for the kernel to verify that the signature is valid, and
Attach the signature to the binary. This could be as easy as having foo.signature in the same directory as foo for every binary you wish to run. Or you could use objcpy to make the signature part of the binary itself (more convenient if you move your binaries around).
Related
ELF binaries of Linux distributions are stripped and don't include ".comment" section.
Therefore, I could not get the information which compiler build the ELF binary.
I guess most of them are created by GCC and want to know which GCC version is used.
I know that if the ".comment" section is included in the ELF binary, I can get the compiler information using "readelf" or "objdump".
The method was posted before at the stackoverflow.com
How to retrieve the GCC version used to compile a given ELF executable?
I guess I can use decompiling tools (e.g., Hex-Rays Decompiler https://www.hex-rays.com/products/decompiler/ ) to estimate the compiler version.
I also want to know the compiler name if the binary is not created by GCC. For example LLVM-clang.
Do you know a tool to estimate the compiler name and version which create the ELF binary?
I prefer to use a free tool.
ELF binaries of Linux distributions are stripped and don't include ".comment" section. Therefore, I could not get the information which compiler build the ELF binary.
Most binaries also come with a separate debuginfo package, which does have .comment sections, and full source package which allows you to configure and build (almost) identical binary.
Examining either the debuginfo, or the source package is a much easier and more reliable way to answer your question, then guessing from the binary will ever be.
Do you know a tool to estimate the compiler name and version which create the ELF binary?
I doubt such a tool exists: writing such a tool would be a mostly pointless exercise.
Is there a GCC configuration which will produce an executable only containing ARM32 code?
I know the -marm switch tells the compiler not to produce Thumb code, but it applies only to the user code of the program, while initialization routines (e.g. _start, frame_dummy, ...) still contain Thumb instructions.
I am using the Linaro cross compiler tool-chain (arm-linux-gnueabihf-) on a Linux x86-64 system.
EDIT :
While recompiling the tool-chain I found the (probable) solution myself. The initialization routines encoded as Thumb are part of glibc and can be found in the object files crt1.o, crti.o and crtbegin.o. I haven't tried recompiling it, but there may be a configuration value which forces the whole libc to be encoded as ARM32.
Is there a GCC configuration which will produce an executable only containing ARM32 code? I know the -marm switch ...
Your main problem is that that code (e.g. _start) is not produced by the compiler but it is already present pre-compiled (as thumb code).
If you want to have these functions to be non-thumb code you'll have to "replace" the existing files (thumb) by your own ones (non-thumb).
(You don't have to overwrite the existing files but you can instruct the linker to search for these files in a different directory.)
If you don't find pre-built non-thumb files you'll have to create them yourself (what may be a lot of work).
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?
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:
Ubuntu Security Team - Executable Stacks
I have a object file which has a main() function inside and just needs to be linked with crt... objects to be an executable . Unfortunately I can only compile and I can not link it to be an executable .
so I decided to create a c program ( on a pc with working GCC and linker ) to attach object(s) at the end of itself and execute the codes attached at run time (simulating a linked object ).
I saw DL API but I do'nt know how to use it for the problem I said .
May sb help me to know , how I can executing a code attached at the end of an executable .
Avoid doing that; it would be a mess .... And it probably won't reliably work, at least if the program is dynamically linked to the libc6.so (e.g. because of ASLR)
Just use shared objects and dynamically linked libraries (See dynamic linker wikipage). You need to learn about dlopen(3) etc.
If you really insist, take many weeks to learn a lot more: read Levine's book on Linker and Loaders, read Advanced Linux Programming, read many man pages (including execve(2), mmap(2), elf(5), ld.so(8), ...) study the kernel code for execve and mmap, the GNU libc and MUSL libc source codes (for details about implementations of the dynamic linker), the x86-64 ABI or the ABI for your target processor (is it an ARM?), learn more about the GNU binutils etc, etc, etc.
In short, your life is too short doing such messy things, unless you are already an expert, e.g. able to implement your own dynamic linker.
addenda
Apparently your real issue seems to use tinycc on the ARM (under Android I am guessing). I would then ask on their mailing list (perhaps contribute with some patch), or simply use binutils and make your own GNU ld linker script to make it work. Then the question becomes entirely different and completely unrelated to your original question. There might be some previous attempts to solve that, according to Google searches.
In Linux, downloaded a program source and want it to be statically linked.
Have a huge Makefile there,
I
./configure
make
to compile.
prehpes it's a bit too general to ask, but how can I make the binary statically linked?
EDIT: the reason for this is wanting to make sure the binary will
have no dependencies (or at least as few as possible), making it possible to run on any Linux based computer, even one without Internet connection, and non-updated Linux.
Most autoconf generated configure script will allow you to make a static build:
./configure --enable-static
make
If that doesn't work, you may be able to pass linker flags in via LDFLAGS, like this:
./configure LDFLAGS=-static
Yeah, you need to edit the make file and add the -static parameter to gcc during the link.
I assume it's using gcc to compile a series of c programs, although you will have to look in the Makefile to find out.
If so, you can adjust the gcc lines in the makefile to do static linking, although depending upon the structure of the program, this may be a complex change. Take a look at man gcc to see how this is done.
I'd be interested to know why you are statically linking. Have you considered using prelinking instead?
You should be aware that there may be licence problems to doing this if all components are not GPL.
If you cannot compile a static binary, I've had good results using Statifier.