Unexpected updates to developer tools caused by security updates – what do to about it?

The past week’s activity in security updates have generated a lot of new blog entries on this page. But does it have to be that way?

Martin Richter has written up a very good summary of why developers need the ability to freeze their environments (or at least be properly warned!!) when tools updates are released as important security updates. The main reason is because they need to target particular runtimes, and if they have to release hotfixes their manifests must match what is already out there. Another reason is that they simply cannot keep track of all the updates, and having your tools changed out from under you out of the blue can have major repercussions, especially if there are new bugs in those tools. It can cause massive numbers of hours of lost productivity in reconfiguring a whole organization’s developer machines.

I suggest you sign up for connect.microsoft.com (Visual Studio and .NET Framework) and read this (don’t forget to vote on it while you’re there):

Feature request: Always ask the developer before applying a security fix or service pack to Visual Studio that need changed the C++ runtime DLLs ATL/MFC/CRT

I definitely support having some better communication about the issues as well at the time they are released, like when KB971090 was released there was a video on channel 9 – see http://channel9.msdn.com/Blogs/Charles/Out-of-Band-Inside-the-ATL-Security-Update for the type of info that should be communicated.

Fixing problems with FindActCtxSectionString in MFC security updates

EDIT – June 18th, 2011 – the below blog entry is out of date – click here for up to date information.

In this blog entry I attempt to fix 3 of the problems associated with FindActCtxSectionString in a statically linked application (2005 and 2008). What I’m going to do is override the appcore.cpp that gets included in every static app with one that we’ll include in our app (again, like the last blog, no editing of the included file is necessary, which is a good thing because if there any updates you’ll get them by rebuilding)

1) Open up your stdafx.cpp file in your project (a statically linked MFC project)
2) Paste the following code after the include:

#undef FindActCtxSectionString
#define FindActCtxSectionString MyFindActCtxSectionString

#ifdef _UNICODE
#define _FINDACTCTXSECTIONSTRING "FindActCtxSectionStringW"
#else
#define _FINDACTCTXSECTIONSTRING "FindActCtxSectionStringA"
#endif

typedef BOOL (WINAPI * PFN_FINDAC)(DWORD dwFlags, const GUID *lpExtensionGuid,ULONG ulSectionId,LPCTSTR lpStringToFind,PACTCTX_SECTION_KEYED_DATA ReturnedData);

BOOL WINAPI MyFindActCtxSectionString(
     DWORD dwFlags,
     const GUID *lpExtensionGuid,
     ULONG ulSectionId,
     LPCTSTR lpStringToFind,
     PACTCTX_SECTION_KEYED_DATA ReturnedData)
{
	// Bug #1 - Windows 2000 
	PFN_FINDAC pfnFindActCtxSectionString =NULL;
	{
		HINSTANCE hKernel32 = GetModuleHandle(_T("kernel32.dll"));
		if (hKernel32 == NULL) 
		{
			return FALSE;
		}

		pfnFindActCtxSectionString = (PFN_FINDAC) GetProcAddress(hKernel32, _FINDACTCTXSECTIONSTRING);

		if (pfnFindActCtxSectionString == NULL) 
		{
			/* pre-fusion OS, so no more checking.*/
			return FALSE;
		}
	}
	
	ReturnedData->cbSize = sizeof(ACTCTX_SECTION_KEYED_DATA); // Bug #2 - missing cbSize initializer 
	return pfnFindActCtxSectionString(/* dwFlags */ 0,  // Bug #3 memory leak - pass in zero as return handle not freed
		lpExtensionGuid, ulSectionId, lpStringToFind, ReturnedData);
}

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

3) rebuild your app

Now, you get the following benefits
1) Successful running under Windows 2000
2) Properly initialized cbSize (see previous blog discussion)
3) Memory leak fix (passing in first parameter leaks a context handle)

Static MFC code bloat problem from VC2010 is now in VC2008 SP1+security fix

EDIT – June 18th, 2011 – the below blog entry is out of date – click here for up to date information.

Thanks to Owen Wengerd from Outside the Box for letting me know about this one – it’s a big regression. Turns out the the code bloat release size problem introduced in VC2010 with MFC statically linked applications is now a problem in VC2008 SP1, thanks to the new security updates of April 12th.

Problem:

It all started with MS11-025. This security update caused a multitude of problems with MFC, some of which are mentioned in previous posts. This particular one is specific to VC2008 SP1, it appears after installing KB2465361 and then rebuilding your existing statically linked MFC application(s).

What happened is that themehelper.cpp now uses the function AfxLoadSystemLibraryUsingFullPath which resides in the afxglobals.cpp file (as an inline function, no less!). As we know from previous experience in VC2010, if your app has to pull in afxglobals.obj for any reason, a cascade effect occurs and approximately 1.2 megs are added to your release EXE size. For example, using the Appwizard to generate a simple MDI app with a classic menu and toolbar, and no visual styles, and building a release is 553KB before the security update, and 1763KB after the security update.

Solution:

Luckily there’s a quick solution. Owen suggested one solution which was similar to my previous blog entry about reducing static size in VC2010, which is to copy and edit the afxglobals.cpp file. But it’s actually easier than that. When I originally wrote this blog entry, I made this suggestion: we’ll include themehelper.cpp in our stdafx.cpp file without copying it, just including it directly, and use some preprocessor magic to make it use our own local version of the AfxLoadSystemLibraryUsingFullPath function instead of the one in afxglobals.cpp. But Owen realized that all you really need is your own local copy of the AfxLoadSystemLibraryUsingFullPath function somewhere in your app, and even better, there won’t be any duplicate symbol errors! So the full solution is:

1) open up your stdafx.cpp from your project
2) paste the following code after the #include "stdafx.h"


// this is our own local copy of the AfxLoadSystemLibraryUsingFullPath function
HMODULE AfxLoadSystemLibraryUsingFullPath(const WCHAR *pszLibrary)
{
	WCHAR wszLoadPath[MAX_PATH+1];
	if (::GetSystemDirectoryW(wszLoadPath, _countof(wszLoadPath)) == 0)
	{
		return NULL;
	}

	if (wszLoadPath[wcslen(wszLoadPath)-1] != L'\\')
	{
		if (wcscat_s(wszLoadPath, _countof(wszLoadPath), L"\\") != 0)
		{
			return NULL;
		}
	}

	if (wcscat_s(wszLoadPath, _countof(wszLoadPath), pszLibrary) != 0)
	{
		return NULL;
	}

	return(::AfxCtxLoadLibraryW(wszLoadPath));
}

3) Rebuild your app, and voila, it’s all better now.

Problem with FindActCtxSectionString in MFC security updates on all platforms

Martin Richter has written a blog entry on a serious issue that was introduced when the MFC security updates were released on April 12. The culprit is, again, FindActCtxSectionString, but in this case it actually affects ALL platforms. Please read the following blog entry:

BUG: Black Patchday for all OS from XP and later 3. – MFC 8.0 (VC-2005) or MFC 9.0 (VC-2008) linked dynamically to the MFC may not find the MFC language DLLs after installation of the security packs dated April 12th 2011

New redists break all dynamically linked MFC 2005/2008 apps on Windows 2000

EDIT – June 18th, 2011 – the below blog entry is out of date – click here for up to date information.

Step by step instructions for Windows 2000 end users that want to get up and running quickly after having installed one or both of the invalid Visual C++ security redistributables on Windows 2000:

1) go to Control Panel – Add/Remove Programs, and uninstall the following (one or both may be installed)
a) Microsoft Visual C++ 2005 Redistributable – KB2467175
b) Microsoft Visual C++ 2008 Redistributable – KB2467174 – x86 9.0.30729.5570

Important: look for entries in the add/remove programs with the exact titles above, i.e including those KB article numbers in the title of the entry, as there may be similar looking ones in there (ignore those ones)

2) Find your “Windows” folder. Usually this is at c:\windows or c:\winnt . For the purposes of these instructions, I’ll assume it’s c:\windows (replace that below with your actual Windows folder)

3) Create a folder on your desktop named WORKDIR. You’ll use this later to hold all the DLLs you’ll be copying to your system32 folder.

4) Using Windows Explorer, go to c:\windows\winsxs. Hit the search button. For “Search for files or folders named”, type in 4053, and then hit ENTER. If nothing has been found type in 762 and hit ENTER.

5) There should be 5 folders that were found (as well as various other files that should be ignored, also, ignore any folders with amd64 at the beginning of their folder names). Note there may be some debug folders in here as well, brining the folder count up to 8.

Example of folder name: x86_Microsoft.VC80.MFC_1fc8b3b9a1e18e3b_8.0.50727.4053_x-ww_b77cec8e

6) For each of these 5 folders (or 8 if you have Debug some debug folders), do the following:
a) double click on the folder.
b) Edit – Select all (or CTRL+A)
c) Edit-Copy (or CTRL+C)
d) click on your desktop and open the WORKDIR folder you created above, and then hit Paste (or CTRL+V).
e) return to the Windows Explorer search window and click the “Back” button.

7) Repeat step (4) except search for 4148. If nothing found, search for 21022, then repeat steps 5 and 6.

8) Now your WORKDIR folder should be full of all the DLLs you will require to have copied to your C:\Windows\System32 folder. Open the WORKDIR folder on your desktop, and select all (CTRL+A) and then Edit-Copy (CTRL+C). Then navigate to your Windows\System32 folder and Paste (CTRL+V). If you receive any errors pasting (files in use) you may have to reboot and/or exclude the MSVCR* files when copying and pasting. At a minimum, you’ll need to copy at least the MFC related DLL files (files with MFC in their names)

9) Try running the problematic applications again, to make sure the problem has been fixed.

More background info:

Thanks to Martin Richter on letting me know about this one – the new VCRedists that were rolled out yesterday due to the multi-version security update breaks all dynamically linked MFC 8.0 and 9.0 (VC2005/VC2008) apps that have ever shipped and are deployed to Windows 2000. Any app that doesn’t have a local copy of MFC in their program folder is affected (due to DLL Hell in system32)

If you install them (do this on a test machine not a production machine!), run dependency walker on the updated mfc80.dll and mfc90.dll versions on Windows 2000 and see a new function being called that is not available under XP:

FindActCtxSectionStringA (or FindActCtxSectionStringW with the Unicode version)

These are the links to the broken redistributables:

VC2005

VC2008

A simple workaround under Windows 2000 is to copy the older versions of MFC80.DLL and MFC90.DLL (or their corresponding Unicode versions) to your program folder(s). Then your app will use those instead (remember Windows 2000 was a pre-SxS world).

To find these old DLLs is tricky – what would have been nice is that something like this would work:
(1) Uninstall redist update
(2) copy older versions from system32 to your program folder

but unfortunately, uninstalling it just leaves the new (broken ones) in system32. No way to retrieve the old ones. Or is there?????

Yes it turns out: Luckily (and luckily I remembered this from years ago), Windows 2000 still installs the DLLs to WinSxS. So the old ones are still there. So the workaround is to copy from the WinSxS folder the older version of MFC8 or 9 back to system32 or your program folder. But of course, this solution not benefitting from the security updates that are so important. So the best workaround is wait for a new version to be issued by Microsoft.

Special note for those that statically link their MFC apps: you will only be affected if you update your tools (i.e. KB2465367 for VS2005, or KB2465361 for VS2008, VS2003 may be affected as well but I don’t have time to check it – see KB2465373) and then recompile your application. Then your app will no longer run on Windows 2000. So beware of installing these tools updates if you plan on rebuilding your app and releasing it and expect it to work on Windows 2000.

KB2465367 – a repeat of the KB971090 roll-out problems?

Today Microsoft released KB2465367, a Microsoft Visual C++ 2005 tools update. See:

KB2465367 download

http://support.microsoft.com/kb/2500212

http://support.microsoft.com/kb/2465367

For those of you that remember the problems that KB971090 caused to developers, I suggest you look at this patch carefully before rolling this out, to see if it affects your particular development environment. To remind you of this, please go and read my blog article about KB971090 at:

http://tedwvc.wordpress.com/2009/08/10/avoiding-problems-with-vc2005-sp1-security-update-kb971090/

NOTE: I’ve confirmed that the exact same technique used to update the VC libraries and DLLs in KB971090 are used in KB2465367 also. That is, the manifest version of your app will be increased to 8.0.50727.5592 (from 8.0.50727.762 which was the original SP1, or 8.0.50727.4053 which was the July 2009 security update). This security update contains the new MFC fixes, as well as the original ATL fixes from July 2009.