mournjust 发表于 2016-08-09 15:07

copy_{from/to}_user的实现

内核空间无法访问用户态地址。但是内核代码段中。include/asm-generic/uaccess.h#L79

78 #ifndef __copy_from_user
79 static inline __must_check long __copy_from_user(void *to,
80               const void __user * from, unsigned long n)
81 {
82         if (__builtin_constant_p(n)) {
83               switch(n) {
84               case 1:
85                         *(u8 *)to = *(u8 __force *)from;
86                         return 0;
87               case 2:
88                         *(u16 *)to = *(u16 __force *)from;
89                         return 0;
90               case 4:
91                         *(u32 *)to = *(u32 __force *)from;
92                         return 0;
93 #ifdef CONFIG_64BIT
94               case 8:
95                         *(u64 *)to = *(u64 __force *)from;
96                         return 0;
97 #endif
98               default:
99                         break;
100               }
101         }
102
103         memcpy(to, (const void __force *)from, n);
104         return 0;
105 }
106 #endif
除了权限检查之外就是直接拷贝,网上看到了一些关于exception的说法,但是还是不能系统的理解。

karma303 发表于 2016-08-11 10:07

朋友,我建议你把这个问题好好再表述一遍。

newsfh 发表于 2016-08-11 17:23

内核空间无法访问用户态地址。
内核代码可以访问用户空间。
具体哪些空间可以访问,需要看MMU配置。

nswcfd 发表于 2016-08-16 16:30

这一段是generic的实现,在具体的架构上应该不是这份代码。

nswcfd 发表于 2016-08-16 16:44

如果user传来的from是恶意地址,比如NULL,那么在内核执行generic版本的__copy_from_user就会产生crash(严格的说是保护错误/异常)。

所以真正的copy_from_user会把函数的调用位置记在一个表里(exception表),
等到非法访问产生异常的时候,在异常处理函数里检查错误的指令是否在exception表里,
如果是,修改表示eip到fixcode;
异常处理返回后,fixcode得到执行,返回错误-EFAULT给调用者。

具体参见ULK3的第10章,最后一部分。
页: [1]
查看完整版本: copy_{from/to}_user的实现