Page MenuHomeFreeBSD

Implement MD header filter for elf binaries.
ClosedPublic

Authored by imp on Aug 14 2014, 11:19 PM.

Details

Summary

Implement a MD header filter for elf binaries. This allows the MD code
to tell the MI code it doesn't support the ELF header based on the
private flags or other information in the header. Use this to
implement a filter for OABI binaries on EABI arm (and vice versa)
since the current failure mode for that is a system hang. Provide a
weak elfXX_check_header_md for platforms that don't need this extra
layer of filtering.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Skipped
Unit
Unit Tests Skipped

Event Timeline

imp retitled this revision from to Implement MD header filter for elf binaries..
imp updated this object.
imp edited the test plan for this revision. (Show Details)

looks good to me, and I tested it (ran an oabi on an eabi system) and it works.

sys/arm/arm/elf_machdep.c
128 ↗(On Diff #1110)

based on private correspondence, I'm going to make these printfs only on bootverbose for the commit. They are too vague (no binary name, no UID, prints just on the console not to the terminal, etc).

In D609#4, @imp wrote:

based on private correspondence, I'm going to make these printfs only on bootverbose for the commit. They are too vague (no binary name, no UID, prints just on the console not to the terminal, etc).

Traditionally, such messages use uprintf(). See e.g. amd64 machdep.uprintf_signal.

Generic question is, why can't you use the existing brand mechanism, which is supposed to handle exactly the problem you are trying to solve. That is, brandelf distinguishes between ABI variations for the ELF image of the single machine.

Existing branding mechanism isn't present. The problem is that OABI binaries can cause system crashes on EABI kernels. Requiring that OABI binaries be branded to prevent this is not acceptable. the existing brandelf mechanism assumes that the binaries are marked in some way differently, which we've not done (apart from the e_flags differences). If there's a way to use the branding stuff in the kernel to distinguish these types of binaries, then I'd use it. However, I see no way to run arbitrary code to validate a brand in the kernel. Requiring brandelf(1) to be run to make this work isn't on the table since this is a potential denial of service issue.

In D609#8, @imp wrote:

Existing branding mechanism isn't present. The problem is that OABI binaries can cause system crashes on EABI kernels. Requiring that OABI binaries be branded to prevent this is not acceptable. the existing brandelf mechanism assumes that the binaries are marked in some way differently, which we've not done (apart from the e_flags differences). If there's a way to use the branding stuff in the kernel to distinguish these types of binaries, then I'd use it. However, I see no way to run arbitrary code to validate a brand in the kernel. Requiring brandelf(1) to be run to make this work isn't on the table since this is a potential denial of service issue.

I did not mean brandelf(1), and did not suggested to add any additional marks to the ELF images when the already existing bits can provide the required information to the activator. Look at the get_brandinfo() function in the imgact_elf.c. It would need to be extended to handle flags, probably guided by some bit in bi->flags, but this is natural place for it.

I do not quite follow the statement about denial of service. Do you mean that just attempting to run OABI binary on EABI kernel causes panic or some other kernel misbehaviour ?

I did not mean brandelf(1), and did not suggested to add any additional marks to the ELF images when the already existing bits can provide the required information to the activator. Look at the get_brandinfo() function in the imgact_elf.c. It would need to be extended to handle flags, probably guided by some bit in bi->flags, but this is natural place for it.

I probably have to explain more. Reason to use brandelf (in kernel) is that it allows to properly handle different ABIs, which is the case there. Use of get_brandelf makes it possible to return proper sysent table for given image, which one day might allow to support both OABI and EABI, if needed.

We're trying to put a stake in the heart of OABI, not write a complex compat layer to support it forever. I'm not sure what kernel misbehavior Warner ran into, but since the ABIs require different stack alignment and different registers for args, I'm not surprised. I think just refusing to run wrong-ABI binaries during this transition period while we're phasing out the old ABI is fine. The world is not full of OABI executables available only in binary format that people are going to want to keep running (and if they do have such a thing, they can run them by building an OABI kernel, at least until fbsd 12).

In D609#10, @kostikbel wrote:

I did not mean brandelf(1), and did not suggested to add any additional marks to the ELF images when the already existing bits can provide the required information to the activator. Look at the get_brandinfo() function in the imgact_elf.c. It would need to be extended to handle flags, probably guided by some bit in bi->flags, but this is natural place for it.

I probably have to explain more. Reason to use brandelf (in kernel) is that it allows to properly handle different ABIs, which is the case there. Use of get_brandelf makes it possible to return proper sysent table for given image, which one day might allow to support both OABI and EABI, if needed.

OK. I understand now. I'll have to expand brandelf in the kernel to grok these things. While OABI on arm is utterly uninteresting to me and most of the community, I can see things like o32, n32 and n64 all being supported on MIPS via a mechanism like this might be interesting. I'll take a look to see the effort involved. Thanks for the pointer.

Let's give brandelf a shot...

Not sure how to update the summary, but it is now wrong. The real commit message looks like

Expand the elf brandelf infrastructure to give access to the whole ELF
header (Elf_Ehdr) to determine if a particular interpretor wants to
accept it or not. Use this mechanism to filter EABI arm on OABI arm
kernels, and vice versa. This method could also be used to implement
OABI on EABI arm kernels, if desired, or to allow a single mips kernel
to run o32, n32 and n64 binaries.

Yes, this is mostly how I imagined the implementation.

You do not need to pass Elf_Ehdr explicitely, the pointer to the image header is available as imgp->image_header.

Refine, per kib's suggestion.

imp updated this revision to Diff 1137.

Closed by commit rS270123 (authored by @imp).