September 2nd, 2024

The Co­Initialize­Security function demands an absolute security descriptor

One unfortunate requirement of the Co­Initialize­Security function is that it requires a security descriptor in absolute format. I call this unfortunate because the most common format for security descriptors is self-relative format. A common way to specify a security descriptor is to use the security descriptor definition language (SDDL), and the Convert­String­Security­Descriptor­To­Security­Descriptor function that converts these strings to security descriptors produces self-relative security descriptors. Another common way to specify a security descriptor is as a block of bytes, perhaps stored in the registry, or stored in a file, or just hard-coded into a binary blob, and these are naturally in self-relative format, since absolute format would be dependent on the location of the block of bytes in memory.

Unfortunately, if you pass a self-relative security descriptor to Co­Initialize­Security it fails with HRESULT_FROM_WIN32(ERROR_BAD_DESCRIPTOR_FORMAT). The requirement that the security descriptor be in absolute format is documented, but it’s still annoying.

Internally, the reason is that the Co­Initialize­Security converts the incoming security descriptor to relative format by calling Make­Self­Relative­SD, without first checking whether the conversion is even necessary. The Make­Self­Relative­SD function fails with ERROR_BAD_DESCRIPTOR_FORMAT if the security descriptor is not absolute, and that error is propagated from Co­Initialize­Security.

Now, Co­Initialize­Security could be updated to support self-relative security descriptor. It would just be a check whether the security descriptor is already self-relative, and using the existing one if so. However, this would create a compatibility problem, but not in the way you’re used to thinking of them.

Most of the time, the compatibility issue is “Will existing old code continue to work on a new system?” But in this case, the compatibility issues goes the other way: “Will new code continue to work on an old system?”

If Co­Initialize­Security started allowing self-relative security descriptors, then somebody writing code today could take advantage of this new feature (perhaps unwittingly), and then encounter problems when their program is run on an older version of Windows. There is no obvious indication as to what went wrong because the function Co­Initialize­Security does exist on the old system.

The scenario is that somebody wants to be compatible with (say) Windows 10 Version 1803, so they compile their program with the Windows 10 Version 1803 SDK, and it compiles just fine. It also runs fine on Windows 11, and since they used the Windows 10 version 1803 SDK, they erroneously conclude that the program also works on Windows 10 version 1803.

Now, maybe you say that somebody who does this deserves what they get, and maybe you’re right, but Windows traditionally has been wary of creating too many of these “pits of failure” where somebody proceeding with the best of intentions can stumble into a bad situation.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

10 comments

Leave a comment

Newest
Newest
Popular
Oldest
  • Theodore Dubois 1 week ago

    This one seems easy enough to fix by Apple’s technique of giving the function the old behavior when the program is linked against the old SDK.

  • alan robinson 1 week ago

    This is the kind of policy choice that shows the value (and required tradeoffs) of a stable API. If this were google they’d change in a heart beat, older phones would stop working sooner, and everybody would just nod and agree that the e-waste was totally worth the (minor) API improvement. And again, next year the cycle would repeat, except this time the API would be debatably improved. And next year, Lo! Again with the change, breaking old phones. But this time for a demonstrably worse API with fewer features, and harder to use too.

    So the Microsoft way may lead to some thorns and rough spots in the API that are 20+ years old. But the other way eventually leads to madness.

    In fact MS isn’t immune to this issue, lots of little changes have accrued to the win32 API that are of debatable advantage, but astronomically fewer than in the android world. I get the sense that Apple is somewhere in-between?

  • James 1 week ago

    Another consideration, especially with a security function is that someone may have come to rely on the returned error, perhaps even to enforce a security property! Introducing security vulnerabilities into someone else’s code from a distance.

    I struggle to imagine how how might rely on rejecting relative SIDs… but people are very creative.

  • Dmitry 2 weeks ago · Edited

    As someone, who has recently read and reread the WinSock MSDN pages to holes in my monitor, I’m surprised. I remember like lots of stuff where I saw ”this thing works this way” and then ”but in WinXP until SPx it works differently”. Anyway, the one who uses latest SDK and, especially, tests on the latest OS version has lost the war of being compatible with older versions far before even starting.
    P.S. And if we talk about Win11, my students have quite a lot of trouble with it when writing low-level software projects. And they use Win10 all the time to work those troubles around. For sure, they don’t care about the ”Artificial Idiocy” features.

  • Henry Skoglund 2 weeks ago

    One solution: introduce another flavor Co­Initialize­SecurityEx() taking the same parameters, but it would support self-relative security descriptors,

    • IS4

      And so the program would simply fail to run on older systems, classic Windows style.

    • alan robinson 1 week ago

      And later on, Co­Initialize­SecurityExEx()….

      But yes, a preferable solution, probably.

      For this specific case, I’d lean towards a Co­Initialize­SecurityRelative()

      • Me Gusta 7 days ago

        @Shawn Van Ness
        Not an Ex3, but there is a MapViewOfFile3 function.

      • GL

        Internet Explorer has IHTMLDocument7 interface…

      • Shawn Van Ness 1 week ago · Edited

        The naming convention is “Ex2”. (not joking .. there are a few of these throughout the SDK .. eg. InternetGetCookieEx2)

        Not sure if any “Ex3” APIs exist. Some COM interfaces, perhaps — which have greater liberty to evolve, than a static Win32 API function.

Feedback