c - copy_from/to_user 何时返回非零值

标签 c linux linux-kernel kernel

我阅读了copy_from/to_user 函数的源代码。 似乎他们总是返回 0

static inline int copy_from_user(void *to, const void __user volatile *from,
                 unsigned long n)
{
    __chk_user_ptr(from, n);
    volatile_memcpy(to, from, n);
    return 0;
}

https://github.com/torvalds/linux/blob/6f0d349d922ba44e4348a17a78ea51b7135965b1/tools/virtio/linux/uaccess.h#L37-L51

但是,有如下代码检查 copy_from/to_user 的返回值。

    if (copy_from_user(&tmp, user, sizeof(tmp)) != 0)
        return -EFAULT;

https://github.com/torvalds/linux/blob/db54615e21419c3cb4d699a0b0aa16cc44d0e9da/net/ipv4/netfilter/ip_tables.c#L1114-L1115

那么我有3个问题。

  1. 返回非零的copy_from/to_user代码定义在哪里?
  2. 是什么导致 copy_from/to_user 返回非零值?
  3. 返回什么值?

最佳答案

我敢肯定您看错了文件; tools/* 不是内核的一部分,而是用户空间工具的源代码。这段代码看起来像是用于链接为用户空间程序中的内核 API 编写的代码的 stub 。

实际的 copy_from/to_user 函数也可能看起来总是返回 0,但据我所知,它们有一些奇特的技巧,链接器部分连接到它们的内联 asm 中,因此当 cpu在复制操作期间捕获访问错误,错误处理程序可以使用伪造的 -EFAULT 返回值在调用者处恢复执行。这些函数的定义是特定于架构的,可能可以在 arch/ 树中的某个地方找到。

关于c - copy_from/to_user 何时返回非零值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57977023/

相关文章:

linux - 什么时候在 linux 中打开端口?

linux - 从/proc/kcore获取系统调用表中的系统调用地址

c - C 中的 block 语句、逗号和控制表达式

c++ - 使用 select 多路复用未命名管道和其他文件描述符

c++ - 递归迭代

c# - 无法在 Linux 下使用 .Net Core 等待 Task.Delay

c - putty 如何检测 xfer 是否正在备份?

c++ - Boost.lockfree 在 RHEL 5.3 上的性能

linux - 没有 X 的 Tegra Mesa GLES

c - sprintf中的pcmC%iD%ip参数