I am migrating the USB driver(written using WDM) from Windows 7 to Windows 10/11 operating systems.
While running the Static Driver Verifier tool, it detected issues around RemoveLock for IRP.
As per the code, when an IRP is received, IoRemoveLock is acquired with the IRP itself as a tag.
The acquired IoRemoveLock with the IRP tag is released in the context of the completion routine of that particular IRP.
But, SDV is detecting incorrectly for Acquiring and Releasing of IoRemoveLock. SDV is only checking for the IoAcquireRemovelock and IoReleaseRemoveLock pair, whereas ideally, it should check for the acquire-release pair concerning the Tag, because of this SDV is resulting in false defects.
Can anyone tell me how to make a False Positive for SDV in the above scenario?
I’m not sure exactly what you are asking, but it is usually wrong for a lock to be acquired in one context, and released in another. Otherwise, what is the lock protecting? Even if it is not a bug per se, it probably reduces performance
Every time I investigate codeql I run into the absurd licensing quagmire and the installation mess and conclude that I’ll once again put off doing anything about it until that mess is cleaned up. If I have to whql something I’ll grudgingly use it.
(not to mention that, the last time I used it, there was no way to tell it to suppress a given instance of a warning. Which is, on its face, ridiculous.)
Yes, that is true, basically we acquire the removelock by using the tag as PIRP so that it would be easier to track the IRP. Initially when an IO Request is triggered, we acquire the IoRemoveLock with IRP as tag and add the same to the pending, later when this IRP is serviced, in completion routine we are releasing the IoRemoveLock with the same PIRP tag.
When I run SDV, even though the tags are different, it is giving false positive results.
Can anyone tell me how to use __assume_analysis or similar tags to make SDV false positive? Specially in case of Acquiring and releasing of IoRemoveLocks?
Well, you're not giving us much to go on. I mean, how can we help you when all you tell us about your problem is "SDV is giving me a false positive"? The question I have is: Is SDV wrong, or is your code actually broken?
Hmmm... well... probably not. Just like the tag on pool allocations, the tag on Remove Locks is informative for debugging purposes. It doesn't actually cause any change in behaviors of the Remove Lock logic.
In other words, it's not clear to me if your code is correct or not.
No, my code is not broken. It is using the IoRemoveLock's properly.
Following is the flow of acquiring and releasing IoRemoveLock w.r.t IRP handling.
1. Once the IoRequest is triggered
2. From the driver side,
A. It will acquire the lock with IRP as tag
B. Verify the Device PNP state
i. If device is not busy mark current IRP as active and process the IRP
a) IoSetCompletion Routine to SyncComplete routine
b) Call the lower driver
c) And return
ii. Else, if device is busy addressing another IORequest
a) Add the IRP to the PendingIoQueue and
b) Return
C. Once lower driver completes processing the IRP and the SyncComplete routine is triggered
i. Do the necessary tasks
ii. While, doing the cleanup, it will release the IoRemoveLock acquired at step.2.A
For every IRP received, the driver acquires the IoRemoveLock, adds the IRP to PendingIoQueue, and returns.
Later, when the driver processes each IRP in the queue, it completes the IRP and releases the IoRemoveLock.
In this way, acquiring and releasing of IoRemoveLock is handled in correct manner.
SDV Issue Scenario:
Consider the IRP_MN_REMOVE_DEVICE case:
Suppose there is an existing IRP (with IRP-tag=1) in PendingIoQueue and driver receives IRP_MN_REMOVE_DEVICE (here IRP-tag=2)
1. When the driver receives IRP_MN_REMOVE_DEVICE (here IRP-tag=2),
2. Driver acquires IoRemoveLock with the IRP-tag=2
3. For each IRP existing in PendingIoQueue
A. Free allocated resources
B. cancel all IRPs with status=STATUS_DELETE_PENDING and
C. Release the IoRemoveLock acquired for that particular IRP tag
***> SDV Error: Actual problem is here. As per code, we are releasing the lock acquired for IRP-tag=1, but SDV assumes that this IoReleaseLock is for IRP-tag2***
4. Set the IoStatus to success and pass IRP to lower driver
5. Release the IoRemoveLock for IRP-tag=2
***> SDV Error: As SDV assumes that acquired lock is released earlier in Step3.C here it is failing with error "The routine was called without first acquiring the RemoveLock"***.
6. Detach and delete device.
7. Return status.