Avoiding problems with VC2005 SP1 Security update KB971090

KB971090 update mitigation

Problem

After installing KB971090 for Visual C++ 2005 SP1, the version of ATL/MFC/CRT referenced in the generated manifests is changed from 8.0.50727.762 to 8.0.50727.4053

The above change forces the application developer to rebuild all components to reference the 4053 version of the versions of ATL/MFC/CRT in the manifest, as well as making it necessary to ship a new vcredist_x86.exe and/or MSM files containing the new 4053 versions of ATL/MFC/CRT.

Solution

Instead of uninstalling the KB971090 update, we can force the build to use the 8.0.50727.762 version instead of the default which is 8.0.50727.4053. Microsoft provides a mechanism to specify the assembly version number to use in the manifests.

Steps to take to allow your applications to reference 8.0.50727.762 instead of 8.0.50727.4053

1) Create a file named targetsxs.h with the following content and put it in a common location

#ifndef __midl
#define _SXS_ASSEMBLY_VERSION "8.0.50727.762"
#define _CRT_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _MFC_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION
#define _ATL_ASSEMBLY_VERSION _SXS_ASSEMBLY_VERSION

#ifdef __cplusplus
extern "C" {
#endif
__declspec(selectany) int _forceCRTManifest;
__declspec(selectany) int _forceMFCManifest;
__declspec(selectany) int _forceAtlDllManifest;
__declspec(selectany) int _forceCRTManifestRTM;
__declspec(selectany) int _forceMFCManifestRTM;
__declspec(selectany) int _forceAtlDllManifestRTM;
#ifdef __cplusplus
}
#endif
#endif

2) The above file needs to be included in every project you wish to build.

Accomplish this in one of two ways. The first method involves the changing of source code. The second involves changing of project settings.

choose A or B which ever one is more appropriate for your situation:

A) #include "targetsxs.h" near the top of every one of your stdafx.h files
(using the path you saved the targetsxs.h)

B) Use the force include (/FI) compile option to make sure that the above file is included in every file built. To accomplish that, add the following command line to your compiler options

/FIc:\path\targetsxs.h

(where c:\path is the location of the targetsxs.h you created in step 1)

There are two methods to accomplish that: either directly in your project or through a compiler environment variable:

Method i)

Add the above to the command line section of the C/C++ project properties.

Method ii)

Create an environment variable named CL with the above-mentioned /FI statement

Method (ii) is more convenient to use when you have dozens of projects that you do not wish to make changes to, but may conflict with other work you do on your machine.

3) For every MFC DLL project in your solution add the following line to the bottom of the stdafx.cpp file

#include "..\src\mfc\dllmodul.cpp"

Step three is only necessary if you have any MFC DLL projects (this step is necessary due to a bug in the handling of the assembly versions in MFC DLLs – the bug is that a reference to the latest version of the DLLs will always be included regardless of what is set in step 1)

4) Do a rebuild all of all the projects in your solution

5) Inspect manifest files (by doing a find in files for *.intermediate.manifest) to ensure that 4053 no longer appears in any of the manifests.

6) Run your app on a machine that has no 4053 components installed to WinSxS to make sure runs properly.

IMPORTANT NOTE: if you have ATL controls that are affected by this security problem please ensure you have followed the directions to modify your controls to take advantage of the security updates. A simple recompile may not be enough. For more info please see the video at:

http://channel9.msdn.com/posts/Charles/Out-of-Band-Inside-the-ATL-Security-Update/

Q&A

Does referencing 762 instead of 4053 make your application less secure?

No. Microsoft provides WinSxS policy redirection, so any application referencing 762 will end up loading the 4053 versions (if they’re installed). The ATL security update redistributable has been released as an update on Windows Update, so the 4053 version of ATL will be in place, and will be used even though your app still references the 762 version of ATL.

*Important note: you should still ship the new version of the redistributable if at all possible, as users may have not updated using Windows Update.

What are the benefits to referencing 762 instead of 4053 in your SP1 applications?

1) If you have existing applications shipped and you need to rebuild any components shipped, then new MSM or vcredist_x86.exe containing 4053 versions do not need to be shipped. You can continue to ship existing components with 762 versions.

2) If you have existing third party static libraries that reference 762, then you need not rebuild them to reference 4053.
 
Does VC2008 SP1 security update have a similar issue?
 
Yes, it does, if you use _BIND_TO_CURRENT_VCLIBS_VERSION in your project. It will bind to the security update version instead of the SP1 version. You can use a similar technique as described above (step 3 is not required) to get around this problem.

For VC2008 SP1 the values for the current versions of the CRT/MFC/ATL have changed slightly, instead of _forceCRTManifest, you should use _forceCRTManifestCUR.  The same thing applies for MFC/ATL (add the CUR). And of course, the version numbers you’re dealing with are different: SP1 9.0.30729.1 vs the new SP1+security update which is 9.0.30729.4148