This repo showcases a simple technique for branching to a dynamically obtained address with a near direct call in a Linux kernel module.
WARNING: Don't try this at home. Safety of the system cannot be guaranteed.
Note: We assume that the lockdown security policy isn't in place such that the loading of unsigned kernel modules is permitted.
The example requires the usual make
as well as headers for the current kernel.
The kernel module can be compiled simply by running
$ make
and loaded with
# insmod ./ddb.ko && rmmod ddb
The output of this can be seen with dmseg
:
[ 216.563935] mod: local_func : ffffffffc1f0c180
[ 216.563942] mod: target : ffffffff9f5a5540
[ 216.563944] mod: rel : ffffffffdd6993bb
[ 216.563946] mod: e9 bb 93 69 dd
[ 216.563951] Hello, World!
[ 221.209151] mod: removing module
The Hello, World!
log message is done via a call to a runtime modified stub function.
Indirect calls/branches can cause issues with Indirect Branch Tracking (IBT), a control flow integrity security feature which requires the target to be marked for indirect branches (with endbr
).
Turning this into a direct call can allow kernel modules to call functions that it obtains the addresses of at runtime without falling foul of IBT.