> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man9/kasan.9.md).

# kasan.9

`KASAN` — 内核地址消毒器

## 名称

`KASAN`

## 概要

GENERIC-KASAN 内核配置可用于以 GENERIC 为基础配置编译启用 KASAN 的内核。或者，要将 KASAN 编译进内核，请将以下行放入你的内核配置文件中：

> options KASAN

```c
#include <sys/asan.h>

void
kasan_mark(const void *addr, size_t size, size_t redzsize, uint8_t code)
```

## 描述

`KASAN` 是一个利用编译器插桩检测内核中无效内存访问的子系统。目前在 amd64 和 arm64 平台上实现。

当 `KASAN` 编译进内核时，编译器被配置为在每次内存访问时发出函数调用。这些函数由 `KASAN` 实现，允许运行时检测若干类型的错误，包括释放后使用、双重释放和释放无效指针，以及越界访问。这些保护适用于由 uma(9)、[malloc(9)](/man/man9/malloc.9.md) 及相关函数，以及 `kmem_malloc` 和相关函数分配的内存，还有全局变量和内核栈。`KASAN` 是保守的，不会检测所有此类错误的实例。通过内核映射的内存访问会被消毒，但通过直接映射的访问不会。当配置 `KASAN` 时，内核旨在尽量减少对直接映射的使用。

## 实现说明

`KASAN` 使用编译器插桩和内核运行时实现。当构建启用 KASAN 选项的内核时，编译器在生成代码中的大多数内存访问之前插入函数调用。运行时实现相应的函数，决定给定访问是否有效。如果无效，运行时根据 `debug.kasan.panic_on_violation` sysctl/可调参数的值打印警告或使内核崩溃。

KASAN 配置的内核中的 `KASAN` 运行时可通过设置 loader 可调参数 `debug.kasan.disable=1` 禁用。

`KASAN` 运行时通过为内核映射维护影子映射来工作。内核映射中的地址与影子映射中的地址之间存在线性映射关系。影子映射用于存储有关内核映射分配的当前状态信息。例如，当 [malloc(9)](/man/man9/malloc.9.md) 返回缓冲区时，影子映射的相应区域被标记为指示缓冲区有效。当其被释放时，影子映射更新为将缓冲区标记为无效。对缓冲区的访问由 `KASAN` 运行时拦截，并使用影子映射的内容进行验证。

启动时，所有内核内存被标记为有效。内核分配器必须将缓存但空闲的缓冲区标记为无效，并在释放内核虚拟地址范围之前将其标记为有效。这略微降低了 `KASAN` 的有效性，但简化了其维护和与内核的集成。

通过调用 `kasan_mark` 执行影子映射的更新。参数 `addr` 是要更新影子的缓冲区地址，`size` 是缓冲区的可用大小，`redzsize` 是从系统底层分配的缓冲区的完整大小。`redzsize` 必须大于或等于 `size`。在某些情况下，内核分配器会返回大于消费者请求的缓冲区；末尾未使用的空间称为红区，始终标记为无效。`code` 允许调用者在将缓冲区标记为无效时指定一个标识符。该标识符包含在 `KASAN` 生成的任何报告中，有助于识别无效访问的来源。例如，当项被释放到 uma(9) 区时，该项用 `KASAN_UMA_FREED` 标记。可用标识符参见以下文件：

```c
#include <sys/asan.h>
```

如果整个缓冲区要标记为有效，即 `size` 和 `redzsize` 相等，`code` 应为 0。

## 参见

[build(7)](/man/man7/build.7.md), KMSAN(9), [malloc(9)](/man/man9/malloc.9.md), [memguard(9)](/man/man9/memguard.9.md), [redzone(9)](/man/man9/redzone.9.md), uma(9)

## 历史

`KASAN` 从 NetBSD 移植，首次出现于 FreeBSD 13.1。

## 缺陷

`KASAN` 运行时忽略对内核映射之外的内核内存的访问。当配置 `KASAN` 时，内核内存分配器被配置为使用内核映射，但仍存在一些对直接映射的使用。例如，在 amd64 和 arm64 上，对页表页的访问不被跟踪。

某些内核内存分配器明确允许在对象被释放后访问。这些无法由 `KASAN` 消毒。例如，从所有使用 `UMA_ZONE_NOFREE` 标志初始化的 uma(9) 区的内存不被消毒。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man9/kasan.9.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
