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: <20250217183827.41da5f52@pumpkin>
Date: Mon, 17 Feb 2025 18:38:27 +0000
From: David Laight <david.laight.linux@...il.com>
To: Peter Zijlstra <peterz@...radead.org>
Cc: Kees Cook <kees@...nel.org>, Andrew Cooper <andrew.cooper3@...rix.com>,
 jannh@...gle.com, jmill@....edu, joao@...rdrivepizza.com,
 linux-hardening@...r.kernel.org, linux-kernel@...r.kernel.org,
 luto@...nel.org, samitolvanen@...gle.com, scott.d.constable@...el.com,
 x86@...nel.org
Subject: Re: [RFC] Circumventing FineIBT Via Entrypoints

On Mon, 17 Feb 2025 14:13:21 +0100
Peter Zijlstra <peterz@...radead.org> wrote:

> On Mon, Feb 17, 2025 at 01:06:29PM +0000, David Laight wrote:
> > On Sat, 15 Feb 2025 22:07:29 +0100
> > Peter Zijlstra <peterz@...radead.org> wrote:
> >   
> > > On Fri, Feb 14, 2025 at 10:57:51AM +0100, Peter Zijlstra wrote:  
> > > > On Thu, Feb 13, 2025 at 12:53:28PM -0800, Kees Cook wrote:
> > > >     
> > > > > Right, the "if they can control a function pointer" is the part I'm
> > > > > focusing on. This attack depends on making an indirect call with a
> > > > > controlled pointer. Non-FineIBT CFI will protect against that step,
> > > > > so I think this is only an issue for IBT-only and FineIBT, but not CFI
> > > > > nor CFI+IBT.    
> > > > 
> > > > Yes, the whole caller side validation should stop this.    
> > > 
> > > And I think we can retro-fit that in FineIBT. Notably the current call
> > > sites look like:
> > > 
> > > 0000000000000060 <fineibt_caller>:
> > >   60:   41 ba 78 56 34 12       mov    $0x12345678,%r10d
> > >   66:   49 83 eb 10             sub    $0x10,%r11
> > >   6a:   0f 1f 40 00             nopl   0x0(%rax)
> > >   6e:   41 ff d3                call   *%r11
> > >   71:   0f 1f 00                nopl   (%rax)  
> > 
> > I tried building a fineibt kernel (without LTO) and that isn't what I
> > see in the object files.
> > (I not trying to run it, just do some analysis.)
> > While the call targets have a 16 byte preamble it is all nops apart
> > from a final 'mov $hash,%rax'.
> > The call site loads $-hash and adds -4(target) and checks for zero.
> > It is too small to be patchable into the above.  
> 
> Right after that comes the retpoline site, which is another 6 bytes
> (assuming you have indirect-branch-cs-prefix, which all kCFI enabled
> compilers should have).

I'm building with clang 18.1.18 - should be new enough.
I may not have retpolines enabled, a typical call site is (from vmlinux.o):
    3628:       48 89 c6                mov    %rax,%rsi
    362b:       41 ba 83 c5 2c af       mov    $0xaf2cc583,%r10d
    3631:       44 03 51 fc             add    -0x4(%rcx),%r10d
    3635:       74 02                   je     3639 <vc_handle_exitcode+0x739>
    3637:       0f 0b                   ud2
    3639:       ff d1                   call   *%rcx
    363b:       4c 89 f6                mov    %r14,%rsi

That one has three targets, one is:
000000000008a5c0 <__cfi_kvm_sev_es_hcall_prepare>:
   8a5c0:       90                      nop
   8a5c1:       90                      nop
   8a5c2:       90                      nop    
   8a5c3:       90                      nop    
   8a5c4:       90                      nop    
   8a5c5:       90                      nop    
   8a5c6:       90                      nop    
   8a5c7:       90                      nop    
   8a5c8:       90                      nop    
   8a5c9:       90                      nop    
   8a5ca:       90                      nop
   8a5cb:       b8 7d 3a d3 50          mov    $0x50d33a7d,%eax
    
000000000008a5d0 <kvm_sev_es_hcall_prepare>:
   8a5d0:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1) 8a5d1: R_X86_64_NONE    __fentry__-0x4
   8a5d5:       48 8b 46 28             mov    0x28(%rsi),%rax

I think that if I had endbra enabled objtool would remove them from non-exported
functions whose address isn't taken.
But none of the 'mov $hash,%eax' get removed - and I think they should suffer
the same fate.

I'm not sure why I don't have endbra though.
I did remove a lot of the mitigations from the config I copied to add the caller
side fineibt (I think) hash checks.
After all this is a local system I want to run fast, not a semi-public one
someone might try to hack.

> You need to go read arch/x86/kernel/alternative.c search for FineIBT

I found some stuff in one of the docs.
Didn't read that bit of source.

What I was hoping to obtain was a list of the valid target functions for
each indirect call site.
With the stack offset of the call (which objtool knows) and a lot of 'shaking'
an real estimate of max stack depth can be determined.
(and recursive loops found.)

	David
 


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ