From 42c5850b640825abf185331eae2ebd77d8b1b0ab Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 14:42:35 +0800 Subject: [PATCH 1/8] linux-kfence: commit correct result of tinycorrect-spaces Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index 4e6adcf..4152227 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,3 +1,4 @@ +> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces]
> Author: pwl999
> Date: 2022/04/28
> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
@@ -5,8 +6,8 @@ # Kfence 详解 -> Author: pwl -> Date: 2022-04-28 +> Author: pwl +> Date: 2022-04-28 ## 1. 原理介绍 @@ -23,7 +24,7 @@ Kfence 的主要特点如下: | 检测密度 | 抽样法,默认每 100ms 提供一个可检测的内存 | 对所有内存访问进行检测 | | 检测粒度 | 核心的检测粒度为 page | 检测粒度为字节 | -### 1.1 slub/slab hook +### 1.1 slub/slab hook Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。但并不是所有的 `slub/slab` 内存都会从 `kfence_pool` 内存池中分配。它规定了两个条件: @@ -142,7 +143,7 @@ void __init kfence_init(void) } ``` -### 2.4 kfence_alloc() +### 2.4 kfence_alloc() 内存分配流程: @@ -160,7 +161,7 @@ kfence_free() → __kfence_free() → kfence_guarded_free(): ## 参考文档 -1.[Linux内存异常检测工具—kfence](https://www.jianshu.com/p/f967086f9129) -2.[Kernel Electric-Fence (KFENCE)](https://www.kernel.org/doc/html/latest/dev-tools/kfence.html) -3.[Linux Kernel Sanitizers](https://gitee.com/mirrors/KASAN) -4.[Linux开源动态之一种新的内存非法访问检查工具KFence](https://www.cnblogs.com/liuhailong0112/p/14683431.html) +1. [Linux内存异常检测工具—kfence](https://www.jianshu.com/p/f967086f9129) +2. [Kernel Electric-Fence (KFENCE)](https://www.kernel.org/doc/html/latest/dev-tools/kfence.html) +3. [Linux Kernel Sanitizers](https://gitee.com/mirrors/KASAN) +4. [Linux开源动态之一种新的内存非法访问检查工具KFence](https://www.cnblogs.com/liuhailong0112/p/14683431.html) -- Gitee From 8a99200fa7e50bc3154de452c4d1fd3b5af27215 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 14:42:42 +0800 Subject: [PATCH 2/8] linux-kfence: commit correct result of tinycorrect-header Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index 4152227..a1156e1 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,6 +1,7 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces header]
> Author: pwl999
> Date: 2022/04/28
+> Revisor: Falcon
> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
> Sponsor: PLCT Lab, ISCAS -- Gitee From b9ba61ea7dfe99e1d18a91db0aa9aed1db2b7110 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 14:42:54 +0800 Subject: [PATCH 3/8] linux-kfence: commit correct result of tinycorrect-toc Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index a1156e1..3fc96c1 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces header]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces header toc]
> Author: pwl999
> Date: 2022/04/28
> Revisor: Falcon
@@ -10,7 +10,7 @@ > Author: pwl > Date: 2022-04-28 -## 1. 原理介绍 +## 原理介绍 Kfence (Kernel Electric Fence) 是 Linux 内核引入的一种低开销的内存错误检测机制,因为是低开销的所以它可以在运行的生产环境中开启,同样由于是低开销所以它的功能相比较 Kasan 会偏弱。 @@ -25,7 +25,7 @@ Kfence 的主要特点如下: | 检测密度 | 抽样法,默认每 100ms 提供一个可检测的内存 | 对所有内存访问进行检测 | | 检测粒度 | 核心的检测粒度为 page | 检测粒度为字节 | -### 1.1 slub/slab hook +### slub/slab hook Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。但并不是所有的 `slub/slab` 内存都会从 `kfence_pool` 内存池中分配。它规定了两个条件: @@ -34,7 +34,7 @@ Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。 ![](images/kfence/kfence_slub_hook.png) -### 1.2 out-of-bounds (over data page) +### out-of-bounds (over data page) 从 `kfence_pool` 中成功分配一个内存对象 `obj`,不管 `obj` 的实际大小有多大,都会占据一个 `data page`。 @@ -42,7 +42,7 @@ Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。 当原本访问 `obj` 的操作溢出到相邻的 `fence page` 时,会立即触发 CPU 异常,通过堆栈回溯揪出异常访问的元凶。 -### 1.3 out-of-bounds (in data page) +### out-of-bounds (in data page) 大部分情况下 `obj` 是小于一个 page 的,对于 `data page` 剩余空间系统使用 `canary pattern` 进行填充。这种操作是为了检测超出了 `obj` 但还在 `data page` 范围内的溢出访问。 @@ -50,7 +50,7 @@ Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。 这种类型的溢出是不能在溢出发生时立刻触发的,它只能在 `obj` free 时,通过检测 `canary pattern` 被破坏来检测到有 `canary` 区域的溢出访问。但是异常访问的元凶却不能直接抓出来。 -### 1.4 use-after-free +### use-after-free 在 `obj` 被 free 以后,对应 `data page` 也会被设置成不可访问状态。 @@ -58,15 +58,15 @@ Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。 这种状态下,如果有操作继续访问 `obj` 会立即触发 CPU 异常,通过堆栈回溯揪出异常访问的元凶。 -### 1.5 invalid-free +### invalid-free 在 `obj` free 时会判断记录的 malloc 信息,判断是不是一次异常的 free。 -## 2. 代码解析 +## 代码解析 分析以下关键的代码流程: -### 2.1 kfence_protect() +### kfence_protect() 把 `fence page` 设置成不可访问的核心就是通过 MMU 清除掉 PTE 中的 `present` 标志位: @@ -91,7 +91,7 @@ static inline bool kfence_protect_page(unsigned long addr, bool protect) } ``` -### 2.2 kfence_alloc_pool() +### kfence_alloc_pool() 在系统启动时保留 Kfence 需要用到的内存 Page,默认保留 255 个 `data page`: @@ -117,7 +117,7 @@ config KFENCE_NUM_OBJECTS default 255 ``` -### 2.3 kfence_init() +### kfence_init() ``` void __init kfence_init(void) @@ -144,7 +144,7 @@ void __init kfence_init(void) } ``` -### 2.4 kfence_alloc() +### kfence_alloc() 内存分配流程: @@ -152,7 +152,7 @@ void __init kfence_init(void) kmem_cache_alloc() → slab_alloc() → kfence_alloc() → __kfence_alloc() → kfence_guarded_alloc(): ``` -### 2.5 kfence_free() +### kfence_free() 内存释放流程: -- Gitee From 854f7d4517ce968c1d6c1e327a1eb6da5f90c5c2 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 15:35:52 +0800 Subject: [PATCH 4/8] linux-kfence: commit correct result of tinycorrect-tables Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index 3fc96c1..382696f 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [spaces header toc]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables]
> Author: pwl999
> Date: 2022/04/28
> Revisor: Falcon
@@ -21,7 +21,7 @@ Kfence 的基本原理非常简单,它创建了自己的专有检测内存池 Kfence 的主要特点如下: | item | Kfence | Kasan | -| -------- | ----------------------------------------- | ---------------------- | +|----------|-------------------------------------------|------------------------| | 检测密度 | 抽样法,默认每 100ms 提供一个可检测的内存 | 对所有内存访问进行检测 | | 检测粒度 | 核心的检测粒度为 page | 检测粒度为字节 | -- Gitee From 84f5ac341e8b2cfaec68c022a1241598a61ae8fc Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 15:35:56 +0800 Subject: [PATCH 5/8] linux-kfence: commit correct result of tinycorrect-images Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index 382696f..4989842 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables images]
> Author: pwl999
> Date: 2022/04/28
> Revisor: Falcon
@@ -16,7 +16,7 @@ Kfence (Kernel Electric Fence) 是 Linux 内核引入的一种低开销的内存 Kfence 的基本原理非常简单,它创建了自己的专有检测内存池 `kfence_pool`。在 `data page` 的两边加上了 `fence page` 电子栅栏,利用 MMU 的特性把 `fence page` 设置成不可访问。如果对 `data page` 的访问越过了 page 边界, 就会立刻触发异常。 -![](images/kfence/kfence_pool.png) +![kfence_pool.png](images/kfence/kfence_pool.png) Kfence 的主要特点如下: @@ -32,13 +32,13 @@ Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。 - 1、默认每隔 100 ms,开放从 `kfence_pool` 内存池中分配一次数据。分配成功后会把 `kfence_allocation_gate` 加 1,阻止继续从 `kfence_pool` 的分配。`kfence_timer` 定时到期以后,又会重新开放一次分配。这相当于一种 `抽样法`。 - 2、每次分配都会占用 `kfence_pool` 中的一个 `data page`,所以可分配的内存长度最大为 1 page。 -![](images/kfence/kfence_slub_hook.png) +![kfence_slub_hook.png](images/kfence/kfence_slub_hook.png) ### out-of-bounds (over data page) 从 `kfence_pool` 中成功分配一个内存对象 `obj`,不管 `obj` 的实际大小有多大,都会占据一个 `data page`。 -![](images/kfence/kfence_outbound_fence.png) +![kfence_outbound_fence.png](images/kfence/kfence_outbound_fence.png) 当原本访问 `obj` 的操作溢出到相邻的 `fence page` 时,会立即触发 CPU 异常,通过堆栈回溯揪出异常访问的元凶。 @@ -46,7 +46,7 @@ Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。 大部分情况下 `obj` 是小于一个 page 的,对于 `data page` 剩余空间系统使用 `canary pattern` 进行填充。这种操作是为了检测超出了 `obj` 但还在 `data page` 范围内的溢出访问。 -![](images/kfence/kfence_outbound_canary.png) +![kfence_outbound_canary.png](images/kfence/kfence_outbound_canary.png) 这种类型的溢出是不能在溢出发生时立刻触发的,它只能在 `obj` free 时,通过检测 `canary pattern` 被破坏来检测到有 `canary` 区域的溢出访问。但是异常访问的元凶却不能直接抓出来。 @@ -54,7 +54,7 @@ Kfence 把自己 hook 到 `slub/slab` 的 `malloc()/free()` 流程当中去。 在 `obj` 被 free 以后,对应 `data page` 也会被设置成不可访问状态。 -![](images/kfence/kfence_use_afterfree.png) +![kfence_use_afterfree.png](images/kfence/kfence_use_afterfree.png) 这种状态下,如果有操作继续访问 `obj` 会立即触发 CPU 异常,通过堆栈回溯揪出异常访问的元凶。 -- Gitee From a0349ebea57689d83a6e2b3b55774ceef0908eb9 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 15:36:12 +0800 Subject: [PATCH 6/8] linux-kfence: commit correct result of tinycorrect-urls Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index 4989842..c61495d 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables images]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables images urls]
> Author: pwl999
> Date: 2022/04/28
> Revisor: Falcon
@@ -162,7 +162,12 @@ kfence_free() → __kfence_free() → kfence_guarded_free(): ## 参考文档 -1. [Linux内存异常检测工具—kfence](https://www.jianshu.com/p/f967086f9129) -2. [Kernel Electric-Fence (KFENCE)](https://www.kernel.org/doc/html/latest/dev-tools/kfence.html) -3. [Linux Kernel Sanitizers](https://gitee.com/mirrors/KASAN) -4. [Linux开源动态之一种新的内存非法访问检查工具KFence](https://www.cnblogs.com/liuhailong0112/p/14683431.html) +1. [Linux内存异常检测工具—kfence][003] +2. [Kernel Electric-Fence (KFENCE)][004] +3. [Linux Kernel Sanitizers][001] +4. [Linux开源动态之一种新的内存非法访问检查工具KFence][002] + +[001]: https://gitee.com/mirrors/KASAN +[002]: https://www.cnblogs.com/liuhailong0112/p/14683431.html +[003]: https://www.jianshu.com/p/f967086f9129 +[004]: https://www.kernel.org/doc/html/latest/dev-tools/kfence.html -- Gitee From 5e4eaabca6d29bb2cdf8365cbfa0141ba2e0221c Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 15:36:18 +0800 Subject: [PATCH 7/8] linux-kfence: commit correct result of tinycorrect-pangu Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index c61495d..84c6586 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables images urls]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables images urls pangu]
> Author: pwl999
> Date: 2022/04/28
> Revisor: Falcon
@@ -162,10 +162,10 @@ kfence_free() → __kfence_free() → kfence_guarded_free(): ## 参考文档 -1. [Linux内存异常检测工具—kfence][003] +1. [Linux 内存异常检测工具—kfence][003] 2. [Kernel Electric-Fence (KFENCE)][004] 3. [Linux Kernel Sanitizers][001] -4. [Linux开源动态之一种新的内存非法访问检查工具KFence][002] +4. [Linux 开源动态之一种新的内存非法访问检查工具 KFence][002] [001]: https://gitee.com/mirrors/KASAN [002]: https://www.cnblogs.com/liuhailong0112/p/14683431.html -- Gitee From 720055fcde674e5c81a75b0782535b415de84333 Mon Sep 17 00:00:00 2001 From: Wu Zhangjin Date: Mon, 26 Sep 2022 15:36:59 +0800 Subject: [PATCH 8/8] linux-kfence: commit correct result of tinycorrect-autocorrect Signed-off-by: Wu Zhangjin --- articles/20220428-linux-kfence.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/articles/20220428-linux-kfence.md b/articles/20220428-linux-kfence.md index 84c6586..2a8ccec 100644 --- a/articles/20220428-linux-kfence.md +++ b/articles/20220428-linux-kfence.md @@ -1,4 +1,4 @@ -> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables images urls pangu]
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1-rc2 - [tables images urls pangu autocorrect]
> Author: pwl999
> Date: 2022/04/28
> Revisor: Falcon
@@ -14,7 +14,7 @@ Kfence (Kernel Electric Fence) 是 Linux 内核引入的一种低开销的内存错误检测机制,因为是低开销的所以它可以在运行的生产环境中开启,同样由于是低开销所以它的功能相比较 Kasan 会偏弱。 -Kfence 的基本原理非常简单,它创建了自己的专有检测内存池 `kfence_pool`。在 `data page` 的两边加上了 `fence page` 电子栅栏,利用 MMU 的特性把 `fence page` 设置成不可访问。如果对 `data page` 的访问越过了 page 边界, 就会立刻触发异常。 +Kfence 的基本原理非常简单,它创建了自己的专有检测内存池 `kfence_pool`。在 `data page` 的两边加上了 `fence page` 电子栅栏,利用 MMU 的特性把 `fence page` 设置成不可访问。如果对 `data page` 的访问越过了 page 边界,就会立刻触发异常。 ![kfence_pool.png](images/kfence/kfence_pool.png) -- Gitee