copy_from_user 和 toctou

本文详细解释了Linux内核中copy_from_user函数的作用及使用方法,包括如何将用户空间的数据复制到内核空间并进行检查,以及如何处理结构体中指向用户空间的指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

      copy_from_user 是把数据从用户空间 copy 到 内核空间。 

     driver 先 把数据从用户空间copy 到内核空间,然后再进行 check.

      因为如果数据在user 空间 check 之后再copy 到内核,check 后到copy 之间的时间,数据有可能会被改变。参见TOCTOU 问题。

      所以把数据 copy 到 内核空间,内核空间不太容易被攻击,数据check 后再使用。


     还有一个问题,如果 copy_from_user() copy 的struct 里面包含指向用户态的指针,该怎么办呢?

     回答: Driver 需要 aware of this.

                 问题中的copy_from_user 只是copy 了指针,并没有copy 指针所指向的数据。需要另外进行copy. 参见下面                    的网页。


http://stackoverflow.com/questions/1698396/linux-kernel-copy-from-user-struct-with-pointers


I've implemented some kind of character device and I need help with copy_ from_user function.

I've a structure:

struct  my_struct{

int a;

int *b;
};

I initialize it in user space and pass pointer to my_struct to my char device using 'write' function. In Kernel's Space character device 'write' function I cast it from a *char to this kind of structure. I alloc some memory for a struct using kmalloc and do copy_from_user into it.

It's fine for simple 'int a', but it copies only pointer (address) of b value, not value pointed by b, so I'm now in Kernel Space and I'm working with a pointer that points to a user space memory. Is this incorrect and I shouldn't access to user space pointer directly and I have to copy_from_user every single pointer in my struct and then copy back every pointer in "read" function using copy_to_userfunction?

回答1:

You must always use copy_from_user and similar to access user space memory from kernel space, regardless of how you got the pointer. Since b is a pointer to user space memory, you must use copy_from_user to access it.

These functions do two important additional tasks:

  1. They make sure the pointer points into user space and not kernel space. Without this check, user space programs might be able to read or write to kernel memory, bypassing normal security.
  2. They handle page faults correctly. Normally a page fault in kernel mode will result in an OOPS or panic - the copy_*_user family of functions have a special override that tells the PF handler that all is well, and the fault should be handled normally; and in the event that the fault cannot be satisfied by IO (ie, what would normally cause a SIGSEGV or SIGBUS), return an error code instead so their caller can do any necessary cleanup before returning to userspace with -EFAULT.
回答2:

You are correct in your surmising. If you need to access the value *b, you will need to use copy_from_user (and copy_to_user to update it back in the user process).



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值