内核功能导致重启_内核可靠性加固技术研究

1 背景

最近一直在关注内核安全加固相关技术。从安全和可靠性领域来看,有一部分技术是重叠的。安全领域将内存USE After Free,Stack溢出,DOS攻击作为安全漏洞。可靠性认为这些问题会导致系统重启故障,属于可靠性范畴。从今年开始,我专门跟踪了kernel几个安全领域项目,收获不少。

2,kernel开源项目

大家有兴趣的可以订阅一下邮件列表:

http://www.openwall.com/lists/kernel-hardening/

技术1:arm64: kernel: Add support for Privileged Access Never

'Privileged Access Never' is a new arm8.1 feature which prevents privileged code from accessing any virtual address where read or write access is also permitted at EL0. This patch enables the PAN feature on all CPUs, and modifies {get,put}_user helpers temporarily to permit access.This will catch kernel bugs where user memory is accessed directly. 'Unprivileged loads and stores' using ldtrb et al are unaffected by PAN. 这个特性是kernel-hardening最近提交的一个特性,原理是这样的:

ARM8.1 CPU特性增加了一个flag:

A new Privileged Access Never (PAN) state bit. This bit provides control that prevents privileged access to user data unless explicitly enabled; an additional security mechanism against possible software attacks

这个特性可以实现的功能:当对cpu使能PAN bit后,cpu执行在EL0(内核代码执行的时),是无法访问TTBR0指向的虚拟空间地址的。例如当你在内核态代码执行的时候,计划访问0x0-0x0000FFFFFFFFFF,如果不打开PAN状态,则内核直接会导致OOPS。

具体实现代码:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=338d4f49d6f7114a017d294ccf7374df4f998edc

对我们参考价值:可靠性领域合入此特性后,可以杜绝内核态通过进程虚拟地址去修改进程数据,提供了一定内核和用户态的内存隔离。

技术2:Add support for eXclusive Page Frame Ownership (XPFO)

https://lwn.net/Articles/700606/

技术1只能杜绝内核态通过进程虚拟地址去修改进程数据问题,但是还有一种内核态修改用户进程的场景无法进行隔离。内核态执行可以通过内核映射页表直接修改物理页数据,如果对应的物理页已经被用户态程序使用了,则会直接破坏对应程序的用户态数据。Linux内核会在开机启动的时候创建内核页表,将大部分物理页映射到内核的虚拟地址空间内。考虑一种场景,内核申请一个物理page,然后释放了这个page给BUDDY系统,由于BUG等原因,后续代码仍旧在使用它;这个时候此page被分配到了一个用户态进程,这样就出现了内核态破坏用户进程的问题。此patch给出了一个方案,其实我们在两年前的一个思路,就是将用户态空间的物理页对应的内核页表设置为只读或清零。当时由于技术水平有限,无法实现。没想到他们作为一个安全特性进行了提交。现在此patch只实现了x86上,但是对于ARM是类似的。

现在提交patch有如下几个:

http://www.openwall.com/lists/kernel-hardening/2016/11/04/3

http://www.openwall.com/lists/kernel-hardening/2016/11/04/4

http://www.openwall.com/lists/kernel-hardening/2016/11/04/5

依赖的特性:https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=46f24fd857b37bb86ddd5d0ac3d194e984dfdf1c

本patch实现原理:

1.在page_alloc路径上根据GFP_FLAGS里面HIGHUSER,决定是否page是内核还是用户态,如果没有这个标记,则在page_ext上设置状态为PAGE_EXT_XPFO_KERNEL,否则清理PAGE_EXT_XPFO_KERNEL标记。

2. 在kunmap增加hook,如果kunmap的page不是PAGE_EXT_XPFO_KERNEL,则将page设置PAGE_EXT_XPFO_UNMAPPED,将对应page的内核页表设置为0。这个地方没有理解清楚,kunmap的内存不是内核态申请的,具体是什么场景?

3. kmap的page不是PAGE_EXT_XPFO_KERNEL,即用户态的内存,则将page的PAGE_EXT_XPFO_UNMAPPED清除,然后页表恢复

4. 当free page到buddy系统时候,将page的PAGE_EXT_XPFO_UNMAPPED清除,然后页表恢复。

不足:

1. 如果内核地址空间映射不是4K page怎么办?

对于arm/arm64来说,内核映射不是4k为单位进行映射的,使用的1M section映射模式

2. 性能影响是多大呢

主要涉及到tlb shootdown(The actions of one processor causing the TLBs to be flushed on other processors is what is called a TLB shootdown)问题

3. 此patch现在解决是内存先被用户态申请之后,内核通过kmap/kunmap访问这个page,如果调用kunmap之后,内核再使用addr去访问物理内存,则会直接panic。如果内存没有被用户态使用,内核仍旧拿着这个指针,当用户态申请之后,则无法访问。

对我们的参加价值:我们可以做一个类似patch,将用户态申请走的内存不允许内核态进行访问,可以作为一种故障隔离定位手段。这个后续需要专门研究一下:为什么不在page alloc时候直接将内核态页表设置unmapped state,当内核使用kmap/kunmap显示访问用户进程内存的时候,再放开权限。

技术三:CONFIG_HARDENED_USERCOPY特性

本身这个特性https://lwn.net/Articles/691012/

已经合入主线:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=f5509cc18daa7f82bcc553be70df2117c8eedc16

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=dfd45b6103c973bfcea2341d89e36faf947dbc33

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=faf5b63e294151d6ac24ca6906d6f221bd3496cd

想法也比较简单,就是在内核调用

copy_to_user() and copy_from_user() on the kernel object being copied to/from:

- address range doesn't wrap around

- address range isn't NULL or zero-allocated (with a non-zero copy size)

- if on the slab allocator:

- object size must be less than or equal to copy size (when check is implemented in the allocator, which appear in subsequent patches)

- otherwise, object must not span page allocations (excepting Reserved and CMA ranges)

- if on the stack

- object must not extend before/after the current process stack

- object must be contained by a valid stack frame (when there is arch/build support for identifying stack frames)

- object must not overlap with kernel text

现在ARM/ARM64已经支持,后续可以移植到kernel 4.1上看看是否我们有类似的问题。

后记:

这三个特性对我们后续在内核可靠性方面是有比较大的帮助。

第二个特性社区实现还很不完善,后续可以沿着他的思路做一部优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值