[译]为驱动设备对象设置适当的安全描述符

[译]为驱动设备对象设置适当的安全描述符
正确的安全描述符能够让你有效的控制其他人对你的驱动设备对象的访问。通常,你可以调用:
IoCreateDeviceSecure 来创建驱动设备对象并拥有正确的 DACL 权限。IoCreateDeviceSecure
的一个问题是 SSDL 字符串的功能有限,一般来说,只能选用预定义的 SID 值。如果你想使用非
预定义的 SID 值,那么你必须自己创建安全描述符,令人遗憾的是这种编码的方法并不简单。

感谢 Paul Sliwowicz 热心的提供了以下这段为驱动设备对象设置适当的安全描述符的代码。不过,
这种方法需要你首先拥有打开驱动设备句柄的权限。因此,最好的方法是在最初创建设备时选择一
个非常严格的 SDDL 字符串从而限制其只能由系统打开,之后通过以下代码调低访问权限。这种方法
适用于 WDM 或者 KMDF 驱动程序。这种方法还可以用来调整其他驱动程序创建的驱动设备对象,但是
你必须仔细考虑并解决在设备创建和你设置安全描述符时的竞争问题。

NTSTATUS
SetDeviceDacl(
PDEVICE_OBJECT DeviceObject
)
{
SECURITY_DESCRIPTOR sd = { 0 };
ULONG aclSize = 0;
PACL pAcl = NULL;
    NTSTATUS status;

status = ObOpenObjectByPointer (DeviceObject,
OBJ_KERNEL_HANDLE,
NULL,
WRITE_DAC,
0,
KernelMode,
&fileHandle);

if (!NT_SUCCESS(status)) {
goto Exit;
}

//
// Calculate how big our ACL needs to be to support one ACE (in
// this case we'll use a predefined Se export for local system
// as the SID)
//
aclSize = sizeof(ACL);
aclSize += RtlLengthSid (SeExports ->SeLocalSystemSid);
aclSize += RtlLengthSid(SeExports->SeAliasAdminsSid);
aclSize += RtlLengthSid(SeExports->SeAliasUsersSid);

//
// Room for 3 ACEs (one for each SID above); note we don't
// include the end of the structure as we've accounted for that
// length in the SID lengths already.
//
aclSize += 3 * FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);

pAcl = (PACL) ExAllocatePoolWithTag(PagedPool, aclSize, TAG);

if (pAcl == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto Exit;
}

status = RtlCreateAcl (pAcl, aclSize, ACL_REVISION);
if (!NT_SUCCESS(status)) {
goto Exit;
}

status = RtlAddAccessAllowedAce (pAcl,
ACL_REVISION,
GENERIC_READ | GENERIC_WRITE | DELETE,
SeExports->SeLocalSystemSid);
if (!NT_SUCCESS(status)) {
goto Exit;
}

status = RtlAddAccessAllowedAce(pAcl,
ACL_REVISION,
GENERIC_READ | GENERIC_WRITE | DELETE,
SeExports->SeAliasAdminsSid );
if (!NT_SUCCESS(status)) {
goto Exit;
}

status = RtlAddAccessAllowedAce(pAcl,
ACL_REVISION,
GENERIC_READ,
SeExports->SeAliasUsersSid );
    if (!NT_SUCCESS(status)) {
goto Exit;
}

//
// Create a security descriptor
//
status = RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(status)) {
goto Exit;
}

//
// Associate the above pAcl with the security descriptor
//
status = RtlSetDaclSecurityDescriptor (&sd, TRUE, pAcl, FALSE);
if (!NT_SUCCESS(status)) {
goto Exit;
}

//
// Set security on the object
//
status = ZwSetSecurityObject (fileHandle, DACL_SECURITY_INFORMATION, &sd);
if (!NT_SUCCESS(status)) {
goto Exit;
}

Exit:
ZwClose(fileHandle);
fileHandle = NULL;

if (pAcl != NULL) {
ExFreePool(pAcl);
pAcl = NULL;
}

return status;

}

===========================================================================
PS: 翻译的比较差,一方面因为我的水平有限,另一方面是因为原话确实很难翻译。

原文为:

Setting a security descriptor on a legacy device object

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值