{"id":110201,"date":"2024-09-02T07:00:00","date_gmt":"2024-09-02T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=110201"},"modified":"2024-08-31T07:57:41","modified_gmt":"2024-08-31T14:57:41","slug":"20240902-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240902-00\/?p=110201\/","title":{"rendered":"The <CODE>Co&shy;Initialize&shy;Security<\/CODE> function demands an absolute security descriptor"},"content":{"rendered":"<p>One unfortunate requirement of the <code>Co\u00adInitialize\u00adSecurity<\/code> 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 <code>Convert\u00adString\u00adSecurity\u00adDescriptor\u00adTo\u00adSecurity\u00adDescriptor<\/code> 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.<\/p>\n<p>Unfortunately, if you pass a self-relative security descriptor to <code>Co\u00adInitialize\u00adSecurity<\/code> it fails with <code>HRESULT_<wbr \/>FROM_<wbr \/>WIN32(<wbr \/>ERROR_<wbr \/>BAD_<wbr \/>DESCRIPTOR_<wbr \/>FORMAT)<\/code>. The requirement that the security descriptor be in absolute format is documented, but it&#8217;s still annoying.<\/p>\n<p>Internally, the reason is that the <code>Co\u00adInitialize\u00adSecurity<\/code> converts the incoming security descriptor to relative format by calling <code>Make\u00adSelf\u00adRelative\u00adSD<\/code>, without first checking whether the conversion is even necessary. The <code>Make\u00adSelf\u00adRelative\u00adSD<\/code> function fails with <code><wbr \/>ERROR_<wbr \/>BAD_<wbr \/>DESCRIPTOR_<wbr \/>FORMAT<\/code> if the security descriptor is not absolute, and that error is propagated from <code>Co\u00adInitialize\u00adSecurity<\/code>.<\/p>\n<p>Now, <code>Co\u00adInitialize\u00adSecurity<\/code> 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&#8217;re used to thinking of them.<\/p>\n<p>Most of the time, the compatibility issue is &#8220;Will existing old code continue to work on a new system?&#8221; But in this case, the compatibility issues goes the other way: &#8220;Will new code continue to work on an old system?&#8221;<\/p>\n<p>If <code>Co\u00adInitialize\u00adSecurity<\/code> 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 <code>Co\u00adInitialize\u00adSecurity<\/code> does exist on the old system.<\/p>\n<p>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.<\/p>\n<p>Now, maybe you say that somebody who does this deserves what they get, and maybe you&#8217;re right, but Windows traditionally has been wary of creating too many of these &#8220;pits of failure&#8221; where somebody proceeding with the best of intentions can stumble into a bad situation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Even though you usually have a self-relative one in hand.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-110201","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Even though you usually have a self-relative one in hand.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=110201"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/110201\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=110201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=110201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=110201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}