The inability to lock someone out of the registry is a feature, not a bug


There is no way to lock the registry. Whereas you can open a file with a deny all sharing mode to prevent anyone else from opening the file, the registry has no such provision. You can’t lock a registry key and prevent others from reading from or writing to it. There is an internal lock on the registry, but that’s just to ensure that registry operations are atomic; that is, that if one thread writes a value to the registry and another thread reads that same value from the registry, then the value that comes back is either the value before the write took place or the value after the write took place, but not some sort of mixture of the two.

Some people consider the inability to lock the registry to be a bug but it’s actually a feature. It means that nobody can launch a denial of service attack against the registry by opening a key in an exclusive mode and preventing anybody else from reading it. This is important, because many security settings are stored in the registry, and locking somebody out of a registry key means that the part of the operating system whose job it is to enforce the security of a particular feature would no longer be able to check whether the operation is allowed.

This all means that if you’re reading from the registry, you have to accept that the contents can change while you’re reading them, in the same way that you have to accept that the file system can change. If you’re writing to the registry, you can take advantage of transactional registry support new to Windows Vista.

Comments (31)
  1. Alexander Grigoriev says:

    Allowing any user to lock files he doesn’t have access to is a bigger denial of service bug. You can open a handle to a critical system file, with minimal access requested (FILE_READ_ATTRIBUTES), or just GENERIC_READ, and pass zero as ShareAllowed, and nobody else will be able to open the file.

  2. Adam V says:

    @Alexander:

    I think I’m missing your point. Why would a regular user have access, even read-only, to critical system files?

  3. John says:

    Well, on Windows XP the Users group has Read access to everything in C:WINDOWS and C:WINDOWSsystem32.  Of course, by the time Explorer comes up all the critical system files are already loaded by the operating system.  However, you can still open something like taskmgr.exe or mmc.exe in exclusive mode and prevent other users from running it.  Sounds like a denial of service to me.  However, the Administrator could always come along and fix it so it’s not like it’s a critical vulnerability.

  4. Alexandre Grigoriev says:

    John, Adam V

    Some services, started by a scheduler, such as Windows update, installer, etc, are not loaded all the time. If a malicious app, even running under limited user, can lock those EXEs/DLLs out, that will prevent the services from starting.

    The administrator cannot fix that, because MSI executable also needs to run under an user.

    AND, YOU DON’T NEED TO HAVE READ ACCESS TO A FILE TO LOCK IT OUT. ALL YOU NEED IS TO HAVE "LIST CONTENT" or "TRAVERSE" ACCESS TO ITS DIRECTORY.

    I suggest to always imply FILE_SHARE_READ|FILE_SHARE_WRITE, unless the CreateFile caller has "modify" access to the file.

  5. d_e says:

    Raymond: Exactly the same argument can be applied to files. IMHO, locking is a missing feature of the registry.

    Regular users should not be able to lock a security-relevant key. They shouldn’t have the rights to do so. If this is the case it’s not a DoS-vulnerability.

  6. Kevin says:

    Doesn’t wiping out the registry achieve the same effect as DoS?

  7. Rich M says:

    There may not be a lock, but you CAN add ACLs to a registry entry, allowing you a measure of control over it.

  8. Gwyn says:

    If you have the access to completely wipe out the registry, then you probably already have administrator access so you could do much worse than a DoS.

  9. Gabe says:

    Why would you need to lock the registry?

  10. henke37 says:

    Ah, great, the msdn url has 404’d before I got to read the article. Let’s hope this is just a random hickup that will solve itself and not just another msdn url invalidation.

    [I like how people go to the most conspiratorial explanation first. I mistyped the URL. Fixed. -Raymond]
  11. configurator says:

    Gabe: For example, to add an entry to an MRU, in a multi-application-safe manner where multiple applications can add values at the same time.

  12. John says:

    Alexandre:

    I don’t see what the problem is.  Yes, somebody can lock the Windows Update service executable (or anything else).  But the Administrator can always come along and kill the process that has it locked (or forcefully logoff the user).

  13. Richard says:

    John:

    Unless it’s Vista/Server 2008 and the "program" in question is a Service.  Hello Mandatory Integrity Control and Service isolation.  And if the Service has been created with evil intent, then the Service Control Manager will be unable to stop it (try to stop the "Remote Procedure Call" Service, for example).

  14. John says:

    Richard:

    If you’re the administrator, you can shutdown the service.  If the service is malicious, then it’s already on the other side of the airtight hatch.

  15. Alexandre Grigoriev says:

    John,

    "But the Administrator can always come along and kill the process that has it locked (or forcefully logoff the user)."

    What if "administrator" is just another clueless user, and the locked service is "antivirus update"? And how would Administrator (capital A) know the file is locked? Would he be always watching the system log, as if it’s a R.Chan blog?

  16. Alexandre Grigoriev says:

    “If the service is malicious, then it’s already on the other side of the airtight hatch.”

    The service can run with reduced privileges, for example as NetworkService account. It’s not almighty then.

    [Irrelevant. You need admin privileges to install the service in the first place. That’s the airtight hatch you’ve already gotten to the other side of. -Raymond]
  17. Gaspar says:

    I think a lot of people are ignoring the most common situation that this would effect, the average, barely computer literate consumer.

    Example:

    Our consumer (we can call him Bob) wants to browse ebay for new Elvis commemorative plates.

    Bob sits down at his computer and turns it on.  It goes through startup process which include XYZ anti-virus/firewall/toaster program.

    When XYZ anti-virus/firewall/toaster program starts up it does its thing which now includes locking registry key UVW.

    Next Bob fires up his browser.  The first thing that browser does is check UVW registry key.  But now, UVW registry key is locked and can’t be read.  So our browser sits until XYZ anti-virus program unlocks it.

    What is the AVERAGE users experience?  "My F@$#ing computer doesn’t work…"  Followed by getting mad about various things and calling and blaming many companies who all pass the buck elsewhere.

    What is the plus side for this?  Making it easier for a developer to put information in a registry key that most likely probably is best placed elsewhere?  That does not sound like a good trade off to me.

    As for why any particular program would lock a key?  Does it really matter, if someone CAN do something, it WILL happen.  Be it software bug, bad design, malicious use, or other.

    My understanding is that the registry is shared data.  Because it is shared no one person should be able to have say over everyone else.  Hence, just because you want to lock everyone else out, doesn’t mean that everyone else likes that idea.  If everyone else was fine being locked out of registry key UVW, then why are they even bothering to look at it in the first place?

  18. ERock says:

    While perhaps I’ve missed the point, thank you Raymond for pointing out Transactions are supported in the Registry in Vista. It’s a feature I welcome wholeheartedly.

  19. Alexandre Grigoriev says:

    “The service can run with reduced privileges, for example as NetworkService account. It’s not almighty then.

    [Irrelevant. You need admin privileges to install the service in the first place. That’s the airtight hatch you’ve already gotten to the other side of. -Raymond]”

    What if the service was compromised by a remote exploit? There is a reason the network-facing services run with reduced privileges now.

    [Okay, so first we start with “Assume somebody installed a rogue service” and then you changed it to “Assume somebody found a remote exploit in an existing service” and now I don’t even know what we’re talking about. Let’s talk about why you can’t lock a registry key. -Raymond]
  20. John says:

    "What if "administrator" is just another clueless user, and the locked service is "antivirus update"? And how would Administrator (capital A) know the file is locked? Would he be always watching the system log, as if it’s a R.Chan blog?"

    And what if the administrator gets hit by a bus while walking his dog?  My assertion was simply that it is possible for an administrator to fix the problem.  Anything further than that is outside the scope of this discussion.

  21. Richard says:

    John:

    Point taken with the default settings for MIC.  But what about enabling the policies SYSTEM_MANDATORY_POLICY_NO_READ_UP and/or SYSTEM_MANDATORY_POLICY_NO_EXECUTE_UP?  It is my understanding that these policies would prevent lower integrity level processes from interacting with said process, including using TerminateProcess(). But I could be wrong.

  22. Aaron Margosis says:

    OK, so I got curious, wrote a program that calls CreateFile to open system32reg.exe for GENERIC_READ, setting share mode at 0, and holds onto the handle.  Went to another console window and ran "reg.exe /?".  It ran fine.  Ran another copy of the test program and it wasn’t able to open reg.exe.  But I could still execute it.  So… I don’t think there’s even a DoS here, at least not as described.  (Ran the test on Vista SP1 x64.)

  23. Alexandre Grigoriev says:

    Aaron,

    That’s interesting data point. I’m curious what it was on previous OSs.

    Executing a file requires GENERIC_EXECUTE rights, which doesn’t use FILE_READ_DATA. Apparently, file locking only controls FILE_READ_DATA and FILE_WRITE_DATA rights.

    To use a memory mapped file, one has to only have GENERIC_EXECUTE rights.

  24. Adam Ruth says:

    I think that even having this discussion highlights that too much stuff is being put into the registry. It’s not a database, it’s an API that has been abused, to everyone’s detriment.

    I try to only use it to store information during the installation of an application, to "register" the application if you will. Stuff that the app may need to know on start up.

  25. John says:

    Aaron:

    I did the same thing with taskmgr.exe on XP 32-bit and I couldn’t execute it.  Is your test app 64-bit?  If not, perhaps WOW64 is redirecting you to syswow64reg.exe.  Then when you run reg.exe from the command line, you are actually running system32reg.exe (which is not the file that is locked).  I don’t have a 64-bit machine in front of me to test this theory.

  26. Leo Davidson says:

    "Why would you need to lock the registry?"

    The trivial, every-day example is simply reading a value from the registry properly.

    You have to query the value with a null buffer first to get the buffer size, then allocate the buffer, then query it again with that buffer. There’s nothing to stop the value being written between those two operations, meaning any correct registry-reading code actually has to be a loop.

    (Of course, in reality, you can get almost always get away without doing that.)

    "It means that nobody can launch a denial of service attack against the registry by opening a key in an exclusive mode and preventing anybody else from reading it."

    Security settings should be read-only for non-admin processes (obviously). If the Registry had *shared* read locks then there would be no way for a non-admin process to prevent anything else from reading those keys. (Such processes could only prevent them from being written to, but that’s the same as files and you could ACL stuff to not allow non-admin processes to read it at all if needed.)

    Allowing a non-admin process to get an exclusive read lock could cause problems, but I don’t think that means the entire concept of locking need be thrown out the window (unless there are other reasons).

  27. Aaron Margosis says:

    @John – I did make that mistake at first, but built an x64 version, verified everything with Process Monitor, and still wasn’t locked out from using reg.exe.

    But:  just tested on Server 2003 SP2 x86 and the issue did manifest.

  28. Gabe says:

    It seems like nobody has noticed that locking a registry key is not like locking a file — it’s like locking a directory, which you can’t do. Locking a value is like locking a file, but since accessing a value is atomic you shouldn’t need to lock it.

    Of course it could be growing as you’re trying to access it, making it impossible to make a buffer big enough. However values are at most 64k bytes, so a buffer that big will always fit and you won’t have to worry then.

  29. Worf says:

    @Aaron: maybe Vista fixed that potential DoS from happening – if an app is locking the file but it’s only being read, and it’s an executable, run anyways?

    Or perhaps some system executables…

  30. Pinocchio says:

    The inability to lock someone out of the registry was originally intended to be a PR stunt.  The plan was to deny the existance of all such functions until a few months before the Windows 1.0 release, and then announce the incredibly extensive support for registry locking to build hype and sales.

    Indeed, a full 97% of the original Win16 API was intended to be dedicated solely to various forms of locking yourself out of the registry!

    When public opinion unexpectedly showed such strong support for the inability to lock someone out of the registry, Microsoft had to quickly scrap their highly extensive API of 14,550 registry locking functions.  They ended up shipping Windows 1.0 with the remaining 450 functions that form the current basis for the Windows API.

  31. Dog says:

    @Pinocchio: The registry didn’t exist in Windows 1.0. It was introduced with OLE in Windows 3.0.

Comments are closed.