|
How do I cancel an IRP that another thread may be completing at the same time? |
Si vous voulez bloquer ce service sur vos fils RSS
Si vous voulez nous contacter ou nous proposer un fil RSS
Menu > Articles de la revue de presse : - l'ensemble [ tous | francophone] - par mots clé [ tous] - par site [ tous] - le tagwall [ voir] - Top bi-hebdo de la revue de presse [ Voir]
How do I cancel an IRP that another thread may be completing at the same time? Par A Hole In My HeadLe [2009-06-02] à 14:41:57
Présentation : Let's say that you allocated a PIRP and sent it down your device stack. You free the PIRP in the completion routine and then return STATUS_MORE_PROCESSING_REQUIRED. To make life more fun, you decide that you want to be able to cancel the sent IRP after you have sent it so you try to do it simple like this typedef struct _DEVICE_EXTENSION { KSPIN_LOCK SentIrpLock; PIRP SentIrp; } DEVICE_EXTENSION; Sending thread: KeAcquireSpinLock(etdevext-SentIrpLock, ...); devext-SentIrp = Irp; KeReleaseSpinLock(etdevext-SentIrpLock, ...); Canceling thread: KeAcquireSpinLock(etdevext-SentIrpLock, ...); if (devext-AllocatedIrp != NULL) { IoCancelIrp(devext-SentIrp); } KeReleaseSpinLock(etdevext-SentIrpLock, ...); Completion routine: PIRP irp; KeAcquireSpinLock(etdevext-SentIrpLock, ...); irp = devext-SentIrp; devext-SentIrp = NULL; KeReleaseSpinLock(etdevext-SentIrpLock, ...); IoFreeIrp(irp); return STATUS_MORE_PROCESSING_REQUIRED; And it then deadlocks ;). If the call to IoCancelIrp causes the IRP to be completed in the calling context (e.g. the one which has acquired the lock), the completion routine will run and try to acquire the lock (SentIrpLock) on the same thread which holds it. So, life is not that simple and you have to do something more. The basic solution is that you need extra state to track who is touching the PIRP and who can free it. Walter Oney's book has a solution (IIRC, it is in the self initiated I/O section, but I do not have the book handy), but IMHO it is a bit complicated. KMDF has a solution to this problem which I like much more (imagine that ;)). You need an extra LONG, calling it CompletionCount per PIRP that you want to be able to cancel. 1. You initialize CompletionCount to 1 before sending it down the stack and storing it in devext. 2. Whenever there is a thread that wants to cancel the PIRP, it tries to interlocked increment CompletionCount only if and only if the current CompletionCount value is 0. For this you need to roll your own InterlockedIncrementWithFloor which is fortunately not that hard and I have already shown you how to do that, http://blogs.msdn.com/doronh/archive/2006/12/06/creating-your-own-interlockedxxx-operation.aspx. 3. After the canceling thread has called InterlockedIncrementWithFloor and IoCancelIrp, it calls InterlockedDecrement. 4. Whomever wants to complete the PIRP, like the completion routine, interlock decrements CompletionCount. If the returned value from InterlockedDecrement is zero, the caller can complete the PIRP. If not, somebody else is trying to touch the PIRP and you must leave the PIRP alone. So here is the revised code: typedef struct _DEVICE_EXTENSION { KSPIN_LOCK SentIrpLock; PIRP SentIrp; ULONG CompletionCount; } DEVICE_EXTENSION; Sending thread: KeAcquireSpinLock(etdevext-SentIrpLock, ...); devext-CompletionCount = 1; devext-SentIrp = Irp; KeReleaseSpinLock(etdevext-SentIrpLock, ...); Canceling thread: PIRP irp = NULL; KeAcquireSpinLock(etdevext-SentIrpLock, ...); if (devext-AllocatedIrp != NULL etet MyInterlockedIcrementeWithFloor(etdevext-CompletionCount, 0) 0 ) { irp = devext-SentIrp; } KeReleaseSpinLock(etdevext-SentIrpLock, ...); if (irp != NULL) { IoCancelIrp(irp); if (InterlockedDecrement(etdevext-CompletionCount) == 0) { IoFreeIrp(irp); } } Completion routine: PIRP irp = NULL; KeAcquireSpinLock(etdevext-SentIrpLock, ...); irp = devext-SentIrp; devext-SentIrp = NULL; KeReleaseSpinLock(etdevext-SentIrpLock, ...); if (InterlockedDecrement(etdevext-CompletionCount) == 0) { IoFreeIrp(irp); } return STATUS_MORE_PROCESSING_REQUIRED; The beauty of this solution is that if you add more actors (let's say a timer for an async timeout, all you have to do is bump the CompletionCount to account for them to asynchronously rundown if you cannot cancel them. []
Les mots clés de la revue de presse pour cet article : thread
Les derniers articles du site "A Hole In My Head" :
- Arbitration and Translation, Part 3 - Translation and Windows - Arbitration and Translation, Part 1 - WDK v7.1 is now available - What is IRQL - one of the books that started it all... - Returning failure from DriverEntry - Once not disableable, forever not disableable - Inconceivableable - Using KeAcquireSpinLockAtDpcLevel is only a perf gain if you know you are DISPATCH_LEVEL
Menu > Articles de la revue de presse : - l'ensemble [ tous | francophone] - par mots clé [ tous] - par site [ tous] - le tagwall [ voir] - Top bi-hebdo de la revue de presse [ Voir]
Si vous voulez bloquer ce service sur vos fils RSS :
- avec iptables "iptables -A INPUT -s 88.191.75.173 --dport 80 -j DROP"
- avec ipfw et wipfw "ipfw add deny from 88.191.75.173 to any 80"
- Nous contacter par mail
Mini-Tagwall des articles publiés sur SecuObs : | | | | sécurité, exploit, windows, attaque, outil, microsoft, réseau, audit, metasploit, vulnérabilité, système, virus, internet, usbsploit, données, source, linux, protocol, présentation, scanne, réseaux, scanner, bluetooth, conférence, reverse, shell, meterpreter, vista, rootkit, détection, mobile, security, malicieux, engineering, téléphone, paquet, trames, https, noyau, utilisant, intel, wishmaster, google, sysun, libre |
Mini-Tagwall de l'annuaire video : | | | | curit, security, biomet, metasploit, biometric, cking, password, windows, botnet, defcon, tutorial, crypt, xploit, exploit, lockpicking, linux, attack, wireshark, vmware, rootkit, conference, network, shmoocon, backtrack, virus, conficker, elcom, etter, elcomsoft, server, meterpreter, openvpn, ettercap, openbs, iphone, shell, openbsd, iptables, securitytube, deepsec, source, office, systm, openssh, radio |
Mini-Tagwall des articles de la revue de presse : | | | | security, microsoft, windows, hacker, attack, network, vulnerability, google, exploit, malware, internet, remote, iphone, server, inject, patch, apple, twitter, mobile, virus, ebook, facebook, vulnérabilité, crypt, source, linux, password, intel, research, virtual, phish, access, tutorial, trojan, social, privacy, firefox, adobe, overflow, office, cisco, conficker, botnet, pirate, sécurité |
Mini-Tagwall des Tweets de la revue Twitter : | | | | security, linux, botnet, attack, metasploit, cisco, defcon, phish, exploit, google, inject, server, firewall, network, twitter, vmware, windows, microsoft, compliance, vulnerability, python, engineering, source, kernel, crypt, social, overflow, nessus, crack, hacker, virus, iphone, patch, virtual, javascript, malware, conficker, pentest, research, email, password, adobe, apache, proxy, backtrack |
|
|
|
|
|