宋宝华:为了不忘却的纪念,评linux5.13内核(上集)

宋宝华 宋宝华     2022-12-23     399

关键词:

5.14-rc6了,看起来5.14也快发布了。而我5.13的总结还没有写出,我早觉得有写一点东西的必要了,这虽然于搬砖的码农毫不相干,但在追求上进的工程师那里,却大抵只能如此而已。为了不忘却的纪念,我们列出5.13内核的10个激动人心的新特性。上集先谈4个:

  1. Apple M1的初始

  2. Misc cgroup

  3. Landlock安全模块

  4. 系统调用的堆栈随机化

Apple M1的初始支持

5.13最爆炸性的新闻无非是初始的Apple M1支持,但是然并卵,实用性几乎为0。因为,已经合入的patch非常类似于SoC bringup的初级阶段:

  • 带earlycon支持的UART (samsung-style) 串口驱动

  • Apple中断控制器,支持中断、中断亲和(affinity )和IPI (跨CPU中断)

  • SMP (通过标准spin-table来支持)

  • 基于simplefb的framebuffer驱动

  • Mac Mini的设备树

这样一个东西,是没法用的,发烧友玩玩可以,但是我们感激并欣赏Hector Martin “marcan”领导的Asahi Linux项目开了一个这样的好头。但是,在Apple M1上面跑Ubuntu啥的,近期、中期和长期的选择还是用Parallels虚拟化技术比较好。

Misc cgroup

众所周知,cgroup具备一个强大的控制CPU、内存、I/O等资源在不同的任务群间进行分配的能力。比如,你通过下面的命令,限制A这个群的CFS调度类进程,最多只能耗费20%的CPU:

这个世界上的绝大多数资源都是可以进行抽象的,比如属于cpuacct、cpu、memory、blkio、net_cls什么的,但是,总有一些不同于常人的人,他们既不是男人,也不是女人,而是“妖如果有了仁慈的心”的人。Linux内核的驱动子系统多达100多个,但是还是有极个别驱动不属于这100多类中的任何一类,于是在drivers下面有个misc:

现在内核碰到了类似的问题,它的资源要进行配额控制,但是不属于通用的类型,而是:

  • Secure Encrypted Virtualization (SEV) ASIDs

  • SEV - Encrypted State (SEV-ES) ASIDs

这些有限的 ASIDs用于在AMD平台上,进行虚拟机内存加密,不能归于现有cgroup的任何一类。那么,咱们加个misc类的cgroup吧,于是Misc control-group controller在5.13内核诞生了。这再次证明了,不要重新造轮子,但是你可以在现有的轮子里面放一个“杂交”轮子。Misc cgroup允许进行一些特殊资源的控制,透过3个接口完成。

  • misc.capacity描述资源的能力(只读),比如:

$ cat misc.capacity
res_a 50
res_b 10
  • 透过misc.current描述当前资源的占用(只读),比如:

$ cat misc.current
res_a 3
res_b 0
  • 透过misc.max设置这个cgroup最多只能使用多少资源(可读可写),比如:

# echo res_a 1 > misc.max

同志们,有了这个misc cgroup的支持,以后咱们的阿猫阿狗资源限制,也可以往里面塞了。它相当于开了一道门。

 

Landlock安全模块

曾经有一个真诚的patch摆在我面前,但是我没有珍惜,发了V1被人怼了后就放弃了,等到失去的时候才后悔莫及,尘世间最痛苦的事莫过于此,如果上天可以给我一个机会再来一次的话,我会对那个patch说我要继续迭代发!如果非要在这个迭代的次数上加上一个期限,我希望是一百遍。5.13内核,最励志的事情无疑是,"Landlock" Lands In Linux 5.13 !在迭代了超过5年之后,安全组件landlock终于合入了Linux内核,这份始于2016年的爱情,终于有了一个美好的结局。为此,Linux内核doc的维护者,LDD3的作者之一Jonathan Corbet发文指出:Kernel development is not for people who lack persistence; changes can take a number of revisions and a lot of time to make it into a mainline release。文章链接:

https://lwn.net/Articles/859908/

所以,没有耐力、不能持之以恒,想一夜暴富的人,真地不适合做kernel开发。Landlock LSM主要给非特权进程提供安全沙盒的能力,比如你可以对一个普通进程,施加自定义的文件系统访问控制策略。

它的操作原理是,先创建一个规则集ruleset,比如,如下的ruleset就是涉及到文件的读、写、执、读DIR、写DIR等:

ruleset对用户以文件描述符fd的形式存在,再次证明了“一切都是文件”。接下来,我们可以透过这个fd,向这个ruleset里面添加rule,比如我们添加一个/usr目录的“读”规则,这样进程就不能写/usr了:

我们把这个ruleset施加起来让它生效:

想要体验的童鞋可以用这个例子启动你的进程,它设置好ruleset后,会去call exec启动命令行参数指定的程序:

https://github.com/landlock-lsm/linux/blob/landlock-v34/samples/landlock/sandboxer.c

LL_FS_RO环境变量是可读文件的列表,LL_FS_RW环境变量是可读写文件的列表,运行方法:

LL_FS_RO=”只读路径” \\
LL_FS_RW=”可写路径” \\
sandboxer  ./a.out

a.out是你的想要安全沙盒的程序。

在下已经一睹为快,在/home/baohua下面创建2个目录1,2,然后创建/home/baohua/1/1和/home/baohua/2/1这2个文件,限制第一个目录只读:

童鞋们看明白了吗?我用sandboxer去启动cat,2个文件都是成功的。但是,去启动echo,/home/baohua/1/1是不允许写的,但是/home/baohua/2/1是可以写的。实际上,/home/baohua/1/1和/home/baohua/2/1并没有丝毫的不同。landlock在发挥作用了!

系统调用的堆栈随机化

这是一项安全增强,它允许对系统调用发生时,内核使用的堆栈添加一个随机偏移。这给基于stack的攻击增加了难度,因为stack攻击通常要求stack有个固定的layout。现在每次系统调用,stack的layout都变化的话,黑客就比较捉摸不定了。比如ARM64主要修改了invoke_syscall()这个函数:

这个东西听起来很高大上,但是它的原理可能简单地你想哭,show me the code:

它实际上就是每次系统调用把offset随机化一下,然后通过__builtin_alloca()从stack里面分配一些stack空间,于是导致stack的位置移动。我们可以写个非常简单的应用程序来验证原理:

然后编译

gcc 1.c  -fno-stack-protector -O0

运行:

亲爱的,你有没有发现,10次函数调用的时候,每次stack临时变量的位置都不一样!!?

本文未完待续,您的赞赏将鼓励我的原创

宋宝华:为了不忘却的纪念,评linux5.13内核(上集)

5.14-rc6了,看起来5.14也快发布了。而我5.13的总结还没有写出,我早觉得有写一点东西的必要了,这虽然于搬砖的码农毫不相干,但在追求上进的工程师那里,却大抵只能如此而已。为了不忘却的纪念,我... 查看详情

2021年九月上旬文章推荐(代码片段)

《如何在Linux中实时监控日志文件|Linux中国》《宋宝华:为了不忘却的纪念,评Linux5.13内核https://mp.weixin.qq.com/s/SLAl366XO-Eh4pkri2XcBA》《Linux阅码场原创精华文章汇总》目录如何在Linux中实时监控日志文件|Linux中国 宋宝华ÿ... 查看详情

宋宝华:评linux5.13内核(代码片段)

目录MisccgroupLandlock安全模块系统调用的堆栈随机化printk无锁ringbuffer的进一步优化BPF可调用内核函数公共的IOPAGEFault支持Linux5.14于14小时之前发布了,而我5.13的总结还没有写出,我早觉得有写一点东西的必要了,这虽然... 查看详情

为了忘却的纪念——2022linux内核十大技术革新功能|年终盘点

...x内核开发者、经典书籍《Linux设备驱动开发详解》作者宋宝华老师为大家解剖2022年Linux内核开发的十大革新技术功能ÿ 查看详情

宋宝华-docker背后的故事之名称空间

名称空间是在OS之上实现容器与主机隔离,以及容器之间互相隔离的Linux内核核心技术。根据《Docker最初的2小时(Docker从入门到入门)》一文,名称空间本质上就是在不同的工作组里面封官许愿,让大家在各自的部门里面都是manager... 查看详情

宋宝华:slab在内核内存管理和用户态memcached的双重存在

很多基础的概念,将跨越软件的层次而存在。比如slab,对于内核人员,我们都知道slab是buddy之上的一层。因为buddy作为Linux内核最底层的内存管理器,它分配1页,2页,4页,2^n页,但是作为内核的堆... 查看详情

宋宝华:slab在内核内存管理和用户态memcached的双重存在

很多基础的概念,将跨越软件的层次而存在。比如slab,对于内核人员,我们都知道slab是buddy之上的一层。因为buddy作为Linux内核最底层的内存管理器,它分配1页,2页,4页,2^n页,但是作为内核的堆... 查看详情

宋宝华:cpu是如何访问到内存的?-mmu基本原理

由于很多童鞋大学的时候学《微机原理》都是打酱油,当老师苍蝇在讲台上发噪音,导致MMU这些基本知识都没有搞清楚,所以对计算机的认识一塌糊涂,Linux也无法学通。然后我经常被问到吐血,我觉得我不得不写点什么东西,让... 查看详情

宋宝华:关于dmazone和dma_alloc_coherent若干误解的澄清

本文已首先在Linuxer公众号(ID:LinuxDev)发表,现转回我的blog也发表。转载请注明出处。1.DMAZONE的大小是16MB?这个答案在32位X86计算机的条件下是成立的,但是在其他的绝大多数情况下都不成立。首先我们要理解DMAZONE产生的历... 查看详情

宋宝华:docker最初的2小时(docker从入门到入门)

最初的2小时,你会爱上Docker,对原理和使用流程有个最基本的理解,避免满世界无头苍蝇式找资料。本人反对暴风骤雨式多管齐下狂轰滥炸的学习方式,提倡迭代学习法,就是先知道怎么玩,有个感性认识,再深入学习高级用... 查看详情

宋宝华:关于linux内存管理中dmazone和dma_alloc_coherent若干误解的澄清

本文已首先在Linuxer公众号(ID:LinuxDev)发表,先转回我的blog也发表。转载请注明出处。1.DMAZONE的大小是16MB?这个答案在32位X86计算机的条件下是成立的,但是在其他的绝大多数情况下都不成立。首先我们... 查看详情

宋宝华:迭代螺旋法——关于linux学习方法的血泪建议

在下是一个码农,也号称是一个老湿,平生阅码农无数(吹牛的^-^)。经由大量的案例,我能够理解了为什么很多码农学了很多年Linux,还是感觉没有掌握要领,仍然内心崩溃,最终对Linux吐血而亡,正所... 查看详情

宋宝华:谈一谈linux写时拷贝(cow)的安全漏洞(代码片段)

写时拷贝的原理我们没什么好赘述的,就是当P1fork出来P2后,P1和P2会以只读的形式共享page,直到P1或者P2写这个page的内容,才发生pagefault导致写的进程得到一份新的数据拷贝。 下面的代码演示了它的效果:int... 查看详情

宋宝华:世上最好的共享内存(linux共享内存最透彻的一篇)上集

共享单车、共享充电宝、共享雨伞,世间的共享有千万种,而我独爱共享内存。早期的共享内存,着重于强调把同一片内存,map到多个进程的虚拟地址空间(在相应进程找到一个VMA区域),以便于CPU可... 查看详情

宋宝华:docker最初的2小时(docker从入门到入门)(代码片段)

最初的2小时,你会爱上Docker,对原理和使用流程有个最基本的理解,避免满世界无头苍蝇式找资料。本人反对暴风骤雨式多管齐下狂轰滥炸的学习方式,提倡迭代学习法,就是先知道怎么玩,有个感性认识,再深入学习高级用... 查看详情

宋宝华:谈一谈linux写时拷贝(cow)的安全漏洞(代码片段)

写时拷贝的原理我们没什么好赘述的,就是当P1fork出来P2后,P1和P2会以只读的形式共享page,直到P1或者P2写这个page的内容,才发生pagefault导致写的进程得到一份新的数据拷贝。 下面的代码演示了它的效果:int... 查看详情

纪念品分组

...,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。输入输出... 查看详情

2007纪念品分组

...,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目 查看详情