> On Sep 2, 2020, at 7:53 PM, Yu, Yu-cheng <yu-cheng.yu@xxxxxxxxx> wrote: > > On 9/2/2020 4:50 PM, Andy Lutomirski wrote: >>>> On Sep 2, 2020, at 3:13 PM, Yu, Yu-cheng <yu-cheng.yu@xxxxxxxxx> wrote: >>> >>> On 9/2/2020 1:03 PM, Jann Horn wrote: >>>>> On Tue, Aug 25, 2020 at 2:30 AM Yu-cheng Yu <yu-cheng.yu@xxxxxxxxx> wrote: >>>>> Add REGSET_CET64/REGSET_CET32 to get/set CET MSRs: >>>>> >>>>> IA32_U_CET (user-mode CET settings) and >>>>> IA32_PL3_SSP (user-mode Shadow Stack) >>>> [...] >>>>> diff --git a/arch/x86/kernel/fpu/regset.c b/arch/x86/kernel/fpu/regset.c >>>> [...] >>>>> +int cetregs_get(struct task_struct *target, const struct user_regset *regset, >>>>> + struct membuf to) >>>>> +{ >>>>> + struct fpu *fpu = &target->thread.fpu; >>>>> + struct cet_user_state *cetregs; >>>>> + >>>>> + if (!boot_cpu_has(X86_FEATURE_SHSTK)) >>>>> + return -ENODEV; >>>>> + >>>>> + fpu__prepare_read(fpu); >>>>> + cetregs = get_xsave_addr(&fpu->state.xsave, XFEATURE_CET_USER); >>>>> + if (!cetregs) >>>>> + return -EFAULT; >>>> Can this branch ever be hit without a kernel bug? If yes, I think >>>> -EFAULT is probably a weird error code to choose here. If no, this >>>> should probably use WARN_ON(). Same thing in cetregs_set(). >>> >>> When a thread is not CET-enabled, its CET state does not exist. I looked at EFAULT, and it means "Bad address". Maybe this can be ENODEV, which means "No such device"? Having read the code, I’m unconvinced. It looks like a get_xsave_addr() failure means “state not saved; task sees INIT state”. So *maybe* it’s reasonable -ENODEV this, but I’m not really convinced. I tend to think we should return the actual INIT state and that we should permit writes and handle them correctly. Dave, what do you think? >>> >>> [...] >>> >>>>> @@ -1284,6 +1293,13 @@ static struct user_regset x86_32_regsets[] __ro_after_init = { >>>> [...] >>>>> + [REGSET_CET32] = { >>>>> + .core_note_type = NT_X86_CET, >>>>> + .n = sizeof(struct cet_user_state) / sizeof(u64), >>>>> + .size = sizeof(u64), .align = sizeof(u64), >>>>> + .active = cetregs_active, .regset_get = cetregs_get, >>>>> + .set = cetregs_set >>>>> + }, >>>>> }; >>>> Why are there different identifiers for 32-bit CET and 64-bit CET when >>>> they operate on the same structs and have the same handlers? If >>>> there's a good reason for that, the commit message should probably >>>> point that out. >>> >>> Yes, the reason for two regsets is that fill_note_info() does not expect any holes in a regsets. I will put this in the commit log. >>> >>> >> Perhaps we could fix that instead? > > As long as we understand the root cause, leaving it as-is may be OK. The regset mechanism’s interactions with compat are awful. Let’s please not make it worse. One CET regret is good; two is not good. > > I had a patch in the past, but did not follow up on it. > > https://lore.kernel.org/lkml/20180717162502.32274-1-yu-cheng.yu@xxxxxxxxx/ > > Yu-cheng