无法验证对象句柄
某些驱动程序必须操作调用方传递给它们的 对象,或者必须同时处理两个文件对象。 例如,调制解调器驱动程序可能会接收事件对象的句柄,或者网络驱动程序可能会接收两个不同文件对象的句柄。 驱动程序必须验证这些句柄。 由于它们由调用方传递,而不是通过 I/O 管理器传递,因此 I/O 管理器无法执行任何验证检查。
例如,在以下代码片段中,驱动程序已传递句柄 AscInfo-AddressHandle>,但在调用 ObReferenceObjectByHandle 之前尚未对其进行验证:
//
// This handle is embedded in a buffered request.
//
status = ObReferenceObjectByHandle(
AscInfo->AddressHandle,
0,
NULL,
KernelMode,
&fileObject,
NULL);
if (NT_SUCCESS(status)) {
if ( (fileObject->DeviceObject == DeviceObject) &&
(fileObject->FsContext2 == TRANSPORT_SOCK) ) {
虽然调用 ObReferenceObjectByHandle 成功,但代码无法确保返回的指针引用文件对象;它信任调用方传入正确的信息。
即使调用 ObReferenceObjectByHandle 的所有参数都正确且调用成功,如果文件对象不用于其驱动程序,驱动程序仍可能获得意外结果。 在以下代码片段中,驱动程序假定成功的调用返回指向预期文件对象的指针:
status = ObReferenceObjectByHandle (
AcpInfo->Handle,
0L,
DesiredAccess,
*IoFileObjectType,
Irp->RequestorMode,
(PVOID *)&AcpEndpointFileObject,
NULL);
if ( !NT_SUCCESS(status) ) {
goto complete;
}
AcpEndpoint = AcpEndpointFileObject->FsContext;
if ( AcpEndpoint->Type != BlockTypeEndpoint )
尽管 ObReferenceObjectByHandle 返回指向文件对象的指针,但驱动程序不保证指针引用它所需的文件对象。 在这种情况下,驱动程序应在访问 AcpEndpointFileObject-FsContext> 处的特定于驱动程序的数据之前验证指针。
为了避免此类问题,驱动程序应检查获取有效数据,如下所示:
检查对象类型,确保它是驱动程序所需的类型。
确保请求的访问权限适用于对象类型和所需任务。 例如,如果驱动程序执行快速文件复制,请确保句柄具有读取访问权限。
请确保 (UserMode 或 KernelMode) 指定正确的访问模式,并且访问模式与请求的访问权限兼容。
如果驱动程序需要驱动程序本身创建的文件对象的句柄,请针对设备对象或驱动程序验证句柄。 但是,请注意不要破坏为奇怪设备发送 I/O 请求的筛选器。
如果驱动程序支持多种文件对象 (,例如控制通道、地址对象和 TDI 驱动程序的连接或文件系统) 的卷、目录和 File 对象,请确保有办法区分它们。