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: [RFC PATCH glibc 1/4] glibc: Perform rseq(2) registration at C startup and thread creation (v6)


----- On Jan 30, 2019, at 1:30 PM, Zack Weinberg zackw@panix.com wrote:

> On Wed, Jan 30, 2019 at 1:03 PM Mathieu Desnoyers
> <mathieu.desnoyers@efficios.com> wrote:
>> ----- On Jan 29, 2019, at 9:40 PM, Joseph Myers joseph@codesourcery.com wrote:
>> > On Tue, 29 Jan 2019, Mathieu Desnoyers wrote:
>> >
>> >> My thinking was to put the #error in the generic header, so architectures that
>> >> are not supported yet cannot build against rseq.h at all, so we don't end up
>> >> in a broken upgrade scenario. I'm open to alternative ways to do it though, as
>> >> long as we don't let not-yet-supported architectures build broken code.
>> >
>> > Any case with #error in installed glibc headers needs special-casing in
>> > check-installed-headers.sh (and, thus, such errors are to be discouraged).
>>
>> One alternative to #error would be to have an empty generic bits/rseq.h
>> that does _not_ define RSEQ_SIG. This way, it would be possible to
>> include sys/rseq.h from an architecture that does not define RSEQ_SIG
>> yet, but it would not cause any build failure. It's only if the code
>> try to use RSEQ_SIG that it would fail to compile because undefined.
> 
> You seem to be clinging to an approach where every architecture (that
> does support rseq(2), which is hopefully going to be all of them in
> the near future) has to define its own bits/rseq.h.  That's exactly
> the thing we don't want.
>
> Could you please explain why you believe it is more important to have
> build errors, in the short term, on architectures that don't support
> rseq(2) yet, than to improve the maintainability of the code in the
> long term?

I'm open to alternative solutions, provided that they don't lead to
glibc/kernel headers/kernel image upgrade scenarios that trigger
segmentation faults.

I just lack imagination in my search to find a solution that fulfills
the non-segfault-on-upgrade requirement without the burden of a
per-architecture bits/rseq.h to define RSEQ_SIG. If we find a solution
that fulfills both goals, I'm all for it.

Note that the alternative solution I hint at above does not use #error,
but rather just leaves RSEQ_SIG undefined for architectures that don't
support rseq yet. It still requires to have per-architecture bits/rseq.h,
which appears to be a maintainability burden though.

> 
>> > If this constant were in a uapi header, the glibc header could just
>> > include that - is the issue that it's not actually an interface between
>> > glibc and the kernel at all, but some kind of purely-userspace interface?
>>
>> The rseq uapi headers do not enforce the value of RSEQ_SIG. The role of the
>> kernel wrt signature is to receive it as sys_rseq argument, and then validate
>> that abort targets are prefixed with the signature before moving the
>> instruction pointer there.
> 
> In that case, is there any reason not to use the same value on _all_
> architectures?  Or maybe the same value on all 32-bit architectures,
> and another one on all 64-bit architectures?

As I stated earlier in the thread, we've encountered a few reasons that
justify overriding the RSEQ_SIG for specific architectures so far:

- Playing nice with objdump quirks by ensuring the signature is a
  valid instruction,
- Ensuring the architecture's speculative execution stops at the signature
  by making sure this is a specific trap instruction that is not found
  typically elsewhere in the code,
- Ensuring the chosen RSEQ_SIG does not happen to be a common byte sequence
  frequently present in the code segments of each target architecture.

> 
> (Based only on what you just said, I can imagine a reason: if this
> "signature" is baked into the code segments of programs, then it may
> need to be chosen for each architecture so it doesn't collide with the
> encoding of any valid machine instruction.  But then it would be fixed
> as part of the ABI and the kernel should know what it is, rather than
> having to be told during process startup.  It's quite possible I have
> misunderstood.  I have not been following this discussion closely.)

As you figured out, this signature needs to be baked into the application
and library code. However, the way rseq uapi is defined, the choice of
the signature is left to user-space. It is not defined by the kernel uapi.

The kernel just validates that signature, which is received as input
parameter to the rseq system call, and needs to be found before abort
target labels.

The main reason why we left the signature choice to user-space is that
we may have to eventually turn the "fixed" signature into a randomly
assigned one for hardened processes. We have to recall that the purpose
of this signature is to protect against control flow redirection by an
attacker through the rseq abort mechanism, so I prefer not to fix it
to a static value within the kernel uapi, and leave that decision to
user-space, which would allow randomizing it on process startup for
hardened processes in the future.

Thanks,

Mathieu

> 
> zw

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


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