METHOD_NEITHER vs MDL vs __try/__except and handling bad user momory

Good morning folks.

Just wanted clarify one simple thing. To do this let me start with known windows driver samples:Windows-driver-samples/general/ioctl/wdm/sys/sioctl.c at main · microsoft/Windows-driver-samples · GitHub

Suppose I have a driver that is regular legacy WDM driver (with virtual device object, not attached to anything, not filter etc) with defined IOCTL with METHOD_NEITHER for which I can send 100B of memory from caller (lets say it is stack memory of caller).

  1. I think OS guarantee that ioctl dispatch function (fast dispatch or regular dispatch) will be always called from withing context of service that sends ioctl, thus I guess to properly handle such ioctl is to do ProbeForRead like here: Windows-driver-samples/general/ioctl/wdm/sys/sioctl.c at main · microsoft/Windows-driver-samples · GitHub but I do not need to allocate MDL that will describe caller memory as I know that this memory comes from PsGetCurrentProcess(). In other words I can skip this part Windows-driver-samples/general/ioctl/wdm/sys/sioctl.c at main · microsoft/Windows-driver-samples · GitHub - is that correct?
  2. There are however some things I need to think off - so I cannot for instance touch this memory from DISPATCH (like under spinlock), but ERESOURCE would be ok in this case?
  3. Moreover touch of user memory should be probably done from withing __try/__except block to prevent access of memory that is broken/unavailable - is that correct?

If all above is correct (please correct me if there are any wrong assumptions) I still think about few things especially how OS protect caller of IOCTL in this case:

  1. Is caller prevented from killing? Suppose I send 100B with METHOD_NEITHER to driver and driver is processing those, but in meantime some other process will KILL/CRASH my service. What will happen with this user memory that driver is handling? will be there exception in __except block or maybe OS is delaying killing of process (I guess thread that is doing IOCTL and in which driver is working cannot be killed just like that - becuase that would make all OS unstable).
  2. What if there is bug in service and while driver is accessing this memory it becomes invalid (say there is buffer overrun, or free done on this memory in meantime due to bug) in such case __except will happen - is that correct?
  3. Finally I understand that __try/__except is handling also paged out memory - in other words: if under __try/__except block I do dereferece of user memory that is paged out for any reason - OS will silently bring it back and it will be not visible to driver - is that correct?

Looks like many nooby questions.
Thank you for your help!

Oh! I figured out I should rather post this to NTDEV forum - is there option to move it there? I dont see such :frowning: apologies for confusion

Thank you for moving my question into more proper place. :+1:

Your assumptions sound right. A few points that I think will answer your questions more broadly:

  1. Reading/writing* an invalid user mode address at IRQL < DISPATCH_LEVEL raises an exception that you can catch with __try/__except. Doesn't matter if this is write to read only, use after free, overrun, etc. As long as you're in a __try/__except every time you access the buffer you're "good to go".

    Accessing paged out memory doesn't raise an exception because the page fault is
    handled and the instruction is just retried.

  2. Accessing an invalid user address at IRQL >= DISPATCH_LEVEL causes an IRQL_NOT_LESS_OR_EQUAL crash. You can't catch this with a __try/__except

  3. Accessing an invalid kernel address always causes a system crash. You can't catch these with a __try/__except. This is one reason why you need to ProbeForRead/ProbeForWrite the address that comes from user mode before accessing it within a __try/__except: those APIs will raise an exception if the address passed in is a kernel address (even if it's valid!)


*Trying to execute user mode addresses is another beast because that's covered by Supervisor Mode Execution Protection

1 Like

Thank you Scott. It answers my question perfectly!