我正在基于此tutorial编写一个简单的syscall,并使用其中的syscall引导到新内核,但是当我编译测试并执行它时,它将导致分段错误(内核转储)。我的my_syscall.h(在本教程中相当于hello.c)看起来像这样。
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/current.h>
struct smallStruct {
int integer;
char str[20];
};
struct bigStruct {
long id;
struct smallStruct a;
struct smallStruct b;
struct smallStruct c;
};
asmlinkage long test_syscall(int pid, struct bigStruct *info)
{
info->id = pid;
info->a.integer = 0;
info->a.str[0] = 'A';
info->a.str[1] = '\0';
info->b.integer = 1;
info->b.str[0] = 'B';
info->b.str[1] = '\0';
info->c.integer = 2;
info->c.str[0] = 'C';
info->c.str[1] = '\0';
return 0;
}
我实际上试图编写一个获取某些信息并将其存储回*info
的系统调用,并且我需要str
中的smallStruct
,但是每次我尝试修改str
时,都会导致分段错误(核心转储),并且当我删除对str
的那些修改以暂时避免核心转储时,它仍然无法按预期工作。这是我的测试文件的样子:
#include <sys/syscall.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
struct smallStruct
{
int integer;
char str[20];
};
struct bigStruct
{
long id;
struct smallStruct a;
struct smallStruct b;
struct smallStruct c;
};
int main()
{
long sys_return_value;
struct bigStruct info;
sys_return_value = syscall(548, 1, &info);
printf("id = %ld, return %ld\n", info.id, sys_return_value);
return 0;
}
似乎我测试中的info
根本没有被syscall修改。我什至在my_syscall.h中使用printk
,传递给我的syscall的pid
根本不正确。这是printk
在dmesg
中打印的内容>
my_syscall中的id
应该是pid
,并且在我的测试中以值1传递。(syscall(548, 1, &info);
)
我知道这很长,但是如果有人可以解释我的工具有什么问题,我将不胜感激,谢谢。
我根据本教程编写了一个简单的syscall,并在其中使用syscall引导到新内核,但是当我编译测试并执行它时,会导致分段错误(内核转储)。我的...
您正在将用户指针作为进程堆栈的一部分传递给内核。这是不好的做法,因为内核内存和用户内存是单独的实体,因此永远不会起作用。您需要使用System Apis在用户与内核内存之间传递指针。查看copy_to_user和copy_from_user函数。您也可以使用ioctl方法来在用户/应用程序和内核之间创建后门。