linux 内核函数 copy_from_user和copy_to_user 介绍
前言
copy_from_user和copy_to_user这两个函数相信做内核开发的人都非常熟悉,分别是将用户空间的数据拷贝到内核空间以及将内核空间中的数据拷贝到用户空间。这两个函数一般用于系统调用中,前者将用户空间参数拷贝到内核,后者将系统用的结果返回到用户空间。
用户空间和内核空间
Linux将地址空间分为用户空间和内核空间,内核文档Documentation/arm64/memory.txt中定义了内核地址空间和用户地址空间的范围,比如4K Page +4 level页表时,地址空间分布如下:
AArch64 Linux memory layout with 4KB pages + 4 levels:Start End Size Use
-----------------------------------------------------------------------
0000000000000000 0000ffffffffffff 256TB user
ffff000000000000 ffffffffffffffff 256TB kernel
用户空间占用低地址,内核空间占用高地址。
用户态和内核态地址空间访问权限
这个问题,做个内核开发的人也一定非常清楚,用户态只能访问用户空间,内核态可以访问用户空间和内核空间。那么在ARM64架构下这是如何实现的呢?
首先,ARM64定义了多种地址转换策略,即translation regime。而Linux内核选择的地址转换策略是Non-secure EL1&0 translation regime,如下图所示:
从上图我们可以看出以下几点:
- 支持two steps地址转换,即VA先转换为IPA,IPA在转换为最终的PA,当然这里也可以选择关闭IPA到PA的转换,那么相当于VA直接转换为PA,Linux中选择的就是这种方案。
- 该地址转换策略可以用于el0和el1的地址转换,由于Linux的策略是用户态工作在el0,内核态工作在el1,所以该地址转化策略可以用于用户态和内核态的地址转换。
地址转换表TTBR
配置Non-secure EL1&0 translation regime的寄存器有两个,分别是TTBR0_EL1和TTBR1_EL1,前者用于低地址空间的转换,后者用于高地址空间的转换,也就是用户空间通过TTBR0_EL1来做地址转换,而内核空间通过TTBR1_EL1来做地址转换。这要要注意的是,ARM64知识定义了TTBR0_EL1用于低地址空间的转换,TTBR1_EL1用于高地址空间的转换,但是并没有定义低地址空间对应用户空间,高地址空间对应内核空间,这个方案是Linux自己选择的。那么这里就有一个问题,Linux是如何实现内核态可以访问用于空间和内核空间,而用户态只能访问用户空间的呢?地址转换表中有一个UXNTable属性,可以控制EL0状态下执行时是否可以使用该地址转换表。这样就很容易实现用户态只能访问低地址空间了。
copy_from_user
static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
{unsigned long res = n;kasan_check_write(to, n);if (access_ok(VERIFY_READ, from, n)) {check_object_size(to, n, false);res = __arch_copy_from_user(to, from, n);}if (unlikely(res))memset(to + (n - res), 0, res);return res;
}
- 检查用户空间地址是否正确
这一步很有必要,试想一下,如果用户做系统调用时,故意传了一个内核地址下来,如果这里不做检查,这里将是一个很大的漏洞,可以轻而易举的对内核搞破坏。 - 将用户空间的数据拷贝到内核空间,由于内核空间可以访问用户空间的数据,所以这里的拷贝动作很容易实现。此外这里拷贝的时候貌似用到了热补丁技术,由于热补丁的内容比较多,我们暂时不做分析,后面一定会有专门的文章介绍,我们这里先明确,内核空间可以很容易的将用户空间的数据拷贝到内核空间,反过来当然也一样。
copy_to_user
static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
{kasan_check_read(from, n);if (access_ok(VERIFY_WRITE, to, n)) {check_object_size(from, n, true);n = __arch_copy_to_user(to, from, n);}return n;
}
同copy_from_user,不在赘述。
linux 内核函数 copy_from_user和copy_to_user 介绍相关推荐
- linux应用调用内核函数,Hooking linux内核函数(一):寻找完美解决方案
前言 我们最近参与了一个Linux系统安全相关项目,需要hooking几个重要的Linux内核函数调用,例如打开文件和启动进程,并利用它来启用系统活动监控并抢先阻止可疑进程. 最后,我们发明了一种有效 ...
- linux内核教学的全套视频,中科大老师全程讲解Linux内核分析视频教程《附加介绍+总结》共23节课...
中科大老师全程讲解Linux内核分析视频教程<附加介绍+总结>共23节课" F4 u& {+ T) p5 G' W ]; o% m 2 q: ]. j8 I; q' D ...
- linux内核函数出错的返回值
linux内核函数出错的返回值 1. 函数返回指针 2. 如何通过错误信息指针来返回错误信息 3. 出错代码返回指针在(-1000,0)区间 4. 错误的判断和错误原因的打印 4.1 错误的判断 4. ...
- 如何替换一个Linux内核函数的实现-热补丁原理
昨晚发过誓了.不会再接着写二进制hook的手艺了,今天有网友咨询技术细节,终于又忍不住了- 为了不违背即便是胡乱说出口誓言,今天不写二进制hook,今天用C语言写,二进制只是沾点边儿! 看题目, 替换 ...
- linux内核函数kmalloc,Linux内核内存分配函数之devm_kmalloc和devm_kzalloc
本文介绍Linux内核内存分配函数devm_kmalloc()和devm_kzalloc(). 一.devm_kmalloc 文件:drivers/base/devres.c,定义如下: /** * ...
- linux内核函数open源码,open()在Linux内核的实现(1)-基本实现
原标题:open()在Linux内核的实现(1)-基本实现 1.基本说明 在用户态使用open()时,必须向该函数传入文件路径和打开权限.这两个参数传入内核后,内核首先检查这个文件路径存在的合法性,同 ...
- Linux内核调试原理和工具介绍--理解静态插装/动态插装、tracepoint、ftrace、kprobe、SystemTap、Perf、eBPF
可以将linux跟踪系统分成Tracer(跟踪数据来自哪里),数据收集分析(如"ftrace")和跟踪前端(更方便的用户态工具). 1. 数据源(Tracers) printk 是 ...
- linux内核函数 ffs,linux内核中的宏ffs(x)【转】
linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __ ...
- linux内核函数 ffs,linux内核中的宏ffs(x)
转自:https://www.cnblogs.com/fengeryi/p/3449720.html linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/incl ...
最新文章
- .pgr照片文件解析,C++与Java存储数据差别大小端模式
- 当我们拿到数据进行建模时,如何选择更合适的算法?
- 最长公共子序列(LCS)问题算法详解+例题(转换成LIS,优化为O(nlogn),看不懂你来打我)
- Ext智能提示 - Spket(Eclipse插件)
- 安全框架 - Shiro与springMVC整合的注解以及JSP标签
- 重装华为服务器系统软件,服务器系统重装软件
- python 两阶段聚类_使用Python进行层次聚类
- 编译linux3内核,与busybox,用qemu模拟运行
- ITK:向转换工厂注册非默认转换
- All in Linux:一个算法工程师的IDE断奶之路
- Unix环境高级编程的学习环境的搭建
- thought works培训总结
- bin文件怎么打开 linux,BIN 文件扩展名: 它是什么以及如何打开它?
- CentOS7用YUM方式安装MySQL5.7
- Python中的global关键字的用法
- 《罗马革命》豆瓣 9.1 从恺撒大帝到屋大维
- Error: Cannot find module ‘@/views/xxx‘ at webpackEmptyContext
- 图片可以360度旋转类似广告代码
- boolean mct_object_set_parent(mct_object_t *object, mct_object_t *parent) 有感
- 【Codeforces Round #172】Codeforces 280D k-Maximum Subsequence Sum