Konrad Eisele
Konrad Eisele

Reputation: 3194

Is the sys_call_table read protected in 4.8 kernel?

I use the simple sys_call_table rewrite to log all execve calls in a system.

When moving to Ubuntu 16.10 with a 4.8 kernel this mechanism suddenly stopped to work. In 16.04 with a 4.6 kernel it was working.

    1: write_cr0 (read_cr0 () & (~ 0x10000));

    2: original_execve = (void *)syscall_table[__NR_execve];
    3: syscall_table[__NR_execve] = (unsigned long)&new_execve;

    4: write_cr0 (read_cr0 () | 0x10000);

The page fault already happens when reading the old entry, that is line 2. To retrive the sys_call_table address I use:

sudo cat /boot/System.map-`uname -r` | grep -e '\ssys_call_table' | awk '{ print $1}' )" 

Code is from: https://github.com/eiselekd/shinterposer/tree/master/mod

Does anyone know what happened? Maybe some protection mechanism has been introduced?

Upvotes: 4

Views: 920

Answers (1)

Konrad Eisele
Konrad Eisele

Reputation: 3194

There seem to be Address Space Layout Randomization (kASLR) on the syscall table taking place by default in the 4.8 kernel. When declaring the sys_call_table symbol as exported and linking against it directly from a module the address for sys_call_table is changing for each boot. The address from /boot/System.map-xxx is useless.

To disable kaslr in ubuntu 16.10 kernel 4.8 one can add

nokaslr

to the kernel command line.

Upvotes: 2

Related Questions