【问题标题】:Generating segfault from a custom syscall从自定义系统调用生成段错误
【发布时间】:2017-10-29 14:08:07
【问题描述】:

我正在通过系统调用执行copy_to_user()

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

【问题讨论】:

  • @Yunnosch 我完全支持 MCVE,但我基本上是在问如何触发与内核空间中地址 X 对应的段错误。我假设一个简单的问题,一个单行的答案。发布设置 linux 构建、连接系统调用、编译、在虚拟机中运行以及让虚拟机执行用户空间测试程序所需的几页代码似乎有点矫枉过正。
  • kill(getpid(), SIGSEGV); 呢?
  • 通常,系统调用应该在出现此类错误时返回 -EFAULT,您确定要打破这种模式吗?否则,看看send_sig_info()
  • 失分。我的目标是一些代码行,它们给出了一些概念的上下文。类似于几行伪代码(嵌入为实际代码中的 cmets)之类的东西,它们说明了您想要触发的情况和一些推理。除了散文(我的口味有点短)之外,我希望你对你的问题提供不同的看法。例如,我不明白您为什么要给人一种虚假的印象,即某些用户空间代码行为不端,而实际上内核空间存在某种问题。我承认 MCVE 是错误的术语。

标签: c linux linux-kernel signals


【解决方案1】:

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

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

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

例如,内核中一个常见的sn-p如下:

if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
    return -EFAULT;

(取自 sendfile64 syscall 在 fs/read_write.c 的实现)

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

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


但是,如果您自己编写内核系统调用,并且想要触发信号,那一点也不难。我没有在内核中挖掘太多,但是在send_sig_info 中调用一些东西(或kernel/signal.c 中的另一个合适的函数)就是你要找的。​​p>

【讨论】:

  • 谢谢。 send_sig_info 很简单,但我想知道如何填写信息结构,发送什么信号(我相信 SIGSEGV 和 SIGBUS 是选项),假设内存访问的行为应该与来自用户空间的行为相同。
猜你喜欢
  • 1970-01-01
  • 2012-10-04
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多