[英]How to use syscall to change vDSO content
I am trying to implement a syscall
on x86
that is able to modify the content of vDSO
.我正在尝试在
x86
上实现一个syscall
,该系统调用能够修改vDSO
的内容。 Given vDSO
content is read-only for userspace, I believe a syscall
is needed.鉴于
vDSO
内容对于用户空间是只读的,我相信需要一个syscall
。 Otherwise it will cause segmentation fault.否则会导致分段错误。 However, I can't do it successfully at this moment.
但是,我目前无法成功。
kernel/sys.c
kernel/sys.c
extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));
SYSCALL_DEFINE1(foo, int, num) {
struct vdso_data *vdata = _vdso_data;
vdata[0].__unused = num;
return 0;
}
The syscall
will read the _vdso_data
which is declared in arch/x86/include/asm/vvar.h
and defined in arch/x86/include/asm/vdso/vsyscall.h
. syscall
将读取在arch/x86/include/asm/vvar.h
_vdso_data
声明并在arch/x86/include/asm/vdso/vsyscall.h
。 Then it will modify the variable __unused
into some number input by the user.然后它将变量
__unused
修改为用户输入的某个数字。
arch/x86/entry/vdso/vclock_gettime.c
arch/x86/entry/vdso/vclock_gettime.c
#include <asm/vdso/vsyscall.h>
notrace int __vdso_query()
{
struct vdso_data *vdata = __arch_get_k_vdso_data();
return vdata[0].__unused;
}
I know it's a bad idea to define something unrelated to time in a timing fucntion, but this is what I'm testing right now.我知道在时序函数中定义与时间无关的东西是个坏主意,但这是我现在正在测试的。 The
__vdso_query()
function will read the data and return the value of the __unused
variable. __vdso_query()
function 将读取数据并返回__unused
变量的值。
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
#define SYS_foo 548
extern int __vdso_query();
int main(int argc, char **argv)
{
int before = __vdso_query();
printf("Before syscall: %d\n", before);
int num = 10;
long res = syscall(SYS_foo, num);
int after = __vdso_query();
printf("After syscall: %d\n", after);
return res;
}
I want to see 0
before the syscall
and 10
after the syscall
returned by __vdso_query()
since the syscall
will change the _vdso_data[0].__unused
if everything follows the plan.我想在系统调用之前看到
0
,在syscall
__vdso_query()
返回的系统syscall
之后看到10
,因为如果一切都按照计划进行, syscall
将更改_vdso_data[0].__unused
。
For now, the content is always 0
regardless of the syscall
.目前,无论
syscall
如何,内容始终为0
。
_vdso_data
properly_vdso_data
There are 2 ways I tried to access the _vdso_data
: __arch_sync_vdso_data()
and extern
.我尝试通过两种方式访问
_vdso_data
: __arch_sync_vdso_data()
和extern
。
__arch_get_k_vdso_data
function where defined in asm/vdso/vsyscall.h
to access the _vdso_data
, I encounter some variable redefinition errors.asm/vdso/vsyscall.h
__arch_get_k_vdso_data
定义的 __arch_get_k_vdso_data function 来访问_vdso_data
时,我遇到了一些变量重新定义错误。 If I include vsyscall.h
in both kernel/sys.c
and arch/x86/entry/vdso/vclock_gettime.c
, it seems DEFINE_VVAR(struct vdso_data, _vdso_data);
kernel/sys.c
和arch/x86/entry/vdso/vclock_gettime.c
中都包含vsyscall.h
,似乎DEFINE_VVAR(struct vdso_data, _vdso_data);
will be called twice and leads to redefinition error of _vdso_data
._vdso_data
的重新定义错误。 I tried to put #ifndef
, #def
, and #endif
macros around it but the error still exists.#ifndef
、 #def
和#endif
宏,但错误仍然存在。_vdso_data
as extern
variable shown in the syscall
implementation._vdso_data
声明为syscall
实现中显示的extern
变量。 The redefinition error is gone if I do this.__arch_sync_vdso_data()
function __arch_sync_vdso_data()
function I read some example usages in the kernel source code a little bit and I find people use __arch_sync_vdso_data
function to write the _vdso_data
in the end.我在 kernel 源代码中阅读了一些示例用法,我发现人们使用
__arch_sync_vdso_data
function 最后编写_vdso_data
。 However, I think this function is actually empty in the generic-asm
and the only definition I can find is on Arm
.但是,我认为这个 function 在
generic-asm
中实际上是空的,我能找到的唯一定义是Arm
。 Not really sure how this will work on x86
and is it needed.不确定这将如何在
x86
上工作,是否需要。
It's really hard to find vdso resources online and I've read all the recent posts.在网上很难找到 vdso 资源,我已经阅读了所有最近的帖子。 I would really appreciate the help and thanks in advance.
我非常感谢您的帮助和提前感谢。
It turns out syscall
is doing the right work and the problem is how to access the vDSO
data.事实证明
syscall
正在做正确的工作,问题是如何访问vDSO
数据。
In fact, __arch_get_vdso_data
is the right function to access vDSO data.事实上,
__arch_get_vdso_data
是正确的 function 访问 vDSO 数据。 It returns a pointer which can be further dereferenced to access the data like __arch_get_vdso_data()->__unused
.它返回一个指针,可以进一步取消引用以访问
__arch_get_vdso_data()->__unused
等数据。
On the other hand, __arch_get_k_vdso_data
never works and I suspect the _k_
in the function name indicates that this function can be only used in kernel space.另一方面,
__arch_get_k_vdso_data
从不工作,我怀疑_k_
名称中的 _k_ 表明这个 function 只能在 Z50484C19F1AFDAF38421ZA08 空间中使用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.