> On Jun 19, 2018, at 10:07 AM, Kees Cook <keescook@xxxxxxxxxxxx> wrote: > >> On Tue, Jun 19, 2018 at 9:59 AM, Yu-cheng Yu <yu-cheng.yu@xxxxxxxxx> wrote: >>> On Tue, 2018-06-19 at 09:44 -0700, Kees Cook wrote: >>> On Tue, Jun 19, 2018 at 7:50 AM, Andy Lutomirski <luto@xxxxxxxxxxxxxx >>>> wrote: >>>> >>>>> >>>>> On Jun 18, 2018, at 5:52 PM, Kees Cook <keescook@xxxxxxxxxxxx> >>>>> wrote: >>>>> Following Linus's request for "slow introduction" of new security >>>>> features, likely the best approach is to default to "relaxed" >>>>> (with a >>>>> warning about down-grades), and allow distros/end-users to pick >>>>> "forced" if they know their libraries are all CET-enabled. >>>> I still don’t get what “relaxed” is for. I think the right design >>>> is: >>>> >>>> Processes start with CET on or off depending on the ELF note, but >>>> they start with CET unlocked no matter what. They can freely switch >>>> CET on and off (subject to being clever enough not to crash if they >>>> turn it on and then return right off the end of the shadow stack) >>>> until they call ARCH_CET_LOCK. >>> I'm fine with this. I'd expect modern loaders to just turn on CET and >>> ARCH_CET_LOCK immediately and be done with it. :P >> >> This is the current implementation. If the loader has CET in its ELF >> header, it is executed with CET on. The loader will turn off CET if >> the application being loaded does not support it (in the ELF header). >> The loader calls ARCH_CET_LOCK before passing to the application. But >> how do we handle dlopen? > > I thought CET_LOCK would not get set in "relaxed" mode, due to dlopen > usage, and that would be the WARN case. People without dlopen concerns > can boot with "enforced" mode? If a system builder knows there are no > legacy dlopens they build with enforced enabled, etc. I think we’re getting ahead of ourselves. dlopen() of a non-CET-aware library in a CET process is distinctly non-trivial, especially in a multithreaded process. I think getting it right will require *userspace* support. It certainly needs ld.so to issue to arch_prctl at a bare minimum. So I see no point to a kernel-supplied “relaxed” mode. I think there may be demand for a ld.so relaxed mode, but it will have nothing to do with boot options. It’s potentially helpful to add an arch_prctl that turns CET off for all threads, but only if unlocked. It would obviously be one hell of a gadget. > >>>> Ptrace gets new APIs to turn CET on and off and to lock and unlock >>>> it. If an attacker finds a “ptrace me and turn off CET” gadget, >>>> then they might as well just do “ptrace me and write shell code” >>>> instead. It’s basically the same gadget. Keep in mind that the >>>> actual sequence of syscalls to do this is incredibly complicated. >>> Right -- if an attacker can control ptrace of the target, we're way >>> past CET. The only concern I have, though, is taking advantage of >>> expected ptracing. For example: browsers tend to have crash handlers >>> that launch a ptracer. If ptracing disabled CET for all threads, this >>> won't by safe: an attacker just gains control in two threads, crashes >>> one to get the ptracer to attach, which disables CET in the other >>> thread and the attacker continues ROP as normal. As long as the >>> ptrace >>> disabling is thread-specific, I think this will be okay. >> >> If ptrace can turn CET on/off and it is thread-specific, do we still >> need ptrace lock/unlock? Let me clarify. I don’t think ptrace() should have any automatic effect on CET. I think there should be an explicit way to ask ptrace to twiddle CET, and it should probably apply per thread. > > Does it provide anything beyond what PR_DUMPABLE does? What do you mean? > > -Kees > > -- > Kees Cook > Pixel Security