[RFC PATCH glibc] Linux: Use fixed rseq_len value for rseq registration
Mathieu Desnoyers
mathieu.desnoyers@efficios.com
Tue Jul 14 15:30:18 GMT 2020
----- On Jul 14, 2020, at 11:07 AM, Florian Weimer fweimer@redhat.com wrote:
> * Mathieu Desnoyers:
>
>> ----- On Jul 14, 2020, at 9:54 AM, Florian Weimer fweimer@redhat.com wrote:
>>
>>> * Christian Brauner:
>>>
>>>>> It works reliably as long as glibc only ever uses the minimum rseq size.
>>>>> And since glibc monopolizes the rseq registration, applications cannot
>>>>> register a larger area. So there is no way to make use of any future
>>>>> kernel extensions.
>>>>
>>>> But when you bump ABI in glibc you can switch to a new rseq size, no?
>>>
>>> We are expected to support interposers with their own definition
>>> __rseq_abi, which could be smaller.
>>
>> In this scenario, the interposers would have to follow the UAPI rules:
>> The size should at least cover the original struct rseq fields,
>> up to and including the flags field.
>
> If you use an ELF symbol, you also have to follow rules related to ELF
> linking (and C language requirements).
Indeed.
>
>> This just means glibc would internally abide by the same rules as the
>> other users if it want to use an extended rseq structure, and not expect
>> to be the only possible library defining the __rseq_abi symbol. If glibc
>> wants to use the extension feature, it would have to validate that the
>> RSEQ_TLS_FLAG_SIZE flag is set in the __rseq_abi.flags, and then validate
>> that __rseq_abi.kernel_size covers the feature it needs before accessing
>> the feature field.
>
> This still does not give us a way to perform the rseq registration with
> the size expected by an interposing definition of __rseq_abi.
Yes it does. The interposing definition of __rseq_abi would have the
__rseq_abi.flags RSEQ_TLS_FLAG_SIZE set, and would have
__rseq_abi.user_size = offsetof(struct rseq, end) (or something similar)
from its own perspective. That would be passed to the kernel on
registration. The "rseq_len" system call parameter would always stay
at value 32 though.
> I think we are looking at this from the wrong perspective. It's not
> userspace that is setting the size here, it's the kernel based on the
> features it supports. So the kernel should put the size into the
> auxiliary vector, and the registration should use that size. But that
> doesn't align well with the use of an ELF TLS symbol.
We have a few possible ways to do things here:
1) Kernel exports supported size, incompatible with ELF TLS symbol,
2) Userspace dictates supported size, compatible with ELF TLS symbol,
triggers failure if the kernel supports a smaller size,
3) Userspace lets kernel know how much space is available for struct rseq
(through user_size field), and the kernel lets user-space know how much
of that structure is being filled (through kernel_size field). This
would also be compatible with ELF TLS symbol AFAIU, and would allow
extending struct rseq.
Option (3) would allow us to have the speed gains that come with using a
TLS from the fast-path, while allowing extension of struct rseq.
Or is there anything in that scheme that breaks ELF rules or C language
requirements ?
Thanks,
Mathieu
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
More information about the Libc-alpha
mailing list