lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CALCETrXb5RRuAnKpU2_3Rac4F4tbv1Z+UHU6=QrYk-GCSLv4cw@mail.gmail.com>
Date:   Tue, 20 Mar 2018 15:04:49 +0000
From:   Andy Lutomirski <luto@...nel.org>
To:     "Chang S. Bae" <chang.seok.bae@...el.com>
Cc:     X86 ML <x86@...nel.org>, Andrew Lutomirski <luto@...nel.org>,
        Andi Kleen <ak@...ux.intel.com>,
        "H. Peter Anvin" <hpa@...or.com>,
        "Metzger, Markus T" <markus.t.metzger@...el.com>,
        Tony Luck <tony.luck@...el.com>,
        "Ravi V. Shankar" <ravi.v.shankar@...el.com>,
        LKML <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH 14/15] x86/fsgsbase/64: Support legacy behavior when FS/GS
 updated by ptracer

On Mon, Mar 19, 2018 at 5:49 PM, Chang S. Bae <chang.seok.bae@...el.com> wrote:
> When FSGSBASE enabled, ptracer's FS/GS selector update
> fetches FS/GS base from GDT/LDT. This emulation of FS/GS
> segment loading provides backward compatibility for the
> legacy ptracers.
>
> When ptracer sets FS/GS selector, its base is going to be
> (accordingly) reloaded as the tracee resumes. This is without
> FSGSBASE. With FSGSBASE, FS/GS base is preserved regardless
> of its selector. Thus, emulating FS/GS load in ptrace is
> requested to keep compatible with what has been with FS/GS
> setting.
>
> Additionally, whenever a new base value is written, the
> FSGSBASE-enabled kernel allows the tracee effectively carry
> on. This also means that when both selector and base are
> changed, the base is not fetched from GDT/LDT, but
> preserved as given.
>

>
> Suggested-by: Markus T. Metzger <markus.t.metzger@...el.com>
> Suggested-by: H. Peter Anvin <hpa@...or.com>

I've also suggested something like this myself, but this approach is
far more complicated than the older approach.  Was there something
that the old approach would break?  If so, what?

> +               /*
> +                * %fs setting goes to reload its base, when tracee
> +                * resumes without FSGSBASE (legacy). Here with FSGSBASE
> +                * FS base is (manually) fetched from GDT/LDT when needed.
> +                */
> +               else if (static_cpu_has(X86_FEATURE_FSGSBASE) &&
> +                        (value != 0) && (task->thread.fsindex != value))
> +                       task->thread.fsbase = task_seg_base(task, value);

The comment above should explain why you're checking this particular
condition.  I find the fsindex != value check to be *very* surprising.
On a real CPU, writing some nonzero value to %fs does the same thing
regardless of what the old value of %fs was.

> +               case USER_REGS_OFFSET(fs):
> +                       if (fs_fully_covered &&

This is_fully_covered thing is IMO overcomplicated.  Why not just make
a separate helper set_fsgs_index_and_base() and have putregs() call it
when both are set at once?

> +                           static_cpu_has(X86_FEATURE_FSGSBASE)) {
> +                               if (invalid_selector(*v))
> +                                       return -EIO;
> +                               /*
> +                                * Set the flag to fetch fsbase from GDT/LDT
> +                                * with FSGSBASE
> +                                */
> +                               fs_updated = (*v != 0) &&
> +                                       (child->thread.fsindex != *v);

Same here.  Why do you care if fs was changed?

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ