在内核模块中执行系统调用



我开始开发一个带有内联汇编的内核模块,我正在尝试执行写入系统调用以写入文件。它编译得很好(此外,在 C 程序中工作正常(,但是当我加载模块时,它会丢弃分段错误,当我查看诊断消息 (dmesg( 时,我看到以下内容:

[  672.687568] BUG: stack guard page was hit at ffffb8a601d13fa8 (stack is ffffb8a601d14000..ffffb8a601d17fff)
[  672.687577] kernel stack overflow (double-fault): 0000 [#1] SMP
...
[  672.777032]  [<ffffffffa50fda16>] ? SYSC_finit_module+0xc6/0xf0
[  672.777396]  [<ffffffffa55ebebb>] ? system_call_fast_compare_end+0xc/0x9b
[  672.777765] Code: 48 89 e7 48 8b 74 24 78 48 c7 44 24 78 ff ff ff ff e8 28 09 a7 ff e9 53 02 00 00 0f 1f 00 0f 1f 00 66 0f 1f 44 00 00 48 83 c4 88 <e8> 7e 01 00 00 48 89 e7 48 8b 74 24 78 48 c7 44 24 78 ff ff ff 
[  672.779059] RIP  [<ffffffffa55ed27d>] page_fault+0xd/0x30
[  672.779481]  RSP <ffffb8a601d13fb8>
[  672.779901] fbcon_switch: detected unhandled fb_set_par error, error code -16

内核模块的代码如下:

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
int example_init(void);
void example_exit(void);
module_init(example_init);
module_exit(example_exit);

int example_init(void) {
    char *file = "/root/test2";
    char *msg = "AAAAAAn";
    asm( "mov eax, 0x2;"
        "mov rdi, %0;" 
        "mov rsi, 0x441;"
        "xor rdx, rdx;"
        "syscall;"
        "mov rdi, rax;"
        "mov eax, 0x1;"
        "mov rsi, %1;"
        "mov rdx, 7;"
        "syscall;"
        "mov eax, 0x3;"
        "syscall;"
        : "=m" (file), "=m" (msg)
    );
        printk("Example: module loaded.n");
        return 0;
}
void example_exit(void) {
       printk("Example: module removedn");
}
我知道失败出在系统调用指令

中,因为我在没有系统调用指令的情况下尝试过,并且汇编代码正常工作,并且在启动系统调用时只做了分段错误。

正如@RossRidge在评论中指出的那样,Linux 内核不是为从内核代码中使用的系统调用而设计的。因此syscall指令不应在内核代码中使用。

系统调用获得的某些功能具有内核内的替代功能。例如,对于在内核中打开文件,可以使用filp_open,而对于写入文件-vfs_write。有关在内核代码中使用文件的更多信息,请参阅该问题。

相关内容

  • 没有找到相关文章

最新更新