When people ask for security holes as features: Privileged execution


A customer wanted to know if there was a way to execute privileged instructions without having to write a driver.

"I just need to execute a few instructions, and writing a driver would be overkill since it's only three instructions. Is there a way I can execute these privileged instructions without a driver?"

The whole point of having a class of modules called drivers is to prevent somebody from doing exactly what you're asking for. Only drivers can execute privileged instructions; that's why they're called privileged instructions.

"Yeah, but I just need three instructions. Do I have to write a whole driver just for those three instructions?"

Even just one instruction can pwnz0r a machine. You have to be a driver in order to have that much power over the computer.

"Maybe there's a driver somebody has already written that I can give the instructions to, and it'll execute them for me?"

If somebody has written a driver which is designed to execute arbitrary instructions handed to it from user-mode, that person needs to be taken outside and beaten. It's one thing to have a bug that permits arbitrary code execution, but to have it as the purpose of your driver?

Think of writing a driver as having access to the secure area of a nuclear power plant. People have to be granted the appropriate security clearance before they are allowed into enter the control room. If you want to get into the control room of the nuclear power plant, you'll have to apply for security clearance.

"But that's so much work. I just need to go in and change a few settings on the control panel."

Dude, that's why you're not allowed in, so you won't change those settings!

Your options are either to get security clearance yourself, or convince somebody with security clearance to change the settings for you.

"Well, do you know somebody who does have security clearance who will change any settings I tell him to?"

Gosh, I sure hope not.

Comments (69)
  1. Medinoc says:

    <<"Maybe there’s a driver somebody has already written that I can give the instructions to, and it’ll execute them for me?">>

    This reminds me an awful lot of inpout32.dll. The only privileged instructions it allows are IN and OUT (as in inp() and outp()), but I’m sure you can already do quite a bunch of bad things with them.

  2. sp says:

    We used to use a driver that we bought in that let you talk to arbitrary hardware without all of that tedious "writing a driver" business in my first programming job, and we went about installing it willy nilly on all our customers computers, whether their configuration needed it or not. It didn’t occur to me at the time how scary that was, but I guess there is nothing you can do about it. As long as no one is dumb enough to install it – oh…

  3. Medinoc says:

    About inpout32.dll, I hope at least it requires to run as an Administrator, but I can’t find the information explicitly stated anywhere.

  4. dave says:

    In a previous job, I had a TCL interpreter running in kernel mode on Windows NT, to which I could feed commands from user mode.  What could possibly go wrong?  ;-)

    (It was used for testing: we were developing a file system driver and the TCL interpreter had commands to fondle the inside of the driver).

    I promise the TCL driver wasn’t shipped.

  5. Wheeto says:

    The driver for the DLL other commenters are referring to needs to be installed by a user with the correct privileges.  After it is installed, the permissions to use it can be set appropriately.

  6. asd says:

    I think that guy mostly had problems with the amount of work needed to permit the application to execute privileged instructions, not with the idea of privileges itself. “I say this application won’t do harm and I want to allow it to run privileged instructions. This is my computer, I’m the boss here, where should I sign?” – “No, you’re wrong, Microsoft’s the boss here. Go spend several days writing a driver, this is the procedure we have for such things here.”

    [And this differs from other modern operating systems how exactly? -Raymond]
  7. Matt Newman says:

    "I say this application won’t do harm and I want to allow it to run privileged instructions. This is my computer, I’m the boss here, where should I sign?" – "No, you’re wrong, Microsoft’s the boss here. Go spend several days writing a driver, this is the procedure we have for such things here."

    The machine is yours and you can tell give it any instruction you want BUT Windows as a feature doesn’t allow you to do that without following its procedures. If you don’t like that feature you can leave Windows and do it yourself.

  8. Joseph Koss says:

    It sure sounds to me like the person you were talking to is intimately familiar with assembly language and the hardware architecture, but not familiar with the (this?) operating systems heavy-handed dot-every-i cross-every-t requirements.

    Remember that 64-bit drivers MUST BE SIGNED, so the OS is not only requiring that his needs be expressed in the form of a driver, but also that he send some payola to an authorized signing authority.

  9. David Walker says:

    Joseph: @hat "payola" comment was rude and unneccessary.  Verifying drivers is a lot of work.  It’s no better in the other worlds, where no outside or non-authorized companies can write drivers (or legally create interoperable hardware).  

  10. Yuhong Bao says:

    "This reminds me an awful lot of inpout32.dll. The only privileged instructions it allows are IN and OUT (as in inp() and outp()), but I’m sure you can already do quite a bunch of bad things with them."

    This reminds me quite a bit of OS/2’s IOPL support, where you can tag an export as IOPL and optionally specify a parameter copy count, then OS/2 will create a call gate to Ring 2, which have IOPL privileges, and then you can execute IN/OUT and CLI/STI. Sadly the elimination of segmentation in 32-bit OS/2 make this impossible, hence you need a 16-bit OS/2 DLL in order to do this.

  11. Steve says:

    OK, someone said "Yuhong Bao, Yuhong Bao, Yuhong Bao", who was it?

  12. "OK, someone said "Yuhong Bao, Yuhong Bao, Yuhong Bao", who was it?"

    I’m pretty sure he’s a clever combination of a Markov chain generator and a Wikipedia scraper. The writing style is about what you’d expect.

  13. slab says:

    "It’s no better in the other worlds, where no outside or non-authorized companies can write drivers (or legally create interoperable hardware)."

    Um, what other worlds would those be?

    You don’t have to work for Apple to write a driver for OS X, nor do you have to work for Red Hat/Ubuntu/Linus/whoever to write a driver for Linux, nor do you have to work for Sun to write a driver for OpenSolaris.

  14. asd says:

    [And this differs from other modern operating systems how exactly? -Raymond]

    Yeah, sorry, I was imprudent to blame specifically ms, it’s not like I’m ms-hater or something. I just tried to explain how that guy should have thought. "Obviously if the problem is just in permissions, then all that it should take is to ask for permission from user".

    Then it turns out he needs to write a special, compiled with a separate ddk, built on a different set of functions and digitally signed application <i>just to be able to ask for that permission</i>. No wonder he thought there should be a short way after all. All the more if the thing he was trying to do was something simple and harmless.

    I’m not trying to blame nobody here, just saying that it’s kinda clear why these things happen. Design your teapot in a form of hammer and you’ll see people hitting nails with it.

  15. John says:

    Ken: Don’t you have to enable test signing mode when using self-signed certificates?  I don’t think many people are willing to run a production system like that.

  16. asd says:

    On the second thought, ignore my previous comment. I don’t think I can come up with a better design anyway, so all of this is just musing. Letting user-level programs run privileged code is impossible, building a kernel-level equivalent of winapi is too much unneccessary work.

  17. Nick Lamb says:

    asd, not impossible, not even hard, but probably ill-advised in most cases.

    When a userspace program tries to execute privileged instructions (e.g. a hardware register write) the CPU will trap that, and control passes to the OS. The OS can determine what caused the trap and choose to simply carry out the privileged instruction itself.

  18. Ben Voigt [C++ MVP] says:

    “And this differs from other modern operating systems how exactly? -Raymond”

    I guess Windows CE is not a modern OS?  Or for a multi-user example which supports security, QNX?

    A number of people here are asking the very reasonable question of why, if Administrator permission is sufficient to write some machine code to a file, install it in the driver database, and execute it, can’t Administrators run a program that takes those actions.

    Clearly driver > application running in a non-privileged user account.  However, I can think of only one reason to make driver > application running in an elevated admin account: DRM.  And hence there are a great many drivers (such as giveio) that perform rather generic privileged operations on behalf of apps running as admin.

    On the other hand, driver-level enforcement of the check for admin privilege on the app from which the request came is non-trivial.  By not providing a standard, tested and secure mechanism for this, Microsoft has encouraged an ecosystem of poorly tested, likely vulnerable workarounds.

    [The issue isn’t admin/non-admin permission. It’s an issue of processor mode. Applications (even applications with administrator privilege) run in user mode; drivers run in kernel mode. -Raymond]
  19. MadQ says:

    @Joseph Koss: Instead of spending all that money, he could just create his own certification authority, declare it trustworthy on his machine, and create the appropriate certificates himself. That’s what I did. I wasn’t about to spend a crapton of money just to able to go spelunking in driver land. On the other hand, I’d rather read an IBM manual than write a driver. No, wait! I didn’t mean it! Let’s just say writing a driver is a major pain in the behind. IMHO.

  20. Joseph Koss says:

    @David Walker: This has nothing to do with "verifying drivers."

    Driver signing is only for verifying who the publisher was. There is no "hard work" involved in this.

    There is nothing rude about pointing this out as it goes directly to Raymond’s article. Things aren’t as simple as just writing a driver for win64. You need to pay for a certificate as well.

    @Ken Hagan:

    You can’t self-sign a driver for 64-bit windows. Really. You can’t. You can run in test mode which allows unsigned drivers, but you certainly can’t ask the end users to run in test mode full time.

    This entire issue has caused quite a stir in the past, as one inventive company decided to sign a driver who’s only purpose was to allow the loading of other unsigned drivers. Microsoft moved quickly and successfully to revoke their certificate.

    In short, you cannot just write a driver for win64. Thats not enough. You need to pay money to one of the short list of authorized certificate authorities as well.

  21. JS says:

    No, you can’t self-sign a kernel driver and have it run on an x64 OS.  Not without enabling test-signing mode on the machine, and you can’t ask your customers to press F8 and select this option on every boot.  

    Also, there is no "verification" required.  Just signing with a "trusted" certificate authority.  The "payola" comment is, unfortunately, accurate.

  22. someone else says:

    I like the NPP metaphor. So the equivalent of bad drivers, idiot administrators and flaky hardware would be Chernobyl?

  23. ChrisR says:

    @Ben Voigt [C++ MVP]

    You can’t just allow any program running as administrator to execute arbitrary instructions.  Then we are back to allowing user mode programs crash the machine at will, probably mostly accidentally.  This was a design goal of NT afaik.  A user mode program should not be able to crash the machine.

  24. Leo Davidson says:

    "No, you can’t self-sign a kernel driver and have it run on an x64 OS.  Not without enabling test-signing mode on the machine"

    Can’t you do it if you also create and install your own root CA? Or is there some kind of restriction on which root CAs can be trusted for drivers which cannot be overridden?

    I know of at least two tools which install their own root CAs when you install them. Made me wish such things were flagged to the user as I don’t really want root CAs on my machine unless I really trust the owner of them.

  25. frymaster says:

    "You need to pay money to one of the short list of authorized certificate authorities as well"

    true.  but, quite frankly, anyone writing code that people pay for that gets executed on other people’s systems should have one anyway, in the same way that anyone who has a website handling confidential information shouldn’t use a self-signed ssl cert.

    in the case of the original issue, that doesn’t help, presumably.  But if he’s just after something quick’n’dirty he can put testing mode on

    @Leo:  The way it works is, you sign your code as proof that it’s yours, then send your code + your driver verifier results to MS, who then counter-sign your code.  So it’s the existence of MS’s signature that matters for drivers, not yours.  And, of course, they only recognise certain issuers for your code signing certificate – a pain, but understandable.

  26. Ben Voigt [C++ MVP] says:

    @ChrisR:

    Any program running as administrator can crash the machine, trivially (you can load any signed driver, connect to any device instance and run any ioctl, overwrite critical OS files, stop any service, take ownership and change permissions on any kernel object, etc).

    You have a point about "accidental" damage, but this is just a design requirement not an insurmountable obstacle, as exemplified by QNX where you have to enable the dangerous privileges on a per-process basis.

    Really though, Microsoft should allow the root driver certificate to be replaced (not just added to, a list would be a good thing but not if you can’t also untrust existing drivers).  The incredibly poor quality of many signed drivers should be more than adequate justification for this.

    Among other things, this would create a space for competitors to WHQL that might actually be serious about quality.  Linux distros have stable and bleeding edge repositories, why not Windows?  Ordinary users could keep on trusting WHQL, while server admins might choose to demand the "Certified Mission Critical" by Company XYZ signature on drivers they load (where XYZ is any of the big names such as Dell, Sun, Novell, etc; ISO NNNN software test groups; or generally whoever is effective).

  27. Dan says:

    AFAIK driver signing (by Microsoft, at least) requires the driver to go through WHQL testing, which I believe David was referring to.  Microsoft really wants signed drivers to be stable because it’s always Windows that gets blamed when the computer crashes regardless of who wrote the driver that crashed it.

    However in Joseph’s favor, on the other hand… really, it’s three instructions.  That can’t be any more than one code path.  Not a lot of testing is going to be needed.

    If you’re writing this three-instruction driver for a commercial application the driver requirements would definitely be annoying.  However if it is for internal use only you could easily create a root CA for the company and install it on all company machines, then just sign drivers yourself.  Problem solved.

  28. Ken Hagan says:

    You can self-sign a driver, so there’s no financial barrier as long as your users trust you. And speaking of trust, a truly terrifying number of users will probably run anything you email them. :(

    In a corporate environment, life *is* harder. That self-signed driver is probably blocked by policy and it is a security professional who you’d have to convince to run your installer. Then there *is* a cash barrier, and for products with very low earning potential it is probably a very real barrier.

    On the other hand, you can get many of the same privileges by writing a service and running it as SYSTEM.

  29. Ben Voigt [C++ MVP] says:

    @Raymond:

    Processor mode is real, but it’s not binary — “kernel mode” and “user mode” are made up by DRM-loving OS vendors.  Windows writes a bunch of processor registers before transitioning to code not designated as “kernel mode” setting up a bunch of restrictions.  It could (and some other OSes do) permit subsets of these restrictions.  It’s a matter of making a few more things per-process variables during context switch instead of constants.

    And yes, doing it well would be expensive.  It’s a matter of whether you want every program wanting to read from SMBus to require a custom driver, forcing code into ring 0 where there are NO restrictions or protections and bugs are practically guaranteed to cause a system crash, or give programmers an environment where they can accomplish what they need to while still providing e.g. memory virtualization.

    [Are you saying that Ken Thompson and Linus Torvalds are DRM-loving OS-authors? -Raymond]
  30. Pax says:

    Re the nuke reactor: "But that’s so much work. I just need to go in and remove some of the control rods."

    Fantastic idea. Then run like hell…

  31. Shane says:

    Ok a driver which executes arbitrary instructions from anyone who asks is a bad idea.

    But what about a driver that uses ACL or some other whitelist device to execute instructions from trusted sources?

    An admin can already write and install any driver they like, so why not allow admins to run arbitrary privileged code via a ‘generic’ driver, seeing as they can do this anyway by writing and installed their own driver?

    This wouldn’t work in versions of Windows that require signed drivers, but it should be allowed in cases where Windows can allow non-signed drivers. The reason being: it’s already possible, it just takes more effort.

    This sort of stuff is already enabled with things like soft-ice and other kernel level debuggers.

  32. woongbin says:

    @Thursday, September 24, 2009 10:29 PM by Ben Voigt [C++ MVP]

    Processor mode is real, but it’s not binary — "kernel mode" and "user mode" are made up by DRM-loving OS vendors.  

    Hahaha, I never expected to see this kind of comment here. Thanks for the laugh of the day.

  33. Christian says:

    I think some big video drivers are essentially "execute anything that gets passed to them in kernel mode" drivers :-)

    They have so many security holes that they would be ideal loaders to get code into 64 bit OS without signing.

    I’m also very annoyed by the signing-requirement for 64 bit os, but at least OpenVPN (TUN/TAP) and WinPCAP are available.

    It’s a good thing if users are still able to create drivers, e.g. to patch running programms and remove certain restrictions (uxtheme comes to mind. One company switched from patching on disc to writing a small drivers that patches it in memory), e.g. DRM or exporting LSASS secrets for recovery of saved passwords etc.

  34. ender says:

    Can’t you do it if you also create and install your own root CA? Or is there some kind of restriction on which root CAs can be trusted for drivers which cannot be overridden?

    You can’t. You have to buy a certificate from one of the authorities listed on http://www.microsoft.com/whdc/winlogo/drvsign/crosscert.mspx and sign your driver with your certificate and the cross-signing certificate from that page. Basically, you have to pay $220 (that was the cheapest offer I saw when I last looked) to get your own code running on your own machine without having to boot your own machine in a special mode (and as you see, there is no driver verification involved – after you pay, you can load anything).

    I imagine the cross-signing requirement is there because the code that checks the signature is run long before the crypto API is initialized to allow you to check the root authorities, and the allowed certificates are probably hard-coded.

  35. Mark says:

    ender: have you tried running an iPhone app on your own device?  Sadly, this is seen as the solution to bad programming.

  36. Joseph Koss says:

    ender:

    The slap in the face is the huge markup over costs. 75% of VeriSign’s revenue (almost a billion/year) is pure profit, according to their financial statements.

    Such large profit margins don’t happen in a free market. Its artificial scarcity, so the term payola is succinctly appropriate.

    [Clearly this entry has uncovered a new law: “Any article which mentions drivers will devolve into an argument over code signing and DRM.” Time to scrub future articles from the queue. -Raymond]
  37. Terry Davis says:

    LoseThos http://www.losethos.com is an alternative operating system for those who do want full access to their own machines.  Live and let live.  If some like the power of doing anything they want, come to LoseThos.  The rest of you stay away and laugh at us, if you like, but don’t be a control freak.

  38. Joel Dillon says:

    I can sort of see his argument, in the ‘why do I have to do this much work to do this’ sense. In Linux, for example, you can use the I/O port instructions from userspace by first calling ioperm() (which requires specific privileges, which on a normal system means being root). This used to be essential for X11 to work without having any kernel drivers, given that VGA and extended VGA mode setting was only accessible with those instructions.

    It’s not unreasonable to ask why Windows won’t allow this where architecturally possible, with safeguards such as the program telling the operating system explicitly ‘Yes I really want to do this’. Anyone with administrator privileges already has a bunch of ways they can totally hose the system.

  39. someone else says:

    You forgot Sturgeon’s law: 90% of everything is crud.

    Separating user mode from kernel mode helps to prevent accidental damage. If you’re serious about executing privileged instruction, go ahead, write a driver. Come to think of it, what good reason would you have to execute privileged instruction from user mode?

    In unrelated news: Does test certificate mode interfere with DRM (whose inventors will surely forever burn in hell)?

    Oh, and no sane person quotes the bible to explain his OS design. Srsly.

  40. Kevin Eshbach says:

    Gotta love lazy developers.  When will they learn that taking shortcuts will always come back to haunt them later on.

  41. manyirons says:

    "The whole point of having a class of modules called drivers is to prevent somebody from doing exactly what you’re asking for. Only drivers can execute privileged instructions; that’s why they’re called privileged instructions."

    I thought the whole point of having drivers was to provide an abstraction from hardware, and all the benefits that result from that abstraction.  That drivers are the only ones that can execute privileged instructions is a distortion of that concept, really just an implementation detail.

  42. Falcon says:

    I love this bit from the LoseThos FAQ:


    To access the task or cpu structure, I have to use a trick.  I place the record’s address at offset zero in the record and get the address like this:

    XOR        RAX,RAX

    MOV       RAX,FS:[RAX]

    This is necessary because [displacement] addressing modes are RIP relative.  (Worthless for these segment registers).  This doesn’t appear to work:  

    XOR        RAX,RAX

    LEA         RAX,FS:[RAX]


    In these code sequences, it’s obvious that LEA will store 0 into RAX, while MOV will load the value from memory at FS:[0]. LEA doesn’t care about segments – this is my understanding from Intel docs.

  43. someone else says:

    Privileged instructions are a hardware detail.

  44. Aaron G says:

    I really love that people are bitching about how you can’t run a self-signed driver without enabling test signing mode, and that it doesn’t make sense to ask all your users to do this on a "production" system.

    Um… duh?

    I think it’s assumed, when people are complaining that writing a driver is "too much work", that they are doing this only on their OWN machine as a development or testing aid.  If you actually plan to deploy this to production machines – and I don’t care if it’s 3 machines or 3 million – then damn right you should have to get it signed and verified.  The dark age of VxDs is long over, who do you think you are?

    I don’t care what your app does, I don’t want it executing kernel-mode instructions on MY machine unless I grant explicit permission (in which case you need to earn my trust, and you can start by not being a lazy cheapskate), or if Microsoft has publicly come out and said "we’ve tested this and promise that it works with your OS and won’t crash everything."

    And if you want to offer your wonderful kernel-mode product free of charge and can’t afford a certificate, that’s your problem.  I can’t practice medicine without a license, not even for free, and it’s not an excuse that I didn’t have the money/time for med school.

    It’s shocking how many people who really should know better just can’t seem to wrap their minds around the concept of trust.

  45. someone else says:

    “And if you want to offer your wonderful kernel-mode product free of charge and can’t afford a certificate, that’s your problem.  I can’t practice medicine without a license, not even for free, and it’s not an excuse that I didn’t have the money/time for med school.”

    Your analogy is just a teensy bit flawed. If I run an unsigned driver on my machine, there is zero chance anyone will be killed, disabled or even develop a slight cough.

  46. Yuhong Bao says:

    [Clearly this entry has uncovered a new law: “Any article which mentions drivers will devolve into an argument over code signing and DRM.” Time to scrub future articles from the queue. -Raymond]

    I would not go that far.

    [Coming from the person who is probably best-known for sidetracking discussions… -Raymond]
  47. someone else says:

    Um, Raymond, are you doing this blog for the discussions or to entertain and educate?

    [I enjoy the discussions when they amplify the topic, as opposed to random flamefesting. -Raymond]
  48. Joseph Koss says:

    @Raymond:

    Discussions about driver development must have a code signing tangent…

    This goes directly to the tone of your correspondence in the article. You tell him/her that all he/she has to do is write a driver to execute privileged instructions, but for 64-bit drivers he also has to spend hundreds of dollars for a 1-year ticket to kernel space.

    I realize that this correspondence probably took place before win64, so I am not faulting you for that. Just the same, its no longer as simple as writing a driver, and I will fault you for not wanting that pointed out here. There is (hopefully) no reason to hide the real situation from developers.

    [I don’t recall ever saying that “all” you need to do is write a driver, as if writing a driver was trivial. Because I know it isn’t. And the existence of these obstacles doesn’t dilute the original point, which is that user-mode code cannot execute privileged instructions. That’s why it’s called user-mode code. -Raymond]
  49. someone else says:

    “true.  but, quite frankly, anyone writing code that people pay for that gets executed on other people’s systems should have one anyway”

    But what about code that people *don’t* have to pay for? Ramdisk-drivers come to mind (and let’s not get into the ramdisks are useless argument here)

  50. ryandenki says:

    Nobody has asked what the three privileged instructions are, or why they would be necessary in an otherwise fully user-mode application?

    Something smells wrong with the requirements, architecture, or implementation for this to be required.

    The only case I can think of personally is for accessing hardware registers, in which case a driver is the only way it should be approached in the first place. Any more details available on the scenario?

  51. Ben Voigt [C++ MVP] says:

    @Joel Dillon:

    That’s exactly what I was talking about in QNX.  I hadn’t bothered to learn that ioperm is available in linux as well.

    @Raymond:

    Since ioperm clearly debunks your claim that modern OSes don’t grant use of privileged instructions (even if disabled by default) to non-driver processes running as admin, I’d like to know what you think about not having an equivalent to ioperm in the Win32 API.  I see at least five possibilities here:

    1) You really consider ioperm() a security hole, as your post says.

    2) Implementing ioperm would be awfully doggone expensive, and the benefits aren’t sufficient to justify it.

    3) Windows actually has an ioperm equivalent that hasn’t been mentioned in this discussion. (I added this option to my list after finding out cygwin has an ioperm package)

    4) Implementing ioperm would poke holes in DRM.

    5) In your opinion ioperm would actually be a good thing to have, someone else decided to exclude it and didn’t share their reasons with you.

    [I suspect the linux folks added ioperm while holding their noses. It was a necessary evil, as I understand it, to get video support. It is, however, a special case of the general principle. I stand by the general principle. (Why do people keep bringing up DRM as if I was the guy who invented it?) -Raymond]
  52. David Walker says:

    The whole article is rather like shouting at someone on the other side of the airtight hatch, and asking them to push some buttons…  :-)

  53. Yuhong Bao says:

    [Coming from the person who is probably best-known for sidetracking discussions… -Raymond]

    Well, yea, but I thought OS/2 IOPL segments would be more interesting than driver signing and DRM. But surprisingly, it got no response.

  54. Ben Voigt [C++ MVP] says:

    @Raymond:

    Well, I would think that enabling e.g. CoreTemp to be a purely user-mode application (albeit with some dangerous privileges enabled) seems more desirable than forcing them to operate in a 100% unrestricted all-safeties-removed kernel-mode environment.

    I mentioned DRM because it although smart people differ on the cost-benefit analysis, it is a solid (see I’m avoiding the words valid and legitimate to try to avoid the flames) reason for restricting privileged instructions to drivers as opposed to processes having Administrator rights.

    I really did want to know if you knew other reasons for the separation.

    Definitely system stability demands that anything which can be implemented without the use of privileged instructions, should be.  But I would have thought that a corollary would be that anything that a partially protected environment (i.e. ioperm-enabled process) would yield better system stability than no-holds-barred kernel-mode-driver solutions.

    (With the advent of UMDF, driver != kernel module, which I think is what manyirons is getting at — use of privileged instructions and hardware abstraction really aren’t synonymous.)

    Plus, the proliferation of kernel modules a/k/a drivers created by excluding ioperm is, in my opinion, creating additional security risks.  Ok, now that developer X has gone to the trouble of writing that driver to read CPU thermal sensors, he has to put an ACL on your user-mode interface.  Will X allow all users read access or only administrators?  All users probably seems reasonable to a lot of developers, who don’t consider the potential information leakage in a server environment (of course cache coupling probably leaks similar information with a lot greater accuracy).  Letting arbitrary web applications connect to the CPU temp driver is almost certainly wrong, but if ioperm was available to administrators, there wouldn’t even be a kernel-user communication boundary where an improper ACL could be in effect.

  55. someone else says:

    *facepalm*

    If anyone ever says that Windows is the most insecure, unstable, stupid OS evar, I can now point them to LostThos.

    That guy is serious. And whatever he might say in the FAQ, he *does* need help. Professional help.

  56. aaron says:

    I see a lot of complaints, but no one nailing down on this point:

    You suppose the developer’s app is already in the position to install a driver some how.  This scenario *already* has them owning the machine.  Should the prompts be the same, there is no escalation; they already *have* said privileges, and are looking how to reduce their dev costs.

    Obviously no story is complete.  I imagine the prequel includes someone first attempting to dissuade this customer from executing privileged instructions at all.

  57. Anonymous Coward says:

    (“The incredibly poor quality of many signed drivers should be more than adequate justification for this.” Agreed. I know Microsoft is supposed to do a lot of testing, but from my personal experience I get the feeling that Microsoft is willing to sign everything if you pay enough.)

    One of the more problematic aspects of driver signing is that it conflicts with the fact that my computer is mine and I should be able to have full control of what code I run on it. (That said, the Cygwin Ioperm package is an abomination because it makes port manipulation available to all applications on the system, which is a huge security hole.) Still, if I were to trust a certain driver, for example because I wrote it myself or reviewed the code, I should be able to load it (if I have admin permissions) on my computer. The 64 bit driver signing spectacle stops you from doing this, giving Microsoft the ultimate control over what drivers can run on your computer. I know why this is done – Microsoft probably was afraid of OEMs shipping faulty drivers with Win64 – but given that this could have been handled differently (better) without imposing such a draconian restriction on the end user, Raymond really shouldn’t be surprised that suspicions in the direction of DRM pop up, especially since there are a lot of operating systems where the end user can install whatever drivers he trusts.

    [And all this time I thought the code signing requirement was to make it harder for malware authors to drop a rootkit. Shows how much I know. -Raymond]
  58. Ken Hagan says:

    To all those who say a signed driver is needed on Win64, I have a thought experiment for you.

    Are you really utterly certain that there is no way any program in user space with admin rights can execute code at kernel level on Win64 without a certificate? Think about viruses and rootkits. Still sure?

    Administrators can do anything. No machine or domain-wide policy can stop them. The only barrier is the complexity of the code, and once that code has been wrapped in a handy library, the additional cost for anyone who can acquire a copy of that code is zero. The second attacker doesn’t even need to be an admin. Once your machine is owned, its dead.

    OK, this may not *sound* ethical, but you wouldn’t be installing a virus on your customer’s machine. You’d be installing a "helper library" to let smaller ISVs avoid the wicked "driver tax". And it would be simple to let each of your customers (small ISVs) "mutate" the code slightly, so that no single variation was ever sufficiently widespread to come to the attention of the AV vendors.

    Given the right PR, the whole exercise becomes a shining example of good citizenship, except in the eyes of a few grumpy old fogeys who can see the thick end of the wedge in the shadows beyond.

  59. Teo says:

    It seems that many people here do not distinguish between a “digital certificate” and “WHQL certificate.” First, you do not need a whql certificate to load a driver on users’ machines, the normal one from VerisSign and co is enough. The difference is only evident for WDM drivers during their installation – the WHQL-signed drivers are silently accepted, while the ones with normal digital signature trigger a question to the user “Do you trust the drivers from <<<name from the certificate>>>”. For non-WDM drivers there is no such UI.

    Also, let’s not be in panic mode – users since around 2003 *expect* that program files are digitally signed, so if you are a serious developer (and frankly, if you were not then you wouldn’t be reading this blog), so there should be no problem with obtaining the digital certificate for the driver – you already have one.

    But, developing a driver has other costs, which I am not sure even Raymond thinks of.

    Lets see. The famous “custommer o’ Microsoft” wants to write this:

    __asm {

     instruction 1

     instruction 2

     instruction 3

    }

    which is 5 lines of code. Now he is forced to write a driver. (I do not argue if this is needed. I treat it as a nature force – if you want to execute privileged instructions on Windows, you need a driver, just accept that).

    So this poor soul has some decisions to make and some wotk to do.

    1. He needs to find out how to setup their machines to write and debug kernel-mode components (aka drivers, KMC for short)

    2. He must figure how to access Microsoft Connect, make account there, search its amazingly hellish user interface and after two hours of cursing change to Internet Explorer, and redo everything in there, because the site *insist* on installing own download manager as an ActiveX control.

    3. Now he has a good 1 GB iso file, he unpacks it and has to deliver it all developers’ machines. He has to go through all his internal procedures to check nothing breaks, then push the package though his Active Directory. Obviosly this cannot be done without some trickery, because it consists of 100+ small MSI packages and one Setup.exe that *interactively* installs it (i.e. it has unskippable UI). Cool, you have to manually install it on every developer machine in the office. Of course, that means that the WDK cannot be certified as “Windows Logo” software, which is totally ironic.

    4. KMC are written in C. If you are shop that writes on .Net/Java/etc, then you either hire new people that groks KMC or assign some of your people to stop doing their work, and start learning C, then leraning writing KMC. Both ways are *expensive*

    4.1. Even if you are C++ shop, you have problems. Good C++ programmers are bad C programmers, because the syntax of the languages only looks similar, and the semantics are completely different.

    5. If you go with “train your own people” then it’s even more complicated.

    5.1. WDK has its own set of header files and libs, which do NOT agree with the ones comming with the Platform SDK (resp. the Visual Studio ones). Basic stuff like NTSTATUS definition disagrees.

    5.2. WDK insists on its own build environment, (although you can coerce Visual Studio to build drivers, after all the WDK compiler is the same as the one in Visual Studio). But lets assume that the guy in question follows the procedure. Now he has TWO build environments – one for the existing project, the other for the driver.

    5.3. That means that you have to re-done your build servers as well, changing the basing assumpions of the build procedure he has made when he created it

    6. You have to change the way the product is tested. For user-mode components, you fire it through the Visual Studio debugger and debug it. With KMC, you need to learn how to use WinDbg. It *is* the best debugger available on Windows, but its interface is complicated and really needs a month just to start using it effectively. Did I mentioned it that it does not work properly under Vista/7 (it’s spelled in its readme file)

    6.1. If you are .Net shop, you are doomed. .Net debuuger in Visual Studio complains that kernel mode debugger runs and refuses to work. You can debug *either* the KMC *or* the rest of your product, but not the two parts at the same time.

    6.2. Cool that you can debug .Net apps with WinDbg. But WinDbg insists on developers having the bit-by-bit exact copy of the .Net frameworks on both the debugging machines and on the developers machines. If your developers workstations are 32-bit, it’s time to buy new, 64-bit ones because otherwise you cannot debug 64-but builds of your project.

    7. If your project wants to get “Windows Logo” certification, then you first need to apply for the WHQL signature for the driver. Additional costs for setting in-house testing lab for just the WHQL test, then for the actual testing.

    8. When a new version of your product arrives, you either:

    8.1. re-submit the driver for WHQL test, because it’s a new version

    8.2. build some frankenbuild consisting of all new bits of the user-mode part and the old driver. So that version 8.0 of your product consists of most parts being version 8.0, but the driver staying at 6.0. Of course that means that your build server has to be re-configured to *skip* building the driver.

    Well Raymond, do you now *understand* why your custommer was so unwilling to accept the news that he had to develop a driver?

    [And this is easy compared to getting security clearance to the control room of a nuclear reactor. -Raymond]
  60. someone else says:

    “2. He must figure how to access Microsoft Connect, make account there, search its amazingly hellish user interface and after two hours of cursing change to Internet Explorer, and redo everything in there, because the site *insist* on installing own download manager as an ActiveX control.”

    If you’re referring to the WDK download, that one is available through simple HTTP. No Akamai download manager there.

  61. Mike Caron says:

    @Teo: Um.

    If I’m writing in Jave/.Net, how do I expect to write /any/ raw instructions at all? I’m not aware of inline assembly blocks in Java, C# OR Visual Basic…

    Further, once I’m committed to writing a driver, must I really install the DDK on every computer in my office? Really? Even for those who think "low-level" means "basic if-constructs"?

    Further, do I really want to keep my driver as an integrated part of my product? Or (more likely) do I want to treat it as a separate component which happens to be bundled with my product? I mean, yeah, versioning must be a *bitch* at your shop…

  62. Teo says:

    My product is a driver, so, yes, versioning is a bitch. And for some weird reason the http link on Connect didn’t trigger the download, so I had to use the MS download manager.

    And in .Net you can use the "it just works" c++ where the compiler takes care for the managed/unmanaged transitions, but you still must debug the result, so the debugging problems stay. But in the unmanaged part you can use whatever you want, including inline assembly (well for 32-bit, the 64-bit compiler does not have it). Remember, there’s more in .Net than C# and VB.Net :-D

    Anyway, my point was that the fact that you have to digitally sign your driver has zero cost – you already have the certificate. The cost come from the disruption of the workflow of your firm and they are substantially higher than the mere 400$ yearly for the certificate. (Nearly) every human being facing this would react in the same way this guy did – it would try to cheat the system. I know I would.

  63. someone else says:

    Ok, so this is how I see it:

    While you are developing in-house, set up your own CA and use that to sign your certificates. After that, you have to options:

    1. Release it for free (that also means without hardware attached). Make it open source and signing is the user’s problem.
    2. You want money for it (or the corresponding hardware). Then get a freakin’ certificate already!

    And what’s so hard about downloading the WDK from http://www.microsoft.com/downloads/details.aspx?FamilyID=2105564e-1a9a-4bf4-8d74-ec5b52da3d00&displaylang=en ?

  64. Medinoc says:

    I can now confirm, after clinical tests, that whoever wrote Inpout32.dll “needs to be taken outside and beaten”:

    The DLL doesn’t only work for administrators. After an administrator has executed ANY program that uses this DLL, ANY user can in ANY other program of his choice. So, this DLL allows any limited user to perform privileged inp and out at will, as soon as an administrator lets it slip ONCE.

    [They don’t quite meet the beating criteria: At least they don’t execute arbitrary instructions. -Raymond]
  65. Ben Voigt [C++ MVP] says:

    “And all this time I thought the code signing requirement was to make it harder for malware authors to drop a rootkit. Shows how much I know.” -Raymond

    If that were really the intent, then the drivers would need to be cosigned by the computer administrator, not MS (or MS proxies such as Verisign).

    (Yes, there’d have to be a boot option to use the MS certificate instead, and consumer installs would use the MS certificate by default — IT departments could override the certificate with the usual unattended setup answer mechanisms.  I’m not saying that requiring code-signing isn’t an improvement, I’m saying that the current system appears to be designed to maximize profit rather than effectiveness.)

    Right now, to drop a rootkit Mr. Malware just has to buy a cert from Versign (remember this fiasco?  http://news.cnet.com/2100-1001-254628.html).  With admin-selected trusted root they’d have to subvert my certificate, and so on.

    Also, you can’t really have a lesser certificate trusted only in the test environment so that beta versions won’t be accidentally loaded in production.  (Selecting test-sign mode on every boot in the test environment is more than a little bit onerous as it prevents automated regression testing, etc)

    “Are you saying that Ken Thompson and Linus Torvalds are DRM-loving OS-authors?” -Raymond

    Linux gives trusted (by superuser, not OS vendor) processes considerable access to hardware (via for example ioperm, /dev/kmem).  By your definition (privileged instructions can only be executed by drivers) these aren’t user-mode applications, and they aren’t kernel modules, so clearly Linux isn’t included in the list of OSes with the kernel mode/user mode dichotomy.

    I think the same argument applies to BSD.

    Totally off-topic: Some people, myself not included, might actually say that Torvalds et al are DRM-loving because they won’t buy off on the GPLv3 license’s anti-DRM language.

    [“Considerable access to hardware” != “executing privileged instructions”. So far I have yet to find somebody that lets user-mode code perform a mov into cr0. Because the processor doesn’t allow it. The closest you can do is have an interface where user-mode code can ask kernel code to do the mov on its behalf. -Raymond],
  66. Ben Voigt [C++ MVP] says:

    “‘Considerable access to hardware’ != ‘executing privileged instructions’. So far I have yet to find somebody that lets user-mode code perform a mov into cr0. Because the processor doesn’t allow it. The closest you can do is have an interface where user-mode code can ask kernel code to do the mov on its behalf.” -Raymond

    Certainly there are some instructions which really require ring 0.  Then there are a bunch more which can be executed in ring > 0 as ring 0 permits.

    But the person with the question would have been perfectly happy with an interface to execute the instructions, which you then mocked via a comparison to asking for control of a nuclear power plant without a security clearance.  Yet the kernel checks security on user-mode processes all the time, and that check could involve verification of code-signing just like it does for kernel modules (for efficiency do the check once, set a bit in the process token).  There’s no real reason that there couldn’t be a privilege that allowed running a short sequence of instructions just like there is a privilege for reading memory of other processes, and a privilege for becoming a debugger of services.

    [Running arbitrary code is very different from reading other process’s memory. One is an information disclosure issue. The other will cause you to lose control of the entire computer. One is controlled. The other is uncontrolled. I wonder whether linux lets you say “Here are some arbitrary instructions, go execute them in kernel mode for me.” -Raymond]
  67. Ben Voigt [C++ MVP] says:

    "Running arbitrary code is very different from reading other process’s memory. One is an information disclosure issue. The other will cause you to lose control of the entire computer. One is controlled. The other is uncontrolled. I wonder whether linux lets you say ‘Here are some arbitrary instructions, go execute them in kernel mode for me.’" -Raymond

    Ok, reading other process’s memory isn’t so powerful.  Writing other process’s memory is, and Windows lets you do this.  Writing kernel memory is pretty much the ultimate level of control, I’d consider that as powerful (although less easy-to-use and more fragile) as executing an arbitrary set of instructions.  And with /dev/kmem, yes Linux (and AIX, BSD, various other Unix flavors) does let you write kernel memory, from user-mode, if your process has appropriate permissions (in Linux that means "group membership" and "capabilities").  Given how dangerous (meaning fragile and great potential for crashes if done wrong, not insecure) installing kernel hooks is, I’d be surprised if there isn’t a way to say "Here are some arbitrary instructions, go execute them in kernel mode for me."

  68. Dave says:

    I know of at least two tools which install their own root CAs when you install them.

    Really?  So they end up in the root store without intervening UI?  Can you name the products?

    (I’m not a MS lawyer :-), just someone who’s curious about an app that can do this).

  69. Dave says:

    I can now confirm, after clinical tests, that whoever wrote Inpout32.dll "needs to be taken outside and beaten":

    Has anyone looked at the more recent giveio (shipped with various hardware-monitoring programs) and any of the plethora of homebrew ioperm()-equivalent drivers floating around out there?

Comments are closed.