Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is SafeHandle.DangerousGetHandle() "Dangerous"?

This is the first time ever that I'll be using SafeHandle.

I need to call this P/Invoke method that needs an UIntPtr.

    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
    public static extern int RegOpenKeyEx(
      UIntPtr hKey,
      string subKey,
      int ulOptions,
      int samDesired,
      out UIntPtr hkResult);

This UIntPtr will be derived from .NET's RegistryKey class. I will be using the method above to convert the RegistryKey class to an IntPtr so I can use the above P/Invoke:

        private static IntPtr GetRegistryKeyHandle(RegistryKey rKey)
        {
            //Get the type of the RegistryKey
            Type registryKeyType = typeof(RegistryKey);

            //Get the FieldInfo of the 'hkey' member of RegistryKey
            System.Reflection.FieldInfo fieldInfo =
                registryKeyType.GetField("hkey", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            //Get the handle held by hkey
            if (fieldInfo != null)
            {
                SafeHandle handle = (SafeHandle)fieldInfo.GetValue(rKey);

                //Get the unsafe handle
                IntPtr dangerousHandle = handle.DangerousGetHandle();                
                return dangerousHandle;
            }
}

Questions:

  1. Is there a better way to write this without using "unsafe" handles?
  2. Why are unsafe handles dangerous?
like image 474
Ian Avatar asked Dec 06 '11 08:12

Ian


1 Answers

The RegistryKey has a handle property. So you can use

private static IntPtr GetRegistryKeyHandle(RegistryKey rKey)
{
    return rKey.Handle.DangerousGetHandle();
}

This is potentially dangerous, because the pointer you are getting may not be valid anymore when you are using it. Quote from MSDN

Using the DangerousGetHandle method can pose security risks because, if the handle has been marked as invalid with SetHandleAsInvalid, DangerousGetHandle still returns the original, potentially stale handle value. The returned handle can also be recycled at any point. At best, this means the handle might suddenly stop working. At worst, if the handle or the resource that the handle represents is exposed to untrusted code, this can lead to a recycling security attack on the reused or returned handle. For example, an untrusted caller can query data on the handle just returned and receive information for an entirely unrelated resource. See the DangerousAddRef and the DangerousRelease methods for more information about using the DangerousGetHandle methodsafely.

like image 198
Daniel Rose Avatar answered Oct 07 '22 14:10

Daniel Rose