Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
 <DS4PR01MB9944536EA4B0C85E39B0E83D61EA692@DS4PR01MB994453.prod.exchangelabs.com>
Date: Tue, 3 Nov 2026 01:53:13 +0000
From: "Puranam, Ananta Srikar" <srikar.puranam@....edu>
To: Rich Felker <dalias@...c.org>
CC: "musl@...ts.openwall.com" <musl@...ts.openwall.com>,
        "West, Emily"
	<emily.west1@....edu>,
        "Priya, Swarn" <swarn.priya@....edu>, "Gao, Peng"
	<penggao@...edu>,
        "Ammanaghatta Shivakumar, Basavesh"
	<basavesh.shivakumar@....edu>
Subject: Re: ldso: map_library does not validate e_phentsize

Hi Rich,

Thanks for explaining. That helps. I talked it over with my advisor Dr. Basavesh,
and we agree it's your call how much validation the loader should do.
We don't want to send you reports you consider out of scope, so we'll
hold back the rest of our malformed-ELF findings: bad header fields,
dynamic table pointers or sizes that point out of range, and so on.

A few of our findings aren't about corrupted files. They come from
ordinary inputs:

- A shared library with a __thread variable aligned to more than the
  page size (for example aligned(8192)) gets a TLS block that is
  misaligned by a multiple of the page size. The values are right,
  but the alignment the program asked for is silently lost. glibc
  lays out the same files correctly.

- dlopen of a library built with -ftls-model=initial-exec fails as it
  should, but the "initial-exec TLS resolves to dynamic definition"
  error formats a name that is never set for relocations with no
  symbol. On 1.2.5 this crashes inside dlopen. On master the message
  shows an empty or unrelated symbol name. golang/go#54805 looks like
  the same thing.

- When ldso is invoked directly (/lib/ld-musl-*.so.1 ./prog), the
  program starts with sp % 16 == 8. musl's own crt1 re-aligns the
  stack, so C programs are fine. An entry point that uses the stack
  before re-aligning takes an alignment fault on aarch64.

Would reports like these be welcome? If so, I'll send them together
in one email rather than as separate threads. If not, let us know and
we'll leave it there.

Thanks again for your time,
Srikar
________________________________________
From: Rich Felker <dalias@...c.org>
Sent: Monday, November 2, 2026 5:29 PM
To: Puranam, Ananta Srikar <a.puranam@....edu>
Cc: musl@...ts.openwall.com <musl@...ts.openwall.com>; West, Emily <emily.west1@....edu>; Priya, Swarn <swarn.priya@....edu>; Gao, Peng <penggao@...edu>; Ammanaghatta Shivakumar, Basavesh <basavesh.shivakumar@....edu>
Subject: Re: [musl] ldso: map_library does not validate e_phentsize
 
[EXTERNAL EMAIL]

On Mon, Nov 02, 2026 at 11:48:32PM +0000, Puranam, Ananta Srikar wrote:
> Hi,
>
> I'm Ananta Srikar Puranam, a PhD student at Washington State
> University. I'm reporting this bug on behalf of my team: Emily West,
> Dr. Swarn Priya, Dr. Peng Gao and Dr. Basavesh Ammanaghatta
> Shivakumar.
>
> map_library in ldso/dynlink.c never checks e_phentsize against
> sizeof(Phdr). It sizes the header read with e_phentsize * e_phnum
> (line 711 at 7813e911) and steps through the table by e_phentsize
> (line 727, also 764 and 825), but reads every entry as a full Phdr.
>
> With e_phentsize set to 28 on x86_64, musl reads e_phnum records 28
> bytes apart: only the first half of the real table, interleaved with
> bogus records that start in the middle of real ones. If PT_TLS is in
> the unread half, dlopen succeeds without TLS, dlsym of a TLS symbol
> returns NULL without setting dlerror, and the library crashes when
> it touches its own TLS. If PT_LOAD or PT_DYNAMIC is in the unread
> half, dlopen fails with "Exec format error".
>
> glibc rejects the same file with "ELF file's phentsize not the
> expected size". Rejecting it with ENOEXEC when e_phentsize !=
> sizeof(Phdr) seems like the expected behavior here.

There is an unbounded surface of things that could be validated when
loading programs/libraries, but no clear benefit from doing so.
Whatever is being loaded is necessarily something you're trusting; its
ctors execute in the same privilege domain as the program. Thus, we
have generally not opted to do validation except in cases where the
tooling could produce something that might appear to work but have
subtle/silent breakage.

If there is going to be any further validation, it should be based on
a goal with a purpose -- for example, if we wanted to guarantee safety
of running ldd on untrusted files. This is tractable, but would be a
big project, and I don't really feel comfortable making such a promise
of safety, so I'd probably rather not create the illusion of it.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.