This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

How to implement a kernel feature check in the crt* files?


Hi Jakub and Roland,

I'm looking for a way to match a kernel capability against a
requirement of an ELF binary in order to prevent the binary from being
executed in case the kernel doesn't support it.

More precisely this is about supporting 64 bit registers in 32 bit
applications on S/390.  In order to make this work the kernel has to
save and restore the upper halfs of 64 bit registers even when running
just 32 bit code.  Kernels starting with version 2.6.32 already
support this and indicate the fact in /proc/cpuinfo as "highgprs" and
in the AT_HWCAPS field of the auxiliary vector with the
HWCAP_S390_HIGH_GPRS flag.

Now the target is to mark executables and DSOs somehow if they are
compiled in a way which needs the upper halfs of the registers to be
saved (-m31 -mzarch) and prevent the execution if the kernel does not
provide that feature.  This is important since the lacking kernel
support would lead to problems which would be extremely difficult to
debug and to reproduce.

Currently I plan to put a check into the _start routine in crt1.o for
executables and another one (perhaps in elf_machine_matches_host) for
DSOs.  For marking the binaries I've identified three different
solutions and would like to get some feedback about which one is
preferrable:


1. Put a flag into the e_flags field of the elf header.


In order to check this flag I've to find the elf header in memory from
the _start routine.  I see two ways to do that:

1a The __executable_start symbol introduced by the linker default
script can be used here.  Unfortunately ld doesn't support that for
PIE.  There does not seem to be a real reason.  But extending the
support in ld would introduce a dependency on a very recent binutils
package.

1b The auxiliary vector does contain the address of the segment
headers in memory.  Currently ld always arranges that the elf header
resides directly before that address.  Using that address to locate
the elf header would break immediately if the elf header gets
extended.  Heuristics like rounding the address down to a page or
checking the elf magic might help. But it stays - well - a heuristic.


2. Put a flag into the .note.gnu.hwcaps section.


That section can be found scanning the segment headers from _start.
There seem to be support for NT_GNU_HWCAPS in glibc as well as
binutils but without any user yet.  Is that mechanism supposed to work
already?  Does anybody know who might already make use of it?


3. Use the .note.ABI-tag set.


Again that segment should be easy to locate in memory by scanning the
segment headers pointed to by AT_PHDR.

The ABI-tag specifies the a required kernel version for the binary and
at least for DSOs there seem to be a check in glibc which prevents
them from being used on older kernels.  I didn't found that for
executables.  Only the dynamic loader seem to care about that - is
that correct?

The assembler could put in 2.6.32 as required kernel version here
assuming that kernels with at least that version provide the needed
feature.



What would be a reasonable approach?  Perhaps there is something much
better I'm completely ignoring so far.


Bye,


-Andreas-


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]