[PATCH v8 0/8] Add support for memory sealing

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Thu Feb 6 14:16:57 GMT 2025



On 03/02/25 17:04, Adhemerval Zanella Netto wrote:
> 
> 
> On 03/02/25 16:40, Florian Weimer wrote:
>> * Adhemerval Zanella Netto:
>>
>>>> CRIU needs to be able to unmap everything that was initially loaded by
>>>> the kernel and glibc.  This will stop working if we use mseal for glibc
>>>> itself.
>>>
>>> So in this case the easiest way it to filter of mseal (with seccomp or
>>> something related) and disable sealing.  I don't have a easy solution.
>>
>> Please test with CRIU and trace and find a way to make them work again
>> if they are broken.
> 
> I don't see a way to make CRIU work where it is orthogonal of the idea of
> immutability of memory sealing.  But I don't have much knowledge of how CRIU
> work internally, maybe someone more well versed in this project could help us
> out here.
> 
>>
>>>>> A dynamic tag would add support only for ET_DYN, where a GNU attribute
>>>>> allows for ET_EXEC as well (similar to recent hardening mechanism like
>>>>> BTI, GCS, etc.).
>>>>
>>>> We don't need the compatibility indicator on static executables because
>>>> incompatible static binaries won't have the PT_* header that requests
>>>> sealing.
>>>
>>> But we will still need to mark the ET_EXEC as opt-in for sealing.  A dynamic
>>> tag will be only enabled for ET_DYN.
>>
>> If the PT_* address ranges are present, the binary opts in to sealing.
> 
> But you still need a opt-in mark to be memory sealed, that's the gnu attribute
> marking.  A dynamic tag would not be present on ET_EXEC (although with PIE
> being more common it might not be that common), so we still need something
> else to mark the binary as opt-in to memory sealing.
> 
>>
>>> Is this allocated dynamic during process execution of defined during build?
>>> Can't you put this on relro segment, with a constructor to do any required
>>> initialization?
>>
>> Constructors currently run after RELRO has been applied.
> 
> Right, so is this some metadata in .data that is initialized after or during
> process execution?  If so, I think for this case it would be better to have
> something like a special section, like ".gnu.mseal"; where the idea of
> adding sealing range makes sense.  But again, I think this is different
> proposal and not really a blocker for this hardening.
> 

Ok, I thought more about it and I still not sure if a range base is the ideal
solution for this.  The whole idea of memory sealing if the assumption of that
all PT_LOAD of the binary should be *immutable* after process startup; meaning 
that if the program intends to change anything it would be better to be explicit 
mark as so.

The OpenBSD memory sealing supported was added as default security hardening
(no opt-out, different that this proposal) and later they found the need to add
PT_OPENBSD_MUTABLE to handle some malloc metadata similar to the problem you bring.

I think we can use a add a PT_GNU_SEAL instead with the expected range for sealing; 
so in the future a binary can adjust the range if required.  I think it is somewhat 
more complex, since we will need to some extra constraints like the VirtAddr should
be page-aligned, there should be no gap, the end should be in a allocated VMA.  There
is also the extra complication that we will need to use a different strategy for 
non-contiguous mapping (as done by the kernel in some cases); which adds even more 
complexity.

Another solution is once we do require a way to mark the memory as mutable
(so loader will remove them during sealing) to add a PT_GNU_NOSEAL similar to
what OpenBSD does.  It makes more sense to me because if binary does require,
it knows exactly the range it requires to be mutable by marking it on a different
section (.gnu.mutable or something like it).


More information about the Libc-alpha mailing list