This is the mail archive of the libc-alpha@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]

Re: Encoding page size in the ELF header


On 09/25/2015 03:29 PM, Florian Weimer wrote:
> On 09/25/2015 09:17 PM, Carlos O'Donell wrote:
>> On 09/25/2015 09:04 AM, Florian Weimer wrote:
>>> Not sure if this the right mailing list for this discussion.
>>>
>>> I think we should record the expected page size in the ELF header in
>>> some way.  It affects the behavior of the static linker, the dynamic
>>> linker, and even some applications.  (For example, an application might
>>> want to make a part of .data read-only after initialization, as a
>>> hardening measure.)
>>>
>>> What would be a good way to do that?
>>
>> Can't the application just call getpagesize(), and then use that to
>> decide how to make .data read-only?
> 
> The idea is to do something like this:
> 
> #define PAGE_SIZE 4096
> 
> union {
>   int critical_data;
>   char pad[PAGE_SIZE];
> } u __attribute__((aligned(PAGE_SIZE))) = {};
> 
> And then call mprotect(&u, PAGE_SIZE, PROT_READ) after initialization.
> This fails if the page size is suddenly 64 KiB.  I don't know how common
> this is, but it does make the binary dependent on page size (similar to
> RELRO, but we transparently disable RELRO if that happens).
> 
> Allocating a new page would mean that you must have a pointer to the
> page somewhere, which you need to protect in the same way, so it doesn't
> solve the problem.

The above makes the object dependent on the page size, and that object
might end up in a shared library or executable. The compiler, static linker,
and dynamic loader, have no real way to transform the above construct into
an annotation that indicates page size as a requirement though. The user
would have to provide some kind of indication via a manual annotation.

The manual annotation could be a GNU Object Attribute (see binutils), and
that could be used to generate static linker warnings when assembling
incompatible requirements.

There would be no glibc API until you say put that data into an allocatable
note section that could be used by such an API.

So if I had to do something like this and had sufficient use cases and
strong justification:

* Some kind of source level annotation.
* A new generic GNU Object Attribute for required page size.
* Rules in ld to merge this new attribute, wtih warnings, and errors.
  * Document it well with the rules.
* Plumb this through the tools for a while to teach users that this is
  an ABI issue.
* Have ld emit an allocatable note section with this information in it.
  * Consider a generic GNU Object Attributes note which can contain
    those present and future Object Attributes which are useful for
    the dynamic loader to parse (see discussions about how to do runtime
    ABI rejection).
* Modify glibc to load and understand the new note and reject invalid
  combinations.
* Modify ldconfig to have a new flag for page size such that incompatible
  objects in the cache can be ignored.

$0.02.

Cheers,
Carlos.


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