Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <8f47b969-c2a5-54df-5bb6-541fcb1fd5df@dereferenced.org>
Date: Sat, 17 Jul 2021 20:40:52 -0500 (CDT)
From: Ariadne Conill <ariadne@...eferenced.org>
To: musl@...ts.openwall.com
cc: Ariadne Conill <ariadne@...eferenced.org>, Timo Teras <timo.teras@....fi>
Subject: Re: option to enable eh_frame

Hello,

On Sat, 17 Jul 2021, Rich Felker wrote:

> On Sat, Jul 17, 2021 at 02:52:48PM -0500, Ariadne Conill wrote:
>> Hello,
>>
>> On Sat, 17 Jul 2021, Rich Felker wrote:
>>
>>> On Sat, Jul 17, 2021 at 06:40:10PM +0300, Timo Teras wrote:
>>>> On Sat, 17 Jul 2021 09:25:44 -0400
>>>> Rich Felker <dalias@...c.org> wrote:
>>>>
>>>>>> Please add in any reasons I may have missed. I would like to have
>>>>>> your complete list of reasons why to remove .eh_frame. So far it
>>>>>> has been coming out in pieces. I'd like constructive discussion if
>>>>>> some of these items could be implemented stronger in other means
>>>>>> than removing ..eh_frame.
>>>>>
>>>>> You're coming at it from the wrong direction. For new, nonstandard
>>>>> functionality requests, musl has a well established process of
>>>>> criteria for inclusion and exclusion, based on invasiveness (this is
>>>>> not just a matter of code change size, but of constraints it imposes),
>>>>> size, how often the lack of the functionality impacts portable or
>>>>> important FOSS programs users want to run on musl, and whether there
>>>>> are other ways the applications that want it could achieve what they
>>>>> want. In this case, all of those criteria indicate against doing it.
>>>>
>>>> Just to be on record, musl used to include .eh_frame until 2012 and
>>>> commit b439c051c7eee4eb4b93fc382f993aa6305ce530 or musl 0.9.5. So back
>>>> then existing "contract" was broken. If this discussion was done then,
>>>> this would be the other angle: why to break something that is working.
>>>
>>> You're still missing the point. Having it there when it just happened
>>> to be (and likewise on archs where there's some weird non-DWARF unwind
>>> table that we haven't opted out of) is not a contract to support it;
>>> it's an artifact of the toolchain. *Explicitly making a change for the
>>> purpose of adding it*, with no other plausible purpose, is such a
>>> contract.
>>>
>>> By the way, I think you're slightly wrong on the history. Prior to
>>> that commit, unwind info was already omitted unless debugging was
>>> enabled; this was because I was not aware that GCC would emit it in
>>> .debug_frame if needed.
>>>
>>>>>> But fundamentally I think if we ship .debug_frame, all people
>>>>>> wanting do backtrace() and the silly stuff, will just enable
>>>>>> .debug_frame support in their code and still do the silly stuff in
>>>>>> worse way, than if .eh_frame was enabled. Since technically they
>>>>>> are the same, even if the intended use case is different. As seen
>>>>>> libunwind does have --enable-debug-frame.
>>>>>
>>>>> They might, but then they're clearly using a debugging interface that
>>>>> only works when debug files are available (or if you include this in
>>>>> main libc.so, when libc.so is not stripped).
>>>>
>>>> But how is this different from the "contract" viewpoint?
>>>>
>>>> You are agreeable to have .debug_frame by default in the main DSO. And
>>>> if we make musl have .debug_frame, and build libunwind with
>>>> --enable-debug-frame, the user gets quite similar "contract" experience
>>>> as with .eh_frame. But just worse than having .eh_frame, because for the
>>>> unwinder to be able to use .debug_frame it needs to do more silly
>>>> things.
>>>
>>> It needs to do "silly" things which explicitly break if debug info is
>>> stripped, making it clear that this is not functionality of the libc
>>> but (strippable) debugging metadata that can't be relied on.
>>>
>>>> Users don't care if it's .debug_frame or .eh_frame as long as the higher
>>>> level functionality works. And it gives same "de facto contract"
>>>> experience.
>>>>
>>>> Sorry for being "stupid" here, but I'm trying to understand your
>>>> viewpoint. So far it's sounding like:
>>>> - same things can be achieved by doing X or Y
>>>> - you argue X is evil and breaking contract, but Y is ok
>>>> - on system/user level the "contract" or "experience" is same
>>>>   regardless of doing X or Y
>>>>
>>>> Basically I'm trying to understand why do you consider .eh_frame so
>>>> much more important "contract" than .debug_frame?
>>>
>>> Because .eh_frame is part of the loaded program segment that ELF
>>> semantics define as being available to the runtime (which is what
>>> makes it non-strippable), and .debug_frame is not.
>>
>> In this case, wouldn't we want to emit .eh_frame for libc.so?  If
>> not, why?  If it's supposed to be available, that seems like a more
>> compelling argument for including it, not excluding it.
>
> I'm not sure who "we" is here and what perspective it's supposed to be
> from.

"We" being in the general sense: if there are tools expecting .eh_frame to 
be present, as part of the ELF specification, then would it not be 
desirable to have it?

> I thought I'd explained the difference. Having something as part
> of the loadable program segment means it's always available, not
> strippable or missing if debug packages are not installed. Having it
> be in a non-load section (not segment) means it's metadata about the
> binary for tooling (e.g. debugger) usage, to be accessed by reading
> the file(s) not runtime data structures mapped in memory. From my
> perspective, the reason for it to be the latter is to reflect that
> this is debug info available only in a debug environment, not part of
> musl's runtime interfaces.

This is not Alpine's position per se: we would like basic debugging to 
work in any environment.  The splitting of debuginfo to -dbg packages is 
intended to reduce image size only.  That decision is not considered by us 
to be a security-impacting decision, even if that is a side effect (and I 
personally consider it not to be a security feature at all, as an attacker 
can simply recreate their attack in a debug environment).

Ultimately, the question is one of how to enable basic debugging features 
without having debuginfo present.  Or in other words, we would like basic 
debugging information, but not necessarily DWARF sections as part of the 
runtime package.

In my opinion -- the solution is to modify the strip functionality in 
abuild to include .debug_frame, and then adjust our libunwind and other 
programs to make use of .debug_frame.  This gives us the basic debugging 
functionality, while also complying with the wishes of upstream musl.

(As a side note, I really do not want to get into a position where Alpine 
is shipping a defacto fork of musl, we already did this with uClibc and it 
created more problems than solutions.  Working with upstream implies a 
social contract that we will abide by upstream's wishes whenever 
reasonable, and I do not see any reason why preferring .debug_frame over 
.eh_frame to solve this problem is an unreasonable request.)

Ariadne

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.