尧图精选

用 Static Driver Verifier 揪出 Storport 迷你端口驱动的 7 类缺陷:SDV-FailDriver-STORPORT 示例源码级实战解析

🕒 发布时间:2026/9/28 7:30:03 📁 来源:尧图网络
示例工程【免费下载链接】Windows-driver-samplesThis repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.项目地址https://gitcode.com/gh_mirrors/wi/Windows-driver-samples点击查看免费下载Static Driver VerifierSDV静态驱动程序验证器是随 Windows Driver KitWDK附带的静态验证工具能够系统性地分析内核模式驱动源码并报告 DDI 使用规则的违反情况。本篇以 SDV-FailDriver-STORPORT 示例为对象完整讲解如何在 Visual Studio 中对一个 Storport 迷你端口驱动运行 SDV、选择规则集、解读报告并结合lsi_u3.c源码逐条剖析 7 处被故意注入的缺陷让你既能跑通 SDV 的完整流程也能理解每条 DDI 规则在真实代码里到底在检查什么。示例概览为 SDV 教学而生的反面教材SDV-FailDriver-STORPORT 是 Windows-driver-samples 仓库中 tools/sdv/samples 目录下的 SDV-FailDriver 系列示例之一同系列还包括 SDV-FailDriver-KMDF、SDV-FailDriver-NDIS 和 SDV-FailDriver-WDM分别针对 WDF、NDIS、WDM 与 Storport 四种驱动模型演示 SDV 的检错能力。该示例的主体是一个模拟 LSI Logic 53C1010Ultra 3SCSI 控制器的 Storport 迷你端口驱动源码中故意埋入了符合 Storport DDI 规则的代码缺陷用于展示 SDV 如何发现这些错误[!CAUTION] 这些示例驱动包含故意制造的代码错误仅用于展示 SDV 的能力与特性。它们不是可用的功能驱动也不应作为真实驱动开发项目的参考范例。切勿将其缺陷模式照搬到生产代码中。从工程文件 driver/lsi_u3.vcxproj 可以看到该驱动以DriverTypeMiniport构建PlatformToolsetWindowsKernelModeDriver10.0目标平台为 Universal Windows 驱动提供 x64 与 ARM64 的 Debug/Release 配置并在链接阶段依赖storport.lib与ntoskrnl.lib——这些正是 Storport 迷你端口驱动的典型工程特征。源码布局一个仿真 SCSI 控制器迷你端口驱动示例由以下文件组成文件作用driver/lsi_u3.c迷你端口驱动主实现约 8800 行内含全部缺陷注入点driver/lsi_u3.h私有头文件SDV 角色类型、53C1010 SIOP 寄存器映射、设备扩展结构driver/sdv-user.sdvSDV 规则清单文件逐行列出本示例默认验证的 7 条规则driver/lsi_u3.vcxprojVisual Studio 工程文件含 .Filters 筛选器文件driver/lsi_u3.rc资源文件SDV-FailDriver-STORPORT.sln解决方案文件lsi_u3.c模拟了一颗 53C1010 芯片的完整迷你端口行为定义了HW_DEVICE_EXTENSION设备扩展含脚本物理地址入口点、队列指针、NVM 数据等、HW_NONCACHED_EXTENSION通过 DMA 访问的非缓存扩展含 SCSI 脚本数组、协商消息缓冲、队列等以及SRB_EXTENSIONSRB 扩展含物理断点计数、协商标志、自动请求感知标志等。迷你端口通过LsiU3FindAdapter、LsiU3HWInitialize、LsiU3StartIo、LsiU3ISR、LsiU3Reset、LsiU3AdapterControl、LsiU3BuildIo等回调与 Storport 交互。值得关注的是 driver/lsi_u3.h 中有一段SDV role types声明它把迷你端口回调函数显式地声明为 Storport 的角色类型如HW_INITIALIZE LsiU3HWInitialize;、HW_STARTIO LsiU3StartIo;、HW_INTERRUPT LsiU3ISR;、HW_FIND_ADAPTER LsiU3FindAdapter;、HW_RESET_BUS LsiU3Reset;、HW_ADAPTER_CONTROL LsiU3AdapterControl;、HW_BUILDIO LsiU3BuildIo;。这正是 SDV 能够分析 Storport 驱动的关键机制通过角色类型声明SDV 才能识别驱动中每个回调的语义约定并据此应用对应的 DDI 合规规则。文件修订历史还注明 Aug-2010: Added defect injections for StorPort rules, checked in as fail driver与示例的定位一致。运行 SDV 的完整操作步骤VS WDKSDV 集成在 Visual Studio 的驱动开发工作流中以下步骤来自示例 README.md并补充了工程层面的前提说明。第 1 步启动 SDV在解决方案资源管理器Solutions Explorer中选中驱动工程lsi_u3.vcxproj。从Driver驱动程序菜单中点击Launch Static Driver Verifier...。此时会打开 Static Driver Verifier 应用程序窗口你可以在这里控制、配置并调度SDV 的分析任务。启动前请确认工程已配置为 Miniport 驱动类型如本示例的lsi_u3.vcxproj所示并已安装匹配目标 Windows 版本的 WDK 工具集。第 2 步选择规则集点击Rules规则选项卡选择在分析启动时需要对驱动校验哪些DDI 使用规则。SDV 会自动检测当前驱动的类型WDF、WDM、NDIS 或 Storport并为该驱动类型预选一组默认规则。如果是第一次对驱动运行 SDV建议直接使用默认规则集。若想缩短示例驱动的分析耗时可以选择Custom rule selection自定义规则选择使用默认规则集或选择Custom rule selection点击Clear All全清然后为 Storport 示例勾选以下 7 条规则StorPortAllocatePool2——校验 StorPort 内存分配/释放的配对与返回值检查StorPortDeprecated——校验驱动是否调用了已弃用的 Storport 接口StorPortEnablePassive——校验被动初始化passive initialization注册的调用时机与上下文StorPortNotification2——校验 StorPortNotification 通知调用及其结果处理StorPortSpinLock——校验自旋锁的获取/释放是否成对、锁类型是否合法StorPortStartIo——校验 StartIo 回调路径中的执行约束StorPortStatusPending——校验 SRB 状态置为 PENDING 时的完成语义这份清单与工程中的 driver/sdv-user.sdv 文件逐行一致——该文件正是 SDV 默认加载的规则选择清单。第 3 步开始分析点击Main主选项卡点击Start开始按钮。点击 Start 后会弹出提示告知静态分析已被调度、分析可能耗时较长点击OK继续即可。分析期间 SDV 会在 Main 选项卡上持续报告分析状态分析结束后会给出结果与统计信息。若驱动未能满足某条 DDI 使用规则结果将以defect缺陷形式报告。7 条 Storport DDI 规则与缺陷注入点逐一对照lsi_u3.c源码中的每处缺陷都用醒目的Defect injection for: 规则名.slic注释块标注方便对照学习。下表汇总了 7 条规则对应的注入位置随后逐条展开SDV 规则注入点所在函数注入位置lsi_u3.c 行号StorPortAllocatePool2StartNegotiations分配段约 L2464释放段约 L2586StorPortDeprecatedLsiU3FindAdapter / BusResetPostProcess约 L1708 与 L799StorPortEnablePassiveLsiU3ISR约 L2185StorPortNotification2LsiU3FindAdapter约 L1694StorPortSpinLockSynchronizeReset约 L2333StorPortStartIoLsiU3StartIo约 L2666StorPortStatusPendingLsiU3StartIo约 L2715行号以当前仓库源码为准不同历史版本可能有细微偏移建议以Defect injection for:注释为检索锚点定位。StorPortAllocatePool2分配返回值未检查该规则要求驱动对 StorPort 分配类 API 的返回值进行校验且分配与释放必须成对、次数匹配。注入点采用Part A / Part B两段式缺陷Part A约 L2459-2464驱动调用StorPortAllocatePool(DeviceExtension, 4096, SPOO, bufferPointer)后没有检查 bufferPointer 是否为 NULLPart B约 L2584-2586随后无条件调用StorPortFreePool(DeviceExtension, bufferPointer)释放该缓冲区。源码注释直白地说明了违规本质The driver fails the rule because it doesnt check the return value of the allocation and unconditionally attempts to free the buffer.驱动因未检查分配返回值并无条件尝试释放缓冲区而违反规则。一旦分配失败对 NULL/无效指针的释放将造成内存管理错误——这正是 SDV 要拦截的典型缺陷。StorPortDeprecated使用已弃用的 Storport API该规则检查驱动是否调用了已被弃用的 Storport 接口。示例注入了两处Part A约 L1707-1713在LsiU3FindAdapter中调用StorPortValidateRange(...)来校验 I/O 范围而该接口属于已弃用 API源码注释注明 this call was already in the driverPart B约 L796-804在BusResetPostProcess中调用StorPortCompleteRequest(...)完成总线复位后挂起的所有请求。值得注意的是BusResetPostProcess上方有一段醒目的 WARNING 注释约 L783-793引用 2008 年微软 Windows 驱动开发者大会的建议不要在迷你端口中使用StorPortCompleteRequest因为它会导致竞态条件可能造成请求被双重完成或永远无法完成推荐做法是遍历迷你端口当前持有的所有请求逐个用StorPortNotification(RequestComplete)完成。示例特意保留这段注释用于解释为何StorPortCompleteRequest被视为弃用调用。StorPortEnablePassive被动初始化调用位置错误该规则校验StorPortEnablePassiveInitialization的调用时机。注入点位于LsiU3ISR中断服务例程中约 L2184-2188// Defect injection for: StorPortEnablePassive.slic if (StorPortEnablePassiveInitialization(DeviceExtension, LsiU3PassiveRoutine)) { }在中断上下文ISR中注册被动初始化回调本身就违反了该规则对调用环境的约束。与之配套文件末尾约 L8850 起定义了缺陷注入配套的被动初始化例程LsiU3PassiveRoutine头文件 driver/lsi_u3.h 中也有HW_PASSIVE_INITIALIZE_ROUTINE LsiU3PassiveRoutine;的声明注释注明 added as part of a defect injection。也就是说这条规则缺陷由注册调用 配套回调两部分构成SDV 需要跨函数路径才能完整验证。StorPortNotification2通知调用结果未校验注入点位于LsiU3FindAdapter中约 L1692-1694// Defect injection for: StorPortNotification2.slic StorPortNotification(GetExtendedFunctionTable, DeviceExtension, pExtFuncTable);驱动向 Storport 请求扩展功能表Extended Function Table但未对返回的pExtFuncTable做有效性检查局部变量初始化为 NULL 后直接使用。函数前部还声明了PSTORPORT_EXTENDED_FUNCTIONS pExtFuncTable NULL; // defect injection表明该变量专为缺陷注入而引入。若扩展功能表获取失败后续对空指针的解引用将引发严重故障SDV 通过该规则能够捕捉到这一未校验路径。StorPortSpinLock自旋锁未成对获取/释放注入点位于SynchronizeReset约 L2331-2333// Defect injection for: StorPortSpinLock.slic StorPortAcquireSpinLock(DeviceExtension, InterruptLock, NULL, IsrLockHandle);驱动在复位同步路径中获取了自旋锁局部变量STOR_LOCK_HANDLE IsrLockHandle{0}; // defect injection亦为注入所需但在该路径上没有对应的释放操作。自旋锁获取与释放不配对会破坏 IRQL 状态并可能造成死锁或同步错误这是 StorPortSpinLock 规则检查的核心语义。StorPortStartIoStartIo 路径中的无谓延时注入点位于LsiU3StartIo的普通 SCSI I/O 路径入口约 L2664-2666// Defect injection for: StorPortStartIo.slic StorPortStallExecution(1000);驱动在 StartIo 主路径中调用StorPortStallExecution(1000)主动忙等延时 1 毫秒。StartIo 回调承担着吞吐量敏感的关键路径职责不应引入无谓的忙等停顿——SDV 通过该规则识别出这条会降低 I/O 性能并可能影响同步语义的调用。StorPortStatusPendingPENDING 状态的错误处理注入点位于LsiU3StartIo中处理 SRB 请求的分支约 L2712-2715// Defect injection for: StorPortStatusPending.slic Srb-SrbStatus SRB_STATUS_PENDING; StorPortNotification( RequestComplete, DeviceExtension, Srb );驱动把请求状态置为SRB_STATUS_PENDING后立即调用StorPortNotification(RequestComplete)完成该请求。正确语义是当驱动设置 PENDING 状态时意味着该请求尚未完成、稍后才完成此时不应立刻发送完成通知。这种既标记 PENDING 又马上完成的矛盾行为正是 StorPortStatusPending 规则要拦截的缺陷——它会让 Storport 认为请求仍处于挂起状态从而引发状态机混乱。查看与分析 SDV 结果静态分析进行时SDV 会在Main选项卡上报告分析进度分析完成后报告结果与统计信息。对于本示例SDV 在默认 7 条规则下会发现 7 处缺陷defects。查看缺陷的流程如下在Main选项卡的Results结果区域点击Rules子选项卡这里列出上一次运行中每条被验证规则及其分析结果。点击Results结果列中的Defect链接SDV 会打开报告页Static Driver Verifier Report Page与跟踪查看器Trace Viewer展示从入口到规则违反点的完整代码路径跟踪。跟踪查看器中的缺陷路径是理解每条规则最有价值的部分它把函数调用链逐步还原展示缺陷是从哪个回调进入、经过哪些调用、最终在哪一步违反规则。对照本示例源码中Defect injection for:注释标注的位置你可以在报告中验证 SDV 是否精确命中了每一处注入点——这正是该示例的核心教学价值。源码中更多可探索的缺陷注入点除默认 7 条规则外lsi_u3.c中还标注了若干其他规则的缺陷注入点它们不在 driver/sdv-user.sdv 的默认清单中但可作为进阶练习在Custom rule selection中自行添加对应规则验证注入点标注的规则大致位置缺陷模式StorPortAdapterControl约 L1623-1625LsiU3AdapterControl一律返回ScsiAdapterControlUnsuccessfulStorPortVirtualDevice约 L1733-1734ConfigInfo-VirtualDevice TRUE强制声明虚拟设备StorPortFindAdapter约 L1909-1911注释掉MaximumTransferLength赋值使其保持未初始化值StorPortMSILock约 L1931-1933 与 L2634-2637声明使用 MSI 中断同步模式却在非 MSI 驱动中获取 MSI 锁StorPortPerfOpts约 L2091-2093StorPortInitializePerfOpts调用方式不当注释标注 SDV Result: TIMEOUT/SPACEOUTStorPortIrql约 L2141-2143在 ISR 中调用StorPortGetGroupAffinityStorPortAllocatePool约 L2812-2813未知 SRB 函数分支中的分配未配对释放StorPortNotification约 L3099-3102 与 L3357-3358请求完成通知后再访问ActiveRequest、完成后才调用StorPortGetOriginalMdl完成后使用型缺陷这些注入点同样以注释块标注适合作为扩展练习验证 SDV 在不同规则集下的检错覆盖面。总结与使用注意运行闭环在 Visual Studio 中通过Driver → Launch Static Driver Verifier...启动 SDV → 在Rules选项卡选择规则集默认或自定义→ 在Main选项卡点击Start调度分析 → 通过Results → Defect链接进入报告页与 Trace Viewer 查看缺陷路径。7 条规则、7 处缺陷默认规则集下 SDV 对本示例报告 7 处缺陷覆盖内存分配检查、弃用 API、被动初始化时机、通知结果校验、自旋锁配对、StartIo 延时与 PENDING 状态语义七类典型问题。源码对照学习所有缺陷均在 driver/lsi_u3.c 中以Defect injection for: 规则名.slic注释标注规则清单固化在 driver/sdv-user.sdv角色类型声明见 driver/lsi_u3.h。务必牢记本示例驱动的缺陷是故意注入的驱动本身不可运行、不可部署。它的正确用途是作为 SDV 的教学标本先在真实驱动上跑通 SDV 流程再回到这份错题集里逐条印证规则含义从而真正理解每条 DDI 规则在检查什么。赞分享示例工程【免费下载链接】Windows-driver-samplesThis repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver and desktop-only driver samples.项目地址https://gitcode.com/gh_mirrors/wi/Windows-driver-samples点击查看免费下载相关推荐StorAhci StorPort AHCI 迷你端口驱动深入解析从 DriverEntry 到 AHCI 控制器编程StorAhci StorPort AHCI 迷你端口驱动深入解析从 DriverEntry 到 AHCI 控制器编程 本指南以 Windows driver示例工程Windows-driver-samples 实战用 DV-FailDriver-WDM 验证 Driver Verifier 与 Device Fundamentals 测试如何捕获注入缺陷Windows driver samples 实战用 DV FailDriver WDM 验证 Driver Verifier 与 Device Fundam示例工程音乐解锁终极指南简单三步让加密音乐重获自由音乐解锁终极指南简单三步让加密音乐重获自由 你是否曾经为下载的音乐只能在特定播放器中打开而烦恼QQ音乐、网易云音乐、酷狗音乐等平台的加密格式让你无法自由享受示例工程上一篇Warp11/Warp未来路线图新功能预告与社区贡献指南下一篇如何快速搭建企业级后台管理系统React-Admin完整解决方案终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →