LWN:不再export kallsyms_lookup_name()!

【深入解析】Linux模块化设计(6):从 /proc/kallsyms 到 kallsyms_lookup_name:内核符号查找机制深度揭秘 作用:根据给定字符串名字,返回该符号对应的地址;其实现是一个遍历内核符号表(kallsyms)的过程。是内核内置符号表查询器;它帮助模块动态解析未导出的符号;默认不导出,需要自行改内核启用;是用户态访问的窗口。 阅读详情

关注了就能看到更多这么棒的文章哦~

Unexporting kallsyms_lookup_name()

By Jonathan Corbet
February 28, 2020

原文来自:https://lwn.net/Articles/813350/

kernel module开发中有一条基本原则,module只能访问那些明确export出来的符号(symbols,指函数和数据结构)。甚至,有许多symbol明确指明了只有哪些兼容GPL license的module才可以访问。不过,现在看来其实有一些workaround方式,可以让module来访问任意的symbol。这个workaround方式很快会被堵上,尽管这会导致一些使用者碰到问题。这个事情的来龙去脉值得给大家详细讲讲。

这个后门就是kallsyms_lookup_name(),它会利用kernel的symbol table来查找,返回指定symbol的地址。module的代码直接访问symbol的话都会被拒绝,但是可以利用kallsyms_lookup_name()来获取地址,然后直接使用这个地址。这个函数本身被export为GPL-only的,理论上来说只有free software(自由软件)才能使用它。不过如果某个proprietary(专有的、私有的) module先通过虚假声明一个自由软件的license,那么就能访问到这些GPL-only的symbol。这种事情发生了不止一次。

Will Deacon提交了一组patch set,移除了对kallsyms_lookup_name()和kallsyms_on_each_symbol()的export声明。马上就有许多人对此表示赞同。毕竟很少有kernel开发者愿意看到module作者能有办法绕过export的限制。不过,还是有些人表达了一些担心。

其中一个问题在于,有一些out-of-tree用户在利用kallsyms_lookup_name(),这种用法其实开发者们都能理解、也认为是合理的,这就是用作kernel的live-patching系统。很讽刺的是,kernel bug通常都有export出来的函数,那么可以使用live patch来确定kernel里某个函数的位置,从而对它进行修补。kallsyms_lookup_name()可以很轻松地实现这个功能。在讨论中,Joe Lawrence提醒大家要多用用kpatch系统,它完全可以替代kallsyms_lookup_name()在live patch中的作用,并且在mainline kernel中已经完全可用了。不过,看起来Ksplice系统还在使用kallsyms_lookup_name。不过Miroslave Benes说了句大实话:“没人关心现在kernel里的ksplice功能”。这样看来,live patch功能应该不会阻止这组patch set的合入了。

Masami Hiramatsu提出了另一个问题,在kernel里面其实还有其他一些方法可以拿到kernel symbol对应的地址。User space可以使用kprobe来提取这些信息,kernel module也可以利用snprintf()的“%pF”格式(会打印出某个函数的对应地址)来遍历获取symbol地址(当然这个比较费时间和CPU资源)。他有点担心做了这个改动之后,普通开发者会碰到一些麻烦,而真正想要滥用module机制的人却不会担心这点麻烦。

Deacon回复的时候,解释了一下他做这个改动的来龙去脉。虽然Kernel开发者们都很喜欢做这些会让滥用Linux系统的人碰到更多麻烦的事情,不过这次来说,他的动力其实是为了帮Google解决一个问题。

在2018年的时候,LWN就报道过,为了能让Android kernel跟mainline尽量接近,有许多工作在进行中。其中之一就是把kernel放到Android generic system image (GSI)里,这是一个通用的Android image版本,可以在任何满足了Android的要求的设备上直接启动并正常运行。把kernel作为GSI的一部分,就意味着硬件厂商不能再修改kernel,所以就只能通过在GSI增加kernel module的方式来实现他们所要做的功能。

通过限制供应商只能使用kernel module,就能限制住他们所做的大多数改动。比如,不会再有Android设备能把CPU scheduler换成vendor自己的特制版本。不过,这就要求module必须只能使用这些export出来的symbol。如果module开始利用kernel里任意的代码,那么这个保护就完全没有意义了。Deacon虽然没有明说,不过看起来很明显有些厂商就在考虑这么做(译者注:哈哈,太鸡贼了吧大家~就不能跟Google好好玩吗?)。所以,要对移除这个接口的export做个冠冕堂皇的解释的话,就是:“如果kallsyms_lookup_name()包含了所有的数据和函数,那么就无法有效地监控和管理ABI接口”。

Hiramatsu接受了这个解释,回复了自己的Reviewed-by tag。所以,他原本担心的问题,也不会组织这组patch set被合入了。

其实,再说一遍,仅仅“给那些绕过export机制的module开发者找些麻烦”这个理由,就足够推动大家合入这个patch set了。不过很有意思的是看到一个大公司也支持这种做法。Google在把Android kernel跟mainline绑定得更加紧密之后,它和kernel社区的长期目标(至少在文中讲到的这一点上)也更加吻合了。希望这种吻合能够在我们那些使用了更像mainline kernel的设备上,为我们带来更好的kernel!

全文完

LWN文章遵循CC BY-SA 4.0许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注LWN深度文章以及开源社区的各种新近言论~

Unexporting kallsyms_lookup_name kallsyms_lookup_name函数可以通过函数名字获取对应的地址。unexporting kallsyms_lookup_name意味着out-of-tree的驱动不能够利用kallsyms_lookup_name函数调用未导出的内核函数。 unexporting kallsyms_lookup_name可能会造成的影响如下: live patch:live patch需要kallsy... 阅读详情

相关推荐

Vmware安装windowsServer2022版本

全网最详细的Vmware安装windowsServer2022版本

A乐神的博客 7005

Linux 内核函数kallsyms_lookup_name

Linux 内核函数kallsyms_lookup_name 函数的使用以及其源码解析

小立仔 5434

YF-S401水流量传感器在STM32上的精准计量实现

本文详细介绍了YF-S401水流量传感器与STM32微控制器的集成应用,实现精准水流计量。通过外部中断和外部时钟两种脉冲计数方案,结合硬件配置、软件滤波和校准技巧,确保高精度流量测量。适用于智能家居和工业自动化中的水控系统,提升系统稳定性和测量准确性。

rainy的博客 896

kallsyms_lookup_name使用简介

使用kallsyms_lookup_name函数,可以在内核态实现类似动态链接的功能,是的模块之间的依赖进一步解耦合。

microsko的专栏 4214

智能座舱测试工程师必看:从零搭建自动化测试框架的5个实战技巧

本文为智能座舱测试工程师提供从零搭建自动化测试框架的5个实战技巧,涵盖环境搭建、ADB高级应用、Python脚本工程化、Monkey测试优化及性能调优。通过ADB深度操作和Python脚本封装,帮助测试人员构建高可复用的智能座舱测试解决方案,显著提升测试效率与问题发现率。

python9snake的博客 632

SolidWorks的GB库(钢型材库,包括铝型材、铝管等结构)安装及使用教程(生成铝型材为例)

1、GB库的下载 2、GB库的安装教程 3、GB库的使用教程

树下等苹果的博客 12万+

内核查找符号指针函数kallsyms_lookup_name

openEuler linux kernel kallsyms_lookup_name

yongjong的专栏 4895

合宙ESP32C3实战:MPU6500六轴传感器数据读取与校准全解析

本文详细解析了如何使用合宙ESP32C3开发板读取和校准MPU6500六轴姿态传感器数据。从硬件接线、开发环境搭建到核心代码解析,提供了全面的实战指南,帮助开发者快速掌握传感器配置与数据处理技巧,适用于姿态控制、运动检测等应用场景。

weixin_27066963的博客 404

Linux内核编程——进程内存窥探修改器(全网最详)

Linux内核编程——进程内存窥探修改器 文章目录Linux内核编程——进程内存窥探修改器关键词主要功能设计思路代码解读运行结果遇到的问题内容总结参考文献 关键词 内核模块法;带参数的系统调用;虚拟内存管理;虚拟地址映射为物理地址;私有内存的入侵读写; 主要功能 使用内核模块法向Linux内核增加两个系统调用,系统调用号分别为335和336 。 335号系统调用:使用此系统调用能够读取任意进程的任意虚拟地址范围内的内容。 336号系统调用:使用此系统调用能够修改任意进程的任意虚拟地址范围内的内容。 两者都

life_forwin的博客 3030

【ROS机器人系统】自主导航+YOLO目标检测+语音播报

完成自主导航功能,并在小车移动至指定地点的过程中,通过机器人的摄像头检测导航途中所见物体,识别出物体的种类(框选出不同物体并标注识别结果),结合科大讯飞语音合成模块对识别结果进行语音播报。..............................

南京大学软件工程硕士在读 2万+

LVGL 磁罗盘效果

环境:LVGL 9.x + SDL2,窗口 1280×800。界面文案用英文(默认 Montserrat,无 CJK)。本文按实现顺序讲:先建立两个耦合转动体,再把磁倾角误差从卡面倾斜里推出来,最后用同一套投影把刻度、数字和目标画到卡上。画面上的迟滞、涡流、摆动和读数偏差都来自方程,没有补间动画。

摸鱼专家 85

linux内核查找符号

从Linux内核的2.6某版本开始,内核引入了导出符号的机制,在内核中使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL导出的符号可以在其他内核模块中直接使用。但是并不是所有的符号都被导出了,这时候如果想要使用未导出的符号呢? 1.kallsyms_lookup_name读取 依赖于CONFIG_KALLSYMS,kallsyms_lookup_name在大多数情况下是被导出了,可...

faxiang1230的专栏 2290

从地方政府网站抓取政务公开数据:Python爬虫技术详解

在本文中,我们通过具体实例介绍了如何使用Python编写爬虫,从地方政府门户网站抓取政务公开数据。我们使用了requestsSelenium等最新技术,结合SQLite数据库存储抓取的数据,最后使用matplotlib进行数据可视化分析。通过本项目,您可以掌握如何抓取政府网站的公开数据,并将其进行清洗、存储和分析。这些技术对于进行政府政策分析、公共服务分析等方面具有重要的实际意义。希望通过本文的介绍,您能够更好地理解政务数据抓取的流程和方法,并能在实际工作中运用这些技术进行数据采集和分析。

2201_76125261的博客 1701

通过系统调用,内核断点方法定位用户进程被内核踩内存的问题

1、系统调用拦截 系统调用拦截的目的其实就是把系统真正要执行的系统调用替换为我们自己写的内核函数,这里有一篇博客,对此作了介绍,https://blog.youkuaiyun.com/zhangyifei216/article/details/49872861 系统调用拦截的两个问题,一个是找到sys_call_table地址,一个是修改内存页的属性,让其变为可写。 1)找sys_call_table地址 我...

sunshineywz的博客 768

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Linux内核系统调用劫持之kallsyms

1.通过kallsyms方式 基于Linux 5.0/Linux5.3 的X86-64系统. 1. 通过kallsyms_lookup_name查找sys_call_table地址. 2. 关闭写保护 3. 修改sys_call_table Linux5.0上直接调用write_cr0接口,能够顺利的修改CR0寄存器,而内核版本更新到Linux5.3以后,发现对CR0的修改进行了保护,所...

bin_linux96的专栏 1868

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Linux 驱动之 EXPORT_SYMBOL 函数以及 2.6 内核 Unknown symbol bug 解决办法

1、Linux中EXPORT_SYMBOL的用法 EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用。您还可以手工修改内核源代码来导出另外的函数,用于重新编译并加载新内核后的测试。 //mod1.c 编译模块mod2,成功。 加载mod2时,输出: insmod: error inserting 'mod2.ko': -1 Invalid parameters dmesg查看: mod2: no symbol version for func

ZP1015 3707

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【转】linux内核kallsyms机制分析

一、前言 Linux内核是一个整体结构,而模块是插入到内核中的插件。尽管内核不是一个可安装模块,但为了方便起见,Linux把内核也看作一个模块。那么模块与模块之间如何进行交互呢,一种常用的方法就是共享变量和函数。但并不是模块中的每个变量和函数都能被共享,内核只把各个模块中主要的变量和函数放在一个特定的区段,这些变量和函数就统称为符号。 因此,内核也有一个module结构,叫做k...

weixin_34247299的博客 641

kallsyms.c 分析

190 .asciz "t.text.lock." 191 .asciz "text.lock." 192 .asciz "t.lock." 193 .asciz "lock." 210 .asciz "tex" 229 .asciz ...

我多么希望明天有太阳,来灼烧我腐烂的梦想 728

"no symbol version for xxx"在2.6.26内核上的问题

主要是2.6.26内核的module.c中check_version()发生了改变,在检查不到符号版本的时候返回0或者是-ENOEXEC,而之前的版本是返回1,导致的这个问题 2.6.26:代码如下: #ifdef CONFIG_MODVERSIONS static int check_version(Elf_Shdr *sechdrs,

敟當柒秒哋魚 2718

python装饰器调用顺序_python 多个装饰器的调用顺序分析

一般情况下,在函数中可以使用一个装饰器,但是有时也会有两个或两个以上的装饰器。多个装饰器装饰的顺序是从里到外(就近原则),而调用的顺序是从外到里(就远原则)样例:def func1(func):print(1)def inner1(*args, **kwargs):print(2)res = func(*args, **kwargs)print(3)return resprint(4)return...

weixin_39606019的博客 319

linux内核模块包含函数,linux 内核模块链接过程

原标题:linux 内核模块链接过程学无止境,一直在做内核开发,却从来没有仔细想过这个过程。因为所有的程序都有个编译,链接的过程。在linux内核模块中,我们可以使用很多内核export出的函数,来实现我们的功能,作为内核附属功能的扩展。但是这些export出来的函数在hook的时候是远远不够用的,所以我们往往还要获取一些没有export出来的函数。使用这些没有export出来的函数就要我们清楚的...

weixin_34668147的博客 418

获得内核函数地址的四种方法

优快云 GitHub 获得内核函数地址的四种方法 LinuxDeviceDrivers/study/debug/filesystem/procfs/func_addr 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处, 谢谢合作因本人技术水平和知识面有限, 内容如有纰漏或者需要修正的地方, 欢迎大家指正, 也欢迎大家提供一些其他好的调试工

OSKernelLAB(gatieme) 1万+

linux内核模块导出函数

一个模块可以使用另一个模块导出的函数,可以通过函数EXPORT_SYMBOL(func_name)来导出,导出后的函数位于/proc/kallsyms文件中。 1. 导出代码: #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dua...

weixin_33734785的博客 676

操作系统面经-什么是系统调用

处于用户态的进程有诸多限制(如不能进行 I/O 操作),所以有些功能必须由内核代劳完成。说白了,系统调用其实就是函数调用,只不过调用的是内核态的函数。控制寄存器的第 16 位是写保护位,若设置为零,则允许超级权限往内核中写入数据。是一份内核符号表,包含了内核中的变量名和函数名地址,在每次编译内核时,自动生成。当应用程序需要调用一个系统调用时,首先需要将要调用的系统调用号(也就是系统调用所在。了解了系统调用的原理后,要拦截系统调用就很简单了。是内核提供给应用程序使用的功能函数,由于应用程序一般运行在。

weixin_65113709的博客 2294

往linux内核函数挂钩子

概述 本文讲解替换一个已经在内存中的函数,使得执行流流入我们自己的逻辑,然后再调用原始的函数。比如有个函数叫做funcion,而你希望统计一下调用function的次数,最直接的方法就是如果有谁调用function的时候,调到下面这个函数就好了。 void new_function() {          count++;          return function(); } ...

Herok 5984
上一篇: LWN大作:Android display pipeline本身以及进程调度!
下一篇: LWN:high memory的末日快到了?
LinuxNews搬运工
博客等级 码龄7年 438粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值