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]
Date:   Fri, 4 Nov 2022 19:38:48 +0000
From:   Sean Christopherson <seanjc@...gle.com>
To:     Dmitry Vyukov <dvyukov@...gle.com>
Cc:     syzbot <syzbot+ffb4f000dc2872c93f62@...kaller.appspotmail.com>,
        bp@...en8.de, brgerst@...il.com, dave.hansen@...ux.intel.com,
        hpa@...or.com, kirill@...temov.name, linux-kernel@...r.kernel.org,
        mingo@...hat.com, peterz@...radead.org,
        syzkaller-bugs@...glegroups.com, tglx@...utronix.de,
        thomas.lendacky@....com, x86@...nel.org
Subject: Re: [syzbot] BUG: unable to handle kernel paging request in get_desc

On Fri, Nov 04, 2022, Dmitry Vyukov wrote:
> On Fri, 4 Nov 2022 at 11:41, Sean Christopherson <seanjc@...gle.com> wrote:
> >
> > On Fri, Nov 04, 2022, Dmitry Vyukov wrote:
> > > On Fri, 4 Nov 2022 at 10:39, 'Sean Christopherson' via syzkaller-bugs
> > > <syzkaller-bugs@...glegroups.com> wrote:
> > > Can it be out-of-bounds or something?
> >
> > The lookup is on CS.base (I trimmed the stack in my first reply) as part of the
> > IOPL emulation to see if userspace is attempting CLI or STI, so it's not related
> > to the sigframe.
> >
> >   insn_get_seg_base arch/x86/lib/insn-eval.c:725 [inline]
> >   insn_get_effective_ip+0x187/0x1f0 arch/x86/lib/insn-eval.c:1476
> >   fixup_iopl_exception+0xd0/0x190 arch/x86/kernel/traps.c:627
> >   __exc_general_protection arch/x86/kernel/traps.c:752 [inline]
> >   exc_general_protection+0x176/0x210 arch/x86/kernel/traps.c:728
> >   asm_exc_general_protection+0x22/0x30 arch/x86/include/asm/idtentry.h:564
> >  RIP: 0003:0x7f250f3abf8c
> >
> > It does look like some form out out-of-bounds selector though.  The offset in the
> > splat suggests CS.sel is something way above __USER_CS, which would explain why
> > insn_get_effective_ip() is doing a lookup in the first place (CS.base is assumed
> > to be 0 if userspace is in 64-bit mode, user_64bit_mode() is true if CS == __USER_CS)),
> > I just can't figure out how that tiny reproducer is getting a bad CS.  And the above
> > RIP strongly suggests userspace is indeed in 64-bit mode.
> 
> My understanding is that rt_sigreturn() restores complete user context
> from the info stored on the stack.
> Normally signal delivery will store that info on the stack first. But
> in this case there is no signal delivery, so rt_sigreturn() reads
> complete garbage from the stack and restores it into the context. I
> assume this can setup any non-sense CS and maybe even pretend this is
> not normal x86_64 mode (?).

Ha!  Indeed, shoving a sigcontext onto the stack that's valid enough to pass
basic checks but throws in a bad CS does the trick.

int main(void)
{
  struct sigcontext regs;
  
  syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  syscall(__NR_iopl, 3);

  memset(&regs, 0, sizeof(regs));
  regs.cs = 0x1d0;
  syscall(__NR_rt_sigreturn);
  return 0;
}

Same root cause, different fix.  I'll post officially in a bit.

diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c
index dff9001e5e12..4a6440461c10 100644
--- a/arch/x86/mm/cpu_entry_area.c
+++ b/arch/x86/mm/cpu_entry_area.c
@@ -195,7 +195,7 @@ static void __init setup_cpu_entry_area(unsigned int cpu)
        pgprot_t tss_prot = PAGE_KERNEL;
 #endif
 
-       cea_set_pte(&cea->gdt, get_cpu_gdt_paddr(cpu), gdt_prot);
+       cea_map_percpu_pages(&cea->gdt, get_cpu_gdt_rw(cpu), 1, gdt_prot);
 
        cea_map_percpu_pages(&cea->entry_stack_page,
                             per_cpu_ptr(&entry_stack_storage, cpu), 1,

The other bare use of cea_set_pte() in percpu_setup_debug_store() also appears
suspect.  The base debug_store area is mapped, but the buffers are not.

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ