我的系统调用原因分段错误(核心已转储)

问题描述 投票:1回答:1

我正在基于此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根本不正确。这是printkdmesg中打印的内容>

this is what the <code>printk</code> print in <code>dmesg</code>

my_syscall中的id应该是pid,并且在我的测试中以值1传递。(syscall(548, 1, &info);

我知道这很长,但是如果有人可以解释我的工具有什么问题,我将不胜感激,谢谢。

我根据本教程编写了一个简单的syscall,并在其中使用syscall引导到新内核,但是当我编译测试并执行它时,会导致分段错误(内核转储)。我的...

c linux system-calls
1个回答
0
投票

您正在将用户指针作为进程堆栈的一部分传递给内核。这是不好的做法,因为内核内存和用户内存是单独的实体,因此永远不会起作用。您需要使用System Apis在用户与内核内存之间传递指针。查看copy_to_user和copy_from_user函数。您也可以使用ioctl方法来在用户/应用程序和内核之间创建后门。

© www.soinside.com 2019 - 2024. All rights reserved.