Поделиться через


Calling VariantClear on a OUT param can lead to security hole !!!

There was a mail thread going on internally where a security hole was suspected due to VarianltClear() being called inside a method on a out param. Since i am new to COM world, I asked my fellow MSFTian Paul Dempsey that how can it be possible. Here is what he told me...

When passing into an OUT parameter, since this variable is receiving a value there is no requirement to initialize it. If the method calls VariantClear on an uninitialized variant, then what happens depends on the exact pattern of bits in that piece of memory. If the vt part is not a valid variant type, nothing happens. If it is 9 (a Unicode TAB character and also VT_DISPATCH), VariantClear calls Release on the pointer in the variant. This will usually be some invalid address and the application crashes, but if an attacker arranges for the right bits to be in the memory that the variant comes from, he can cause code of his choice to run, yielding elevation of privilege if the code is running in elevated mode.

I though that this information could be useful for COM Beginners so just shared here :).

Comments

  • Anonymous
    March 31, 2009
    Hi Jaiprakash, I'm not sure if this is right. I had the same feeling about it and programmed my COM-object in that way. But it is leaking memory when called from VBScript. There is not much documentation about who is responsible for freeing VARIANTS in COM. Many people are using VARIANTs by always initializing and always cleaining them. My COM object declared the following method: HRESULT Test ([out]VARIANT *Value); and in them implementation I did fill it with a string, without calling VariantClear(). VBScript code: dim i, obj, v set obj = CreateObject ("myobject") for i=0 to 1000000   obj.Test v next v was correctly filled, but it is leaking fast. This behaviour is different when you change the attribute from [out] into [out,retval]. After that its not leaking any more. The VBScript code is than: dim i, obj, v set obj = CreateObject ("myobject") for i=0 to 1000000  v =  obj.Test next Regards, Peter vd Weerd