Recently I am study vdso in linux. I tried to modify the data in vvar
section but it failed. Following is what I've tried.
According to lwn described, there're two address for vvar
:
The first one is a regular kernel-space address whose value is greater than PAGE_OFFSET. If you look at the System.map file, you'll find that this symbol has an address like ffffffff81c76080.
The second address is in a region called the "vvar page". The base address (VVAR_ADDRESS) of this page is defined in the kernel to be at 0xffffffffff5ff000, close to the end of the 64-bit address space. This page is made available read-only to user-space code.
Modify by first address: First address is easy to find by checking the address of _vdso_data
in /boot/System.map-kernel-version
. After getting the address, I modify the member (__unused
) of it in kernel module ( thus, there's not permission issue ). Then, I check the __unused
from user space program, it still remain 0
which means that I failed to modify it from kernel space.
Modify by second address: Second address can be found by auxiliary vector. After getting the address of vdso
, then we can find vvar
section. I pass this address into kernel module and modify its member __unused
. The the error occur, showing the permission error issue. ( The reason should be vvar
is read-only memory, checking by cat /proc/pid/maps
)
I think the first way is almost at the solution but it seems vvar
at that address is not be mapped to all process' vvar
section. Are there any idea? Thanks in advance.
[EDIT]: The first way get more closer to solution. I modify the cr0 bit, thus allow permission of writing. Even I successfully write it, it still can't be read from linux kernel (by getting vdso_data through __arch_get_k_vdso_data
and accessing its member which I modify in user space + kernel module previously)