|
|
Log in / Subscribe / Register

Control-flow integrity in 5.13

Control-flow integrity in 5.13

Posted May 22, 2021 15:11 UTC (Sat) by ale2018 (subscriber, #128727)
Parent article: Control-flow integrity in 5.13

I'm not clear how an attacker is supposed to redirect a call to some other address than the function it was meant to reach. The example shows the check carried out in the code near the location of the call itself. It does nothing to prevent, say, returning from an overflowed stack, does it?

CFI is meant to defend against an attacker who is able to fiddle with jump tables in kernel memory, but neither with the bit arrays nor with the code itself (still in kernel memory), right? Or maybe it merely tries to impede the attacker by requiring coordinated changes in the jump table and in the bit array?

And how about compiling with GCC?


to post comments

Control-flow integrity in 5.13

Posted May 22, 2021 16:17 UTC (Sat) by corbet (editor, #1) [Link] (1 responses)

As noted in the article, this change provides forward-edge protection. Protecting against return-address corruption (backward-edge) requires different techniques like shadow stacks.

The jump tables will be in read-only memory, which makes them a lot harder to overwrite.

Control-flow integrity in 5.13

Posted May 25, 2021 1:33 UTC (Tue) by cypherpunks2 (guest, #152408) [Link]

PaX RAP uses a different technique which does not require shadow stacks and is more performant. Sadly it is available for customers only right now.

Control-flow integrity in 5.13

Posted May 27, 2021 5:35 UTC (Thu) by wahern (subscriber, #37304) [Link]

Take an object like

struct foo {
  char buf[64];

  int (*fptr)(int);

  struct {
    int (*fptr)(int);
  } *vtable;
};

If an attacker can overflow (struct foo).buf, then they can rewrite the address of fptr or vtable to point wherever. The latter takes extra leg work to exploit, unless they know the address of the (struct foo) object, in which case they can just point vtable back into an area they already wrote, reducing it to the former case. There are more complex cases (e.g. involving integer indices into tables rather than raw pointers) but the basic problem is the same: deriving a function pointer through loads from writeable memory regions.


Copyright © 2026, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds