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] [day] [month] [year] [list]
Message-ID: <CALCETrWXKUPbECLcZp=0Ja5Veqni3=tB1WAM=B67VcuqOyihhg@mail.gmail.com>
Date:   Wed, 24 Jun 2020 17:54:44 -0700
From:   Andy Lutomirski <luto@...nel.org>
To:     Andy Lutomirski <luto@...nel.org>
Cc:     X86 ML <x86@...nel.org>, LKML <linux-kernel@...r.kernel.org>,
        Sasha Levin <sashal@...nel.org>
Subject: Re: [PATCH 3/3] x86/ptrace: Fix 32-bit PTRACE_SETREGS vs fsbase and gsbase

On Wed, Jun 24, 2020 at 3:50 PM Andy Lutomirski <luto@...nel.org> wrote:
>
> Debuggers expect that doing PTRACE_GETREGS, then poking at a tracee
> and maybe letting it run for a while, then doing PTRACE_SETREGS will
> put the tracee back where it was.  In the specific case of a 32-bit
> tracer and tracee, the PTRACE_GETREGS/SETREGS data structure doesn't
> have fs_base or gs_base fields, so FSBASE and GSBASE fields are
> never stored anywhere.  Everything used to still work because
> nonzero FS or GS would result full reloads of the segment registers
> when the tracee resumes, and the bases associated with FS==0 or
> GS==0 are irrelevant to 32-bit code.
>
> Adding FSGSBASE support broke this: when FSGSBASE is enabled, FSBASE
> and GSBASE are now restored independently of FS and GS for all tasks
> when context-switched in.  This means that, if a 32-bit tracer
> restores a previous state using PTRACE_SETREGS but the tracee's
> pre-restore and post-restore bases don't match, then the tracee is
> resumed with the wrong base.
>
> Fix it by explicitly loading the base when a 32-bit tracer pokes FS
> or GS on a 64-bit kernel.

> diff --git a/tools/testing/selftests/x86/fsgsbase_restore.c b/tools/testing/selftests/x86/fsgsbase_restore.c
> new file mode 100644
> index 000000000000..70502a708dee
> --- /dev/null
> +++ b/tools/testing/selftests/x86/fsgsbase_restore.c

> +       if (false && syscall(SYS_modify_ldt, 1, &desc, sizeof(desc)) == 0) {

Whoops.  That 'false &&' shouldn't be there.  Want a v2?

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ