从自定义系统调用生成段错误

PSk*_*cik 6 c linux signals linux-kernel

我是在做copy_to_user()一个系统调用.

如何在错误时生成段错误或sigbus,就像用户空间试图访问相同的内存一样?

Mar*_*gal 0

嗯,一般来说,你不能。除非你打算重写内核。

当内核访问用户模式地址时,它使用安全形式,通常是copy_from_user, copy_to_user, get_user, ... - 正如您所提到的。这些宏具有内核检查的返回值,并且在大多数情况下将返回-EFAULT

然后,通常会出现 libc 并调整返回值以适合页面man- 这意味着它会设置errno结果是否错误(取决于调用哪个系统调用)。

例如,内核中的一个常见片段如下:

if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
    return -EFAULT;
Run Code Online (Sandbox Code Playgroud)

(取自sendfile64fs/read_write.c 中系统调用的实现)

如您所见,当内核无法从用户模式读取时,它会返回-EFAULT.

鉴于可以将多个指针传递给某些系统调用,因此可能无法找出哪一个导致了-EFAULT. 因此,没有一种通用的用户模式方法可以SIGSEGV代表内核在检查到无效内存访问时发送 s 。


但是,如果您自己编写内核系统调用,并且想要触发信号,那么这并不困难。我没有在内核中进行过多的挖掘,但是send_sig_info您正在寻找在(或 kernel/signal.c 中的另一个合适的函数)行中调用某些内容。