Re: [PATCH v3] ELF: document some de-facto PT_* ABI quirks

From: Alexey Dobriyan
Date: Mon Dec 11 2023 - 11:26:45 EST


On Sun, Dec 10, 2023 at 04:58:50PM -0600, Eric W. Biederman wrote:
> Alexey Dobriyan <adobriyan@xxxxxxxxx> writes:
>
> > On Thu, Dec 07, 2023 at 09:03:45AM -0600, Eric W. Biederman wrote:

> >> Quite frankly if we are going to do something with this my sense is that
> >> we should fail the execve with a clear error code as userspace should
> >> not be doing this, and accepting a malformed executable will hide
> >> errors, and perhaps hide someone causing problems.
> >
> > Maybe do it for PT_GNU_PROPERTY which is relatively new.
> >
> >> I really don't think having multiple copies of these headers with
> >> different values is something we should encourage.
> >>
> >> It looks like -ELIBBAD is the documented way to fail and report
> >> a bad file format.
> >
> > It is obvious you don't know how much will break.
>
> My assumption is frankly that nothing will break. My quick examination
> of userspace binaries suggests that nothing is silly enough to duplicate
> such headers.

Ha! Non-overlapping PT_LOAD segments is reasonable requirement (why would
you have them?) but it was reverted.

> Do you know of a binaries in userspace that duplicate these headers?
>
> Without a documented ordering arguably anything that results in
> these headers being duplicated is already buggy, and broken.
>
> I can think of no use for duplicating these headers other than
> as some kind of gadget in an exploit. I don't see how such
> a gadget would be useful currently.
>
> >
> >> For PT_GNU_PROPTERTY perhaps we should accept it anywhere, instead of
> >> silently ignoring it depending upon it's location?
> >>
> >> I thinking change the code to talk one pass through the program headers
> >> to identify the interesting headers, and then with the interesting
> >> headers all identified we go do something with them.
> >>
> >> Anyway just my opinion, but that is what it feels like to me.
> >
> > _Not_ checking for duplicates will result in the simplest and fastest exec.
> > which is what current code does.
>
> Given that I/O is involved taking a pre-pass through the headers is
> in the noise, and it might even make the code faster as it would
> prime the code for the other passes.

Branches will evict other branches from branch predictor.
And it is always more code.

ELF is very rigid format. E.g segment headers can overlap everything
else and it is not a problem. Overmapped PT_LOAD segments aren't
a problem too (for the kernel).

These things should have been rejected from the very beginning.

I'd even argue kernel rejects too much:

elf_entry = e_entry;
if (BAD_ADDR(elf_entry)) {
retval = -EINVAL;
goto out_free_dentry;
}

Why even check? If e_entry is bad than process will segfault and that's it.

elf_ppnt->p_filesz > elf_ppnt->p_memsz

Again, why check, just map the minimum.

> The fastest of course would be to have the elf loader only look
> at the first of any of these headers.
>
> What got you wanting to document how we handle duplicates?

I read ELF code too much and noticed that loops are slightly different,
that's all.