Weekly Report 2026-04-26

工作任务

1.对sota工具进行实验

工作进展

对sota工具进行实验

0.knight(已实验,待做推理)

<u>工具原理:</u>通过llm分析某个cve的commit,然后编写出对应的checker,用这个checker扫描全内核

假说-演绎法:

<u>提出假说:</u>由于通用llm对强riscv语义理解不透彻,或者llvm的checker对riscv语义的api支持较差,所以生成的checker对强riscv语义的漏洞难以检测或者生成的checker质量差或者难以编译成功。

演绎推理:如果上述假设成立,那么对于强riscv语义commit生成的checker,checker会难以生成成功,召回率一定更差,误报率也一定更高,对于浅riscv语义或者通用语义的commit生成的checker则是反之。

<u>实验验证:</u>

将在https://has2lab.github.io/RISCV_CVE_Dashboard/提取的CVE分为通用漏洞(9个)和RISC-V专有漏洞(10个),分别给Knight运行其gen阶段从而测试其召回率

CVE编号Best Score
特殊/边缘情况遗漏(逻辑错误)|CVE-2024-42267TP=0, TN=1
隐式ABI规定违反|Unaligned Memory|CVE-2024-43868TP=0, TN=0
隐式API规定违反|CVE-2024-46792TP=0, TN=1
分支路径遗漏(逻辑错误)|Resource Leak|CVE-2024-53075TP=1, TN=1
隐式API规定违反|CVE-2024-57939TP=1, TN=1
特殊/边缘情况遗漏(逻辑错误)|CVE-2025-37975TP=0, TN=1
特殊/边缘情况遗漏(逻辑错误)|CVE-2025-38433TP=0, TN=0
特性/机制冲突|CVE-2025-40358TP=1, TN=1
隐式时间规定违反|CVE-2025-38681待测

表 1 通用漏洞

CVE编号Best Score
RISC-V_MMU|隐式API规定违反|CVE-2024-53687TP=0, TN=0
RISC-V_MMU|隐式API规定违反|CVE-2024-56673TP=0, TN=1
RISC-V_MMU|隐式ABI规定违反|CVE-2024-57945TP=-10, TN=-10(编译错误)
RISC-V_Traceing(Probes/Ftrace)|隐式ABI规定违反|CVE-2025-22069TP=-10, TN=-10(编译错误)
RISC-V_Traceing(Probes/Ftrace)|功能实现不完整(逻辑错误)|CVE-2025-37822配置项未开kernel编译错误
RISC-V_Pointer Masking Extensions|功能实现不完整(逻辑错误)|CVE-2025-37966TP=1, TN=1
RISC-V_CSR|RISC-V_Context_Switch|功能实现不完整(逻辑错误)|CVE-2025-38261TP=-2, TN=-2(checker运行时错误)
RISC-V_SBI|隐式API规定违反|CVE-2025-38407TP=0, TN=1
RISC-V_MMU|特性/机制冲突|CVE-2025-38434TP=-10, TN=-10(编译错误)
RISC-V_Vector_Extension|功能实现不完整(逻辑错误)|CVE-2025-38435TP=-10, TN=-10(编译错误)

表 1 riscv漏洞

同一批cve,可以假定复杂度等等都是一致的,由于仅仅根据riscv语义进行分类后进行实验,出现riscv漏洞大量checker生成失败,并且召回率很低(只成功一个),而通用漏洞全部编译成功,召回3个,可以完美符合演`绎推理的结果

所以得出结论,由于knight对riscv语义理解不够,导致其对强riscv语义的commit难以生成checker或者生成质量差,从而存在缺陷

1. bugstone(One Bug, Hundreds Behind: LLMs for Large-Scale Bug Discovery) [arXiv 2025.10](作者:Qiushi Wu1, Yue Xiao2, Dhilung Kirat1, Kevin Eykholt1, Jiyong Jang1, Douglas Lee Schales1)

<u>工具原理</u>:通过llm分析某个commit(种子),总结出某个api的用法(安全编码规则),然后找出整个内核中使用过这个api的位置(调用点枚举),然后使用llm对于所有调用点进行违规判断

假说-演绎法

<u>提出假说</u>:由于此工具以及通用llm,对于riscv的语义理解不透彻,导致即使在提供了api用法以及安全编码规则的前提下,依旧会出现大量的误报或者难以检测出问题

<u>演绎推理A</u>:如果上述假设成立,那么我们必然会观测到,假如我们提供一条真实的riscv底层bug的修复commit,它必然无法精准的提取出安全规则,而只能提出肤浅/错误的规则

<u>演绎推理B</u>:如果上述假设成立,那我们必然会观测到,即使我们人工提供一条正确的riscv安全规则,在扫描时也会因为不懂上下文从而使其崩溃

<u>实验验证A</u>:

使用三个riscv强相关的commit进行实验,实验结果如下

<table style="width:100%;"> <caption><p>表 1 实验A结果</p></caption> <colgroup> <col style="width: 18%" /> <col style="width: 39%" /> <col style="width: 41%" /> </colgroup> <thead> <tr> <th>Commit</th> <th>人工提取含义</th> <th>实验结果</th> </tr> </thead> <tbody> <tr> <td>b3431a8</td> <td>flush_tlb_kernel_range蕴含着对于所有hart的刷新,但是在关闭中断的条件下不能发中断给别人</td> <td><p>提取api正确,其正确了一半,但是最关键的提取api提取到了preempt_disable,是错误的,导致后面实验全部错误</p> <p>安全编码规则提取基本正确</p></td> </tr> <tr> <td>2b29be9</td> <td>在NUMA的场景下,早期的内存分配(特别是对于per cpu的内存分配)可能会fallback到page allocator,这个时候依然调用了pa函数,这个函数隐式规定给他的地址应该是连续的,这个时候pa返回了错误的结果,而把这个结果传给了之后的sbi call,导致的失败(sbi错误)</td> <td><p>提取api错误,应该需要提取出pa函数和相应的sbi call(两者不应该同时出现的问题)</p> <p>安全编码规则提取错误:他只捕获到了如何修改错误,特别浅层,没有深刻认识到这个sbi call需要物理地址,但是不能和pa一起用</p></td> </tr> <tr> <td>788aa64</td> <td>在switch函数没有保存ssatus的SUM,导致没有办法恢复SUM(即少保存了一些context)</td> <td><p>提取api正确(实际上这不存在一个通用的api)</p> <p>安全编码规则提取正确</p></td> </tr> </tbody> </table>

实验结果与演绎推理A需要的结论不符,有两个安全编码规则都提取正确了,原因是其实commit message中详细描述了漏洞成因,但是对于第二个commit,有着复杂的隐式约束,并且commit message内容没有那么丰富,所以没有提取出根因,所以部分证伪

可以得出结论,llm在存在简单riscv语义以及有足够内容的commit message的情况下,部分可以得出安全编码规则和api调用点

并可以提出假说2: 在隐式条件不复杂且commit message提供的信息足够的情况下,他能提取出语义和api,但是在复杂的情况下不能提取出来(但是证明先搁置)

<u>实验验证B:</u>使用给定的riscv相关的安全编码规则,做实验

子系统分析数违规数违规率
arch/riscv542546.3%
arch/x8616318.8%
drivers181688.9%
kernel3133.3%
mm2150.0%
net77100.0%
API分析数违规数违规率类型
request_irq10330.0%通用
clk_prepare_enable10880.0%通用
create_singlethread_workqueue1010100.0%通用
dma_alloc_coherent8562.5%通用
sbi_ecall10660.0%RISC-V
csr_write20420.0%RISC-V
flush_tlb_all201050.0%RISC-V
local_flush_tlb_all12758.3%RISC-V

违规率未见明显偏低,同样证伪,但是需要人工一个一个看是否为误报,暂时工作量较大,搁置,但是导致实验并不完美严谨

两个推理得出的结论都不完美符合假说,说明需要不断迭代提出假说,但是过于耗时,于是得出阶段性结论,bugstones在有丰富commit message信息以及隐式含义不复杂,或者人工提供精准语义的情况下,llm能基本分析出riscv的漏洞,但是假如隐式含义复杂的情况下,工具依旧存在缺陷。

2. app-miner(APP-Miner: Detecting API Misuses via Automatically Mining API Path Patterns)[IEEE S&P 2024.05](Jiasheng Jiang, Jingzheng Wu, Xiang Ling, Tianyue Luo, Sheng Qu, and Yanjun Wu)

<u>工具原理</u>:从代码中自动挖掘API路径模式(API Path Pattern),然后检测不符合这些模式的API误用

假说-演绎法:

<u>提出假说:</u>由于app-miner缺乏riscv的语义,所以对于riscv内核的riscv特定api误用情况检测会出现大量的fp和fn

<u>演绎推理A:</u>如果上述结论成立,那么首先对于riscv的api挖掘出来的app应该较少(即app/api比值),并且app中难以形成riscv语义强相关的pattern

<u>演绎推理B:</u>riscv的app去检测误用会出现大量fp,特别是riscv语义强相关的app

<u>实验验证A:</u>

子系统x86 API(stat)RV API(stat)x86 APPRV APPx86 APP/APIRV APP/APIx86 ViolRV Viol
drivers~10743453712692460.02510.00867629100
fs~2173554135741000.02640.01851383141
net~14468-310-0.0214-7440
kernel~5466-100-0.0183-4120
mm~2829144773370.02580.025615276
sound~6323-151-0.0239-4600
crypto~364-16-0.0440-320
lib~130767924100.01840.014727482
security~478065730210.00630.03204415
arch~46085115650.01220.00981519
block~6215601470.02250.01253818
ipc~214149230.00930.0201136
总计~1714831528540772350.02380.015411383455

可以发现,riscv提取出来app确实是最少的(app/api),只有0.98%,完美支持推理A,然后,将他235个riscv的app进行ai分析,结论如下:

235个RISC-V APP模式按语义相关度分为三类:

1. RISC-V专有APP(2个,0.9%)

- `__riscv_isa_extension_available+3`(support=31)— RISC-V ISA扩展查询,语义较浅

- `flush_icache_pte+3`(support=33)— icache刷新,与RISC-V缓存一致性相关

2. 架构相关APP(29个,12.3%) — 涉及页表/内存管理(pte/pmd/pgd/folio等),与架构间接相关但非RISC-V专有

3. 通用APP(204个,86.8%) — spin_lock、kmalloc、copy_to_user等完全架构无关的API

关键发现:零RISC-V强语义APP。 CSR操作(csr_read/csr_write)、SBI调用(sbi_ecall/sbi_base_ecall)、TLB刷新(flush_tlb_all/flush_tlb_range)、虚拟化指令(hfence/sfence)等RISC-V强语义API均未成为APP。这些API在statistic阶段确实被提取(248个RISC-V专有API进入statistic),但因调用点不足(98%调用位置<10)被MIN_SUPPORT阈值淘汰。

也可以完美支持结论,最后获得的语义相关的app只有两个

<u>实验验证B:</u>

arch/riscv/ Violation详情(9个,按violation位置)

1.arch/riscv/kvm/vcpu_insn.c:wfi_insn API: __srcu_read_lock+2

2.arch/riscv/kvm/vcpu_insn.c:kvm_riscv_vcpu_wfi API: __srcu_read_lock+2

3.arch/riscv/kvm/vcpu.c:kvm_riscv_check_vcpu_requests API: __srcu_read_lock+2

4.arch/riscv/kernel/cpufeature.c:riscv_resolve_isa API: _find_next_bit+4

5.arch/riscv/kvm/aia_device.c:aia_create API: xa_load+3

6.arch/riscv/kvm/vcpu_onereg.c:kvm_riscv_vcpu_copy_reg_indices API:llvm.cttz.i64+3

7.arch/riscv/mm/context.c:set_mm API: _find_next_zero_bit+4

8.arch/riscv/purgatory/purgatory.c:purgatory API: memcmp+4

9.arch/riscv/mm/fault.c:die_kernel_fault API: die+3

1,2是看不懂wfi的语义导致的误报,3是用锁的复杂情况,也是误报,456是llvm intrinsic,无法在源代码里面直接判断,其他经过llm分析也全是误报

也完美证明推理B

<u>结论:</u>由于app-miner缺乏riscv的语义,所以对于riscv内核的riscv特定api误用情况检测会出现大量的fp和fn

所有需要真跑fuzzer的syzkaller类论文全部在服务器上失败,服务器没有sudo权限,docker和宿主机共享内核,无法跑riscv内核的fuzzer,所以动态工具只选取某些生成syzlang的工具进行实验,后续这些需要真跑fuzzer的实验根据需要在我自己的电脑上进行实验。

3.KernelGPT: Enhanced Kernel Fuzzing via Large Language Models (ASPLOS 2025)( Chenyuan Yang, Zijie Zhao, Lingming Zhang)

<u>工具原理:</u>KernelGPT是一个基于LLM的syzkaller规范自动生成工具,其核心思路是:从内核源码中静态提取接口信息 → 使用LLM逐步推理生成syzlang规范 → 通过syz-check验证并迭代修复

假说-演绎法:

<u>提出假说:</u>由于缺乏riscv语义并且riscv语义强相关的部分大多为汇编,静态提取接口信息会不完整,并且llm生成的syzlang规范也不完整

<u>演绎推理A:</u>如果上述结论成立,首先会是提取的riscv接口信息数量要远小于其他子系统的接口信息

<u>演绎推理B:</u>如果上述结论成立,对于riscv接口信息的syzlang生成的结果会不准确

<u>进行实验A:</u>

评估指标x86 编译全量RISC-V 编译全量RV/x86 比值预期偏差验证结果
struct 条目数89,36380,3440.90RISC-V << x86不符合
func 条目数686,292610,7550.89RISC-V << x86不符合
enum 条目数24,75121,8340.88RISC-V << x86不符合
ioctl 条目数8287630.92RISC-V << x86不符合
评估指标x86 (arch/x86)RISC-V (arch/riscv)RV/x86 比值预期偏差验证结果
struct 条目数1,3631500.11RISC-V << x86符合
func 条目数18,4233,4670.19RISC-V << x86符合
enum 条目数179320.18RISC-V << x86符合
ioctl 条目数400.00RISC-V << x86符合
指标x86 (41.9万行)RISC-V (4.4万行)接口密度 (x86)接口密度 (RV)密度比(RV/x86)结论
struct1,36315032.5/万行33.8/万行1.04结构定义频率相近
func18,4233,467439.6/万行781.8/万行1.78RV 符号密度更高
enum179324.3/万行7.2/万行1.69RV 密度更高
ioctl400.10/万行0/万行0.00RV 传统 IO 接口缺失

并没有见到riscv显著偏低,所以推理A证伪

<u>进行实验B:待做</u>

4. Multi-target Coverage-based Greybox Fuzzing [arXiv 2026.03](Masami Ichikawa)

<u>工具原理:</u>MTCFuzz通过修改QEMU的TCG翻译过程,以基本块粒度统一追踪内核和固件的执行覆盖率,将两者的并集作为单一反馈信号引导fuzzing——任何一侧出现新覆盖都被视为"有趣",从而能发现单目标fuzzer遗漏的跨软件边界执行路径。

<u>提出假说:?</u>

对科研以及当前研究方向的思考(开题思考)

由于在复现论文的时候对当前做的事情产生了“为什么要做”的迷茫,于是对于科研整个方法论进行了一点思考

如果说做题是

给定的条件(+教科书隐含的条件概念) + 良定义的问题, 然后经过严格严谨的逻辑推理 得出最终的结论

那科研就是

散落在整个领域的隐含的知识 加 未知的问题 经过推理 得到一个 未知的结论

现在仅仅只是给了我一个方向 叫做“内核 riscv 存量/增量代码安全性的研究”,但是这不是一个可以直接解决的问题,所以现在是

有方向,没有条件 没有问题 没有结论,该怎么办

首先,条件一定是基于具体的问题的,结论是用来回答问题的,而方向本身,我认为是a bunch of 问题

所以第一步我认为是我现在的第一步就是找到藏在方向后面的一簇问题,这是第一个结论

然后我认为问题的可以在两个维度上进行划分,良定义的(可解的)但低价值,高价值但是不良定义的,以及在这之间的问题。

如果一个问题是低价值但是良定义的,那么解决它获得的价值有限,但是如果一个问题是高价值但是不良定义的,那么他会难以解决,良定义和高价值是鱼和熊掌,所以,好问题会是介于两者之间的好的trade-off,这是第二个结论 (即问题的评估标准)

(这也同时能回答,该把什么类型的问题丢给ai,即良定义的,而什么问题是能发paper的呢,一定是高价值的。良定义意味着学术/工业界在这个问题上已经成熟了,不良定义即是不成熟的,难以解决的)

问题还能在另一个维度进行分类,即问题的语义,对于一个高价值的问题,解决的思路是将其不断拆分,但是做到在拆分中继承更多的价值,并且让问题更加良定义,更易解决,然后递归拆分,最后,尝试从众多良定义的问题,通过复杂但是严谨的推导,尝试重组,让他最终解决那个最难解决的高价值问题(分而治之),这是第三个结论(即问题的拓扑关系)

于是,在对问题概念本身之后了解清楚后,我开始头脑风暴不断对“内核 riscv 存量/增量代码安全性的研究”这个方向进行最高价值问题的提问:

  1. 能否能创建一个工具,他能对riscv的存量/增量代码进行很好的检测?

  2. 对于riscv的内核代码,是否存在独属于riscv的新的攻击方式?

  3. 对于增量代码(以riscv in kernel为例)带来熵的增加,如何能自动进行熵减?

  4. 对于冯诺依曼架构下的软硬件边界(以riscv和linux为例),是否注定了存在某些安全漏洞?

然后对于上述问题进行拆分提问,首先对第一个(这是我们正在研究的)

  1. 能否创建一个工具,他能对riscv的存量/增量代码进行很好的检测?
<!-- -->
  1. riscv在linux kernel中有哪些存量代码?(良定义,已解决)

  2. riscv的增量代码的增加频率?(良定义,已解决)

  3. 现有的工具能否对riscv的存量/增量代码进行很好的检测(良定义,正在解决)

  4. 为什么现有的工具能/不能对riscv代码进行很好的检测?(不良定义,做拆分)

  • Riscv代码有哪些特有的架构特性?

  • 对于上述的特有的架构特性,哪些是现有工具不能检测出来的?

  • 现有工具只能检测什么类型的漏洞?(良定义)

  1. 对于第四点发现的哪些特性,怎么样能让工具对riscv代码进行很好的检测呢?(不良定义,需拆分)
  • 能否通过某种方式将这些语义的信息提取出来?(不良定义,需做拆分)

  • 这些语义信息被提取出来之后能否增强现有的工具,让他成功找到riscv漏洞呢?(不良定义,需做拆分)

-(如果能import我之前的layer模型)layer3的哪些形式可以提供给现有的工具形式从而增强现有工具呢?

  • 如果现有工具的形式不能找到漏洞,是否能研究出一个新的工具形式他的检测方法能检测出riscv漏洞呢?(不良定义,需做拆分)

可以发现问题是递进的,能通过拆分慢慢依照上一步的结论最终推导到最终结论,上述问题的提出是这次思考的第四个结论

(对于2,3,4这几个高价值问题也需要进行拆分,但是这几个问题本身过于困难,于是暂缓)

Linux内核中,各模块的编排,比如RV部分是怎么在通用层规定的,V拓展是怎么设计实现的(未完成)

(这部分可能我会花比较长的时间去研究,去读源码)

一个很重要的前提是,内核代码的设计就是能通用则通用,实在在通用层没有办法实现的,才会求助于arch specific代码,具体来说是编译时进行include某些arch specific的函数(在通用层未实现),如果arch/目录下没有实现,首先会编译错误(而不是我一开始认为的函数指针,那是运行态的)

所以最基本的就是arch specific的代码作为通用代码的后援,会在多个子系统提供支持(只是被聚集在了arch/下)

通过子系统可以分类为:

  • Bootstrap

  • Mem setup

  • MMU Management

  • Thread Management

  • Time Management

  • IRQs and exception management

  • System calls

  • Platform Drivers

  • Machine specific code

可以发现,从另一个角度分类,可以把这些分为,boot和runtime,arch specific code对于boot有很大一部分比重,他们是其他子系统setup之前的setup,所以单独分类,而boot又可以分为bootstrap和mem setup,所以将其分为这两类,可以说所有arch的代码向上,都是为这些功能服务的。

以下是读linux v4.15代码和freebsd release/13.0.0代码的笔记和结论

Bootstrap

<u>linux主要流程:</u>主hart启动,设置双层跳板页表实现mmu的初始化,保存sbi提供的信息(fdt),然后进入内核的通用初始化(通用初始化主要有内存初始化会在下面讲到,和其他初始化)

<u>freebsd主要流程:</u>主hart启动,设置页表实现mmu的初始化,保存sbi提供的信息(fdt)(但是貌似不会做fdt解析),然后进入riscv专用初始化—initriscv,之后进入通用SYSINIT初始化(比linux混杂在一起初始化优雅很多,非常漂亮的声明式初始化系统)

<u>架构特定部分:</u>多hart启动,sbi掌管m mode启动

(其实这个过程每一个架构都很不一样,比如说x86是实模式,保护模式启动等等,arm有安全世界启动的概念)

Mem setup

<u>linux主要流程:</u>fdt收集内存->memblock初始化->page子系统->buddy子系统,memblock销毁(基本就是先实现memblock,用这个简陋的分配器实现内存系统的bootstrap,比如初始化page子系统)

<u>freebsd主要流程:</u>fdt收集内存->physmem(同样也是reserve逻辑)->pmap_bootstrap,这个pmap_bootstrap就是整个的mem bootstrap

<u>架构特定部分:</u>这个部分架构相关的部分可能不多,这个流程基本是memblock先收集所有内存,然后转给buddy,基本只有这个收集内存架构相关的比较多,因为涉及特有的内存布局,freebsd同理,然后主要就是页表部分架构相关

MMU manegemrnt

<u>Linux主要流程:</u>主要可以从最早期的页表设置和mmu初始化开始,然后page_init完成基本的全部初始化,运行阶段主要是四个部分,tlb管理,地址空间管理(含pgtable管理),缺页处理

<u>Freebsd的流程:</u>前期也需要页表设置和mmu初始化,之后用pmap初始化整个内存系统,freebsd也基本是分为上述四个部分,只是代码全部集中在pmap.c中,并且pmap是架构代码的一个抽象层,有着明确的规范,设计也比linux优雅(linux完全分散在不同文件里面)

Platform Drivers

(暂时不涉及acpi等高级机制)

<u>Linux的主要流程:</u>完全由sbi提供的dt驱动的整个platform的发现和初始化,只有rst求助于sbi本身

Freebsd的主要流程:

Machine Specific Code

Riscv由于比较新,没有Machine Specific code,纯dt驱动,算是sbi的带来的一个好处之一

2026-09-08 · Also readable in terminal: ssh blog@www.yizishun.com then run blog security/riscv-linux-security/weekly-reports/2026-04-26

Comments

Loading…

    Connecting to real terminal…