linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* How do I force an IBT trap in a demo kernel module?
@ 2023-05-23 19:28 Preble, Adam C
  2023-05-24  8:00 ` David Laight
  0 siblings, 1 reply; 5+ messages in thread
From: Preble, Adam C @ 2023-05-23 19:28 UTC (permalink / raw)
  To: linux-kernel

I am debugging why a kernel module of ours triggers the IBT (Indirect Branch Tracking) trap, and while doing that, I was trying to write a standalone demo that would forcefully trigger it on purpose. This has turned out to be much more difficult than I thought! What can I do to get a module to generate an indirect branch without an endbr64? Creating the indirect branch itself doesn't appear to be hard:

1. Set up a function call
2. Assign it to a function pointer
3. Call the function pointer
4. ...maybe add a compiler flag so it doesn't optimize the call to a direct branch.

I am primarily building in a Debian environment with gcc (Debian 10.2.1-6) 10.2.1 20210110. By default, the branch does get optimized away. I had to set the -mforce-indirect-call flag. The endbr64 instruction would still emit so I added a function attribute to suppress it:


__attribute__((nocf_check))
static void indirect_jump_to_me(void)
{
    pr_info("Reached indirect jump\n");
}


I think that took care of my code generation, but objtool is offended by what I am doing:


/root/module/ibt_test.o: warning: objtool: init_ibt_test_module+0x11: relocation to !ENDBR: indirect_jump_to_me+0x0
  MODPOST /root/module/Module.symvers
ERROR: modpost: "__x86_indirect_thunk_nt_rax" [/root/module/ibt_test.ko] undefined!
make[4]: *** [/usr/src/my-header-6.3.0/scripts/Makefile.modpost:136: /root/module/Module.symvers] Error 1


So what do I have to do to tell objtool to allow to me deliberately shoot myself in the foot here?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: How do I force an IBT trap in a demo kernel module?
  2023-05-23 19:28 How do I force an IBT trap in a demo kernel module? Preble, Adam C
@ 2023-05-24  8:00 ` David Laight
  2023-05-27 22:40   ` Pavel Machek
  0 siblings, 1 reply; 5+ messages in thread
From: David Laight @ 2023-05-24  8:00 UTC (permalink / raw)
  To: 'Preble, Adam C', linux-kernel

From: Preble, Adam C
> Sent: 23 May 2023 20:29
> 
> I am debugging why a kernel module of ours triggers the IBT (Indirect Branch Tracking) trap, and while
> doing that, I was trying to write a standalone demo that would forcefully trigger it on purpose. This
> has turned out to be much more difficult than I thought! What can I do to get a module to generate an
> indirect branch without an endbr64? Creating the indirect branch itself doesn't appear to be hard:
> 
> 1. Set up a function call
> 2. Assign it to a function pointer
> 3. Call the function pointer
> 4. ...maybe add a compiler flag so it doesn't optimize the call to a direct branch.
> 
> I am primarily building in a Debian environment with gcc (Debian 10.2.1-6) 10.2.1 20210110. By
> default, the branch does get optimized away. I had to set the -mforce-indirect-call flag. The endbr64
> instruction would still emit so I added a function attribute to suppress it:
...
> So what do I have to do to tell objtool to allow to me deliberately shoot myself in the foot here?

You could try adjusting the function pointer by the size of the endbr64 instrauction.

Oh, put the function pointer variable into static data.
That should stop it all being optimised away.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: How do I force an IBT trap in a demo kernel module?
  2023-05-24  8:00 ` David Laight
@ 2023-05-27 22:40   ` Pavel Machek
  2023-05-31 23:02     ` Preble, Adam C
  0 siblings, 1 reply; 5+ messages in thread
From: Pavel Machek @ 2023-05-27 22:40 UTC (permalink / raw)
  To: David Laight; +Cc: 'Preble, Adam C', linux-kernel

On Wed 2023-05-24 08:00:36, David Laight wrote:
> From: Preble, Adam C
> > Sent: 23 May 2023 20:29
> > 
> > I am debugging why a kernel module of ours triggers the IBT (Indirect Branch Tracking) trap, and while
> > doing that, I was trying to write a standalone demo that would forcefully trigger it on purpose. This
> > has turned out to be much more difficult than I thought! What can I do to get a module to generate an
> > indirect branch without an endbr64? Creating the indirect branch itself doesn't appear to be hard:
> > 
> > 1. Set up a function call
> > 2. Assign it to a function pointer
> > 3. Call the function pointer
> > 4. ...maybe add a compiler flag so it doesn't optimize the call to a direct branch.
> > 
> > I am primarily building in a Debian environment with gcc (Debian 10.2.1-6) 10.2.1 20210110. By
> > default, the branch does get optimized away. I had to set the -mforce-indirect-call flag. The endbr64
> > instruction would still emit so I added a function attribute to suppress it:
> ...
> > So what do I have to do to tell objtool to allow to me deliberately shoot myself in the foot here?
> 
> You could try adjusting the function pointer by the size of the endbr64 instrauction.
> 
> Oh, put the function pointer variable into static data.
> That should stop it all being optimised away.

volatile will help, too.

Or simply write the code in assembly.
								Pavel

-- 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: How do I force an IBT trap in a demo kernel module?
  2023-05-27 22:40   ` Pavel Machek
@ 2023-05-31 23:02     ` Preble, Adam C
  2023-06-01  8:04       ` David Laight
  0 siblings, 1 reply; 5+ messages in thread
From: Preble, Adam C @ 2023-05-31 23:02 UTC (permalink / raw)
  To: Pavel Machek, David Laight; +Cc: linux-kernel

It looked to me like I was getting the indirect jump just fine with what I already was doing. Sure, I made the instruction pointer volatile and static, but nothing changed just from that.

The make command ultimately invoked is:
make -C /lib/modules/6.4.0.headers/build M=/root/module KCFLAGS="-mforce-indirect-call -O0" modules

(I'm now messing around with the 6.4.0 kernel; it was 6.3.0 before)

objtool will then puke:
/root/module/ibt_test.o: warning: objtool: init_ibt_test_module+0x11: relocation to !ENDBR: indirect_jump_to_me+0x0

I think that between those KCFLAGS and my function prototype that I was able to mark the function to not have an endbr64 landing pad:
__attribute__((nocf_check))
static void indirect_jump_to_me(void)

However, I am assuming that objtool is rejecting the alteration:
/root/ibt_experiments/module/ibt_test.o: warning: objtool: indirect_jmp_ptr.0+0x0: data relocation to !ENDBR: indirect_jump_to_me+0x0
  MODPOST /root/ibt_experiments/module/Module.symvers
ERROR: modpost: "__x86_indirect_thunk_nt_rax" [/root/ibt_experiments/module/ibt_test.ko] undefined!

I wondered if I could circumvent this check too without, say, just resorting to coding it in assembler.

If there's one thing I'm learning so far, it's how hard it is to actually force IBT to trigger. This makes the trap I'm hitting in this legacy code with IBT on particularly galling.

-----Original Message-----
From: Pavel Machek <pavel@ucw.cz> 
Sent: Saturday, May 27, 2023 5:41 PM
To: David Laight <David.Laight@aculab.com>
Cc: Preble, Adam C <adam.c.preble@intel.com>; linux-kernel@vger.kernel.org
Subject: Re: How do I force an IBT trap in a demo kernel module?

On Wed 2023-05-24 08:00:36, David Laight wrote:
> From: Preble, Adam C
> > Sent: 23 May 2023 20:29
> > 
> > I am debugging why a kernel module of ours triggers the IBT 
> > (Indirect Branch Tracking) trap, and while doing that, I was trying 
> > to write a standalone demo that would forcefully trigger it on 
> > purpose. This has turned out to be much more difficult than I thought! What can I do to get a module to generate an indirect branch without an endbr64? Creating the indirect branch itself doesn't appear to be hard:
> > 
> > 1. Set up a function call
> > 2. Assign it to a function pointer
> > 3. Call the function pointer
> > 4. ...maybe add a compiler flag so it doesn't optimize the call to a direct branch.
> > 
> > I am primarily building in a Debian environment with gcc (Debian 
> > 10.2.1-6) 10.2.1 20210110. By default, the branch does get optimized 
> > away. I had to set the -mforce-indirect-call flag. The endbr64 instruction would still emit so I added a function attribute to suppress it:
> ...
> > So what do I have to do to tell objtool to allow to me deliberately shoot myself in the foot here?
> 
> You could try adjusting the function pointer by the size of the endbr64 instrauction.
> 
> Oh, put the function pointer variable into static data.
> That should stop it all being optimised away.

volatile will help, too.

Or simply write the code in assembly.
								Pavel

-- 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: How do I force an IBT trap in a demo kernel module?
  2023-05-31 23:02     ` Preble, Adam C
@ 2023-06-01  8:04       ` David Laight
  0 siblings, 0 replies; 5+ messages in thread
From: David Laight @ 2023-06-01  8:04 UTC (permalink / raw)
  To: 'Preble, Adam C', Pavel Machek; +Cc: linux-kernel

From: Preble, Adam C
> Sent: 01 June 2023 00:02
> 
> It looked to me like I was getting the indirect jump just fine with what I already was doing. Sure, I
> made the instruction pointer volatile and static, but nothing changed just from that.

This ought to compile to code that does what you want..

void func(void) {}

void (*func_ptr)(void) = func;

void test(void)
{
	void (*ptr)(void) = (void *)func_ptr + 4;

	ptr();
}

See https://godbolt.org/z/o8cedv3d4 but that doesn't have the option
that generated the endbra.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-06-01  8:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-05-23 19:28 How do I force an IBT trap in a demo kernel module? Preble, Adam C
2023-05-24  8:00 ` David Laight
2023-05-27 22:40   ` Pavel Machek
2023-05-31 23:02     ` Preble, Adam C
2023-06-01  8:04       ` David Laight

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).