Short form: our COM routines return a BSTR. If you assign that BSTR value to an object of the CComBSTR class, the value is copied to the internal storage for the class instead of being attached to the internal storage. So if you were counting on the BSTR being cleaned up when the CComBSTR object went out of scope, well, you were right for one out of two strings.
The solution is to call the Attach method for the CComBSTR class so that it takes ownership of the pointer.
And happily, I figured this out before code freeze.
Now we just need to fix all of the places that are doing it wrong.