copy_from / to_user何时返回非零值
收藏

我读了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
然后我有三个问题。
哪里定义了返回非零的copy_from/to_user的代码?
是什么导致copy_from/to_user返回非零值?
返回什么值?


最佳答案:

我敢肯定你看错了文件;tools/*不是内核的一部分,而是用户空间工具的源代码。这段代码看起来像是连接用户空间程序中为内核api编写的代码的存根。
实际的copy_from/to_user函数看起来也总是返回0,但据我所知,它们有一些花哨的技巧,将链接器部分连接到它们的内联asm中,以便当cpu在复制操作期间捕获访问错误时,错误处理程序可以用一个假的-EFAULT返回值在调用方恢复执行。这些函数的定义是特定于arch的,可能可以在arch/树中找到。

    公众号
    关注公众号订阅更多技术干货!