It is for IRP_MJ_SET_SECURITY. I’m trying to get the before and after of a security change, so trying to grab the existing security descriptor before the new one goes down the stack and overwrites it.
OK, that makes sense, I get it now.
The code is checking every function’s return value.
OK, the overall set security operation must be failing then. 0x8007051B is the HRESULT version of ERROR_INVALID_OWNER, which is NTSTATUS STATUS_INVALID_OWNER (0xc000005a). You could do the NTFS status debugging trick to trap the error where it happens, but that probably won’t tell you more than the fact that it’s failing…
My theory would be that NTFS/Se are making assumptions about the calling thread in the IRP_MJ_SET_SECURITY request. By posting to a worker thread you’re disassociating the caller and the requestor. Impersonating the requestor might fix it OR just don’t post the call (more below).
The docs for FltQuerySecurityObject say required IRQL level is PASSIVE_LEVEL if I’m reading it right, so posting a callback seems like the only way to be guaranteed to be at that level for the call.
IRQL and PreOperation callbacks is murky so it’s easy to over engineer…IRP_MJ_SET_SECURITY requests are generated by {Zw|Nt|Flt}SetSecurityObject, all of which require PASSIVE_LEVEL operation. Sure, a driver could build the IRP and send it at DISPATCH_LEVEL, but that would be a really bad idea. All the SeXxx APIs require PASSIVE_LEVEL and NTFS even puts its IRP_MJ_SECURITY code in a pageable section.
The file systems can’t handle being called for security info at DISPATCH_LEVEL anyway.
I didn’t know that. Being called at PASSIVE_LEVEL should be safe then right? Or are you implying that IRP_MJ_SET_SECURITY will always come in at PASSIVE_LEVEL anyway? Could it come in at APC_LEVEL?
I wouldn’t expect to see it at APC_LEVEL or a Guarded Region (which has the same behavior as APC_LEVEL). I could maybe see another filter sending it in a Critical Region (e.g. if they had an ERESOURCE held). Though in any case none of these should cause a problem from a functional standpoint for this API. Worst case you might run afoul of FltMgr Verifier.
I saw this today on my system - Windows Update failed with the IRP_MJ_SET_SECURITY PreOp processing, but turning it off allowed updates to install. But I can set security properties, change owner, change inheritance, etc, etc from Windows Explorer while IRP_MJ_SET_SECURITY PreOp processing is running without issue.
It’s possible the files being laid out have just the right Security Descriptors associated with them to trigger the behavior. I’d do the NTFS status debug trick and then dump the Security Descriptor in the IRP with !sd so see if there’s anything special about it.