Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Best practices for Windows Kernel call-back functions and operations

MecanikMecanik Member Posts: 41
edited October 23 in NTDEV

I have asked opinions on this question on stack overflow, but unfortunately that "community" has become... poisoned. I'll leave it a that.

With that being said, I decided to come here, where the actual kernel experts are.

This question aims to get a bit of clarity and more information about Windows Kernel call-backs.

If you go the official documentation you will find the following:

  • Keep routines short and simple.
  • Do not make calls into a user mode service to validate the process, thread, or image.
  • Do not make registry calls.
  • Do not make blocking and/or Interprocess Communication (IPC) function calls.
  • Do not synchronize with other threads because it can lead to reentrancy deadlocks.
  • ...

From my own opinion, this defeats the purpose of having a call-back in the first place. If you can't validate a thread, image, process or even perform IPC... what's the point?

Based on MSDN you shouldn't even contact your service, or log information via IPC or registry, etc. So again, what's the point of having one?

Consider having an AV like product and you want to validate images on LOAD_IMAGE_NOTIFY_ROUTINE/OB_PRE_OPERATION_CALLBACK, you are not supposed to. So now what?

I've already seen countless drivers doing a lot of validations and operations in these call-backs, even though they do not follow "best practices". And yet, nothing "bad" happens.

Please share your thoughts as to:

  • Why is MSDN really recommending these best practices?
  • How would one perform "correct" and "best practice" operations without System Worker Threads? Because on the example above (LOAD_IMAGE_NOTIFY_ROUTINE/OB_PRE_OPERATION_CALLBACK), it would be pointless to "queue" a validation for an image for example, when your purpose is to prevent loading it if it's invalid. Please share an example if possible.

A5EF6AC930666A823A905224B7829A417718CA3360E62B9F890B722B20B8BDA5AE187C20E8F7070EADC6B82998999F02

Post edited by Peter_Viscarola_(OSR) on

Comments

  • Mark_RoddyMark_Roddy Member - All Emails Posts: 4,575

    Do not make calls into a user mode service to validate the process, thread, or image.

    I have no clue what that really means, but certainly you can notify your user mode service that it has work to do and wait for that work to complete, as that is basically the point of having the callback to begin with.

  • MecanikMecanik Member Posts: 41

    @Mark_Roddy said:

    Do not make calls into a user mode service to validate the process, thread, or image.

    I have no clue what that really means, but certainly you can notify your user mode service that it has work to do and wait for that work to complete, as that is basically the point of having the callback to begin with.

    Agreed. One of the methods... but look at what Microsoft says :)

    That's the whole question... WHY.

    A5EF6AC930666A823A905224B7829A417718CA3360E62B9F890B722B20B8BDA5AE187C20E8F7070EADC6B82998999F02

  • Mark_RoddyMark_Roddy Member - All Emails Posts: 4,575

    Well literally they tell you to not make a function call into a user mode service. So I agree: don't do that.

  • NiallNSecNiallNSec Member Posts: 3

    Certain types of drivers violate these conditions all the times. The biggest offender being AV/EDR products. The best practices, in my (limited) opinion, serve as more of a serious warning. Unless you know EXACTLY what you are doing you can cause serious problems by not following them, but that doesn't mean you can't do something like call a user mode service in a callback.

    Usually, if you need to break one of those rules, there will be an alternative safe way of achieving your goal which does follow Microsofts guidelines. So it should only be exceptional cases where you would consider breaking one of these rules. If you do choose to ignore Microsofts recommendations then you should be prepared for situations where a future update causes problems for your driver.

    (Also, it's worth noting that Microsoft themselves do appear to break these rules. If you were to, for example, suspend the windows defender user mode service you would be surprised to find that many things stop working because they are held up in WdFilter.)

  • MBond2MBond2 Member Posts: 494

    I think that you should apply judgement to these rules. In any performance critical section of anything, keeping the work to be done as short and simple as possible is an obvious goal. Avoiding blocking or waiting gratuitously should be done. But when the functional objective cannot be achieved without blocking, then blocking must happen. Just make sure that you have a strategy to avoid deadlock and consider what to do if the component that you need to wait on does not respond - usually a decision to fail open or fail closed

    Mark's literal interpretation that they tell you not to execute a call instruction targeting a UM address should also be followed of course ;)

  • brad_Hbrad_H Member Posts: 125
    edited October 28

    @Mark_Roddy said:

    Do not make calls into a user mode service to validate the process, thread, or image.

    I have no clue what that really means, but certainly you can notify your user mode service that it has work to do and wait for that work to complete, as that is basically the point of having the callback to begin with.

    I'm pretty sure they are talking about FltMgr's Communication Ports.

    And there is no issue in using communication ports to contact your service for some user-mode checking.

  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,519

    Originally some of these Ps callbacks were called with a non-recursively acquirable per-process lock held. If you happened to try and perform an operation that also attempted to acquire this lock you'd deadlock. This led to confusing and draconian language being added to the docs telling people to basically not do anything in these callbacks.

    The locking has changed over time and it's possible to do more in these callbacks these days, though the guidance stays (presumably to avoid constraining the Ps implementation from changing in the future). Though the primary issue is around anything to do with the process (address space, PEB, loaded moduies, etc.). Lots of products just end up scanning the underlying file (e.g. FltCreateSectionForDataScan) and that would be safe given that there are no file system locks held in these callbacks. Anything else they're doing just happens to work by way of the current implementation.

    -scott
    OSR

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 January 2023 Live, Online
Developing Minifilters 20 March 2023 Live, Online
Writing WDF Drivers TBD 2023 Live, Online
Internals & Software Drivers 17 April 2023 Live, Online