[Mono-dev] [PATCH] Mixed-mode: Ensure that the image is managed before calling LoadLibrary

Zoltan Varga vargaz at gmail.com
Sun Jun 29 21:32:21 EDT 2008


Hi,

  This is ok to check in. Changes to coreee.{h,c} and to the windows
specific parts of
image.c you wrote do not need a review.

                       Zoltan

2008/6/29 Kornél Pál <kornelpal at gmail.com>:
> Hi,
>
> Currently LoadLibrary is called on the file that is possibly a CLI image.
> This patch adds a check to ensure that the image is really a CLI image
> before calling LoadLibrary.
>
> _CorValidateImage is only called for CLI images so this extra check is
> required to ensure security.
>
> Please review and approve the patch.
>
> Thanks.
>
> Kornél
>
> Index: mono/mono/metadata/image.c
> ===================================================================
> --- mono/mono/metadata/image.c  (revision 106858)
> +++ mono/mono/metadata/image.c  (working copy)
> @@ -1130,7 +1130,7 @@
>                                /* Increment reference count on images loaded
> outside of the runtime. */
>                                fname_utf16 = g_utf8_to_utf16 (absfname, -1,
> NULL, NULL, NULL);
>                                module_handle = LoadLibrary (fname_utf16);
> -                               g_assert (module_handle != NULL);
> +                               g_assert (module_handle == (HMODULE)
> image->raw_data);
>                        }
>                        mono_image_addref (image);
>                        mono_images_unlock ();
> @@ -1141,7 +1141,7 @@
>                }
>
>                fname_utf16 = g_utf8_to_utf16 (absfname, -1, NULL, NULL,
> NULL);
> -               module_handle = LoadLibrary (fname_utf16);
> +               module_handle = MonoLoadImage (fname_utf16);
>                if (status && module_handle == NULL)
>                        last_error = GetLastError ();
>
> Index: mono/mono/metadata/coree.c
> ===================================================================
> --- mono/mono/metadata/coree.c  (revision 106858)
> +++ mono/mono/metadata/coree.c  (working copy)
> @@ -301,8 +301,8 @@
>
>  NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress
> =
> NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
>
>  NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size
> =
> NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
>
>  NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress
> =
> NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
> -
> NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size
> = 0;
> -
> NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress
> = 0;
> +
> NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size
> =
> NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
> +
> NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress
> =
> NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
>
>  NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size
> = 0;
>
>  NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress
> = 0;
>
>  NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size
> =
> NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size;
> @@ -344,6 +344,9 @@
>        if (NtHeaders32->OptionalHeader.Magic !=
> IMAGE_NT_OPTIONAL_HDR32_MAGIC)
>                return STATUS_INVALID_IMAGE_FORMAT;
>
> +       if (NtHeaders32->OptionalHeader.NumberOfRvaAndSizes <=
> IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)
> +               return STATUS_INVALID_IMAGE_FORMAT;
> +
>        CliHeaderDir =
> &NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
>        if (!CliHeaderDir->VirtualAddress)
>                return STATUS_INVALID_IMAGE_FORMAT;
> @@ -382,6 +385,79 @@
>        return CorBindToRuntimeEx (pwszVersion, pwszBuildFlavor, 0, rclsid,
> riid, ppv);
>  }
>
> +HMODULE WINAPI MonoLoadImage(LPCWSTR FileName)
> +{
> +       HANDLE FileHandle;
> +       DWORD FileSize;
> +       HANDLE MapHandle;
> +       IMAGE_DOS_HEADER* DosHeader;
> +       IMAGE_NT_HEADERS32* NtHeaders32;
> +       IMAGE_NT_HEADERS64* NtHeaders64;
> +       HMODULE ModuleHandle;
> +
> +       FileHandle = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ,
> NULL, OPEN_EXISTING, 0, NULL);
> +       if (FileHandle == INVALID_HANDLE_VALUE)
> +               return NULL;
> +
> +       FileSize = GetFileSize(FileHandle, NULL);
> +       if (FileSize == INVALID_FILE_SIZE)
> +               goto CloseFile;
> +
> +       MapHandle = CreateFileMapping(FileHandle, NULL, PAGE_READONLY, 0, 0,
> NULL);
> +       if (MapHandle == NULL)
> +               goto CloseFile;
> +
> +       DosHeader = (IMAGE_DOS_HEADER*)MapViewOfFile(MapHandle,
> FILE_MAP_READ, 0, 0, 0);
> +       if (DosHeader == NULL)
> +               goto CloseMap;
> +
> +       if (FileSize < sizeof(IMAGE_DOS_HEADER) || DosHeader->e_magic !=
> IMAGE_DOS_SIGNATURE || FileSize < DosHeader->e_lfanew +
> sizeof(IMAGE_NT_HEADERS32))
> +               goto InvalidImageFormat;
> +
> +       NtHeaders32 = (IMAGE_NT_HEADERS32*)((DWORD_PTR)DosHeader +
> DosHeader->e_lfanew);
> +       if (NtHeaders32->Signature != IMAGE_NT_SIGNATURE)
> +               goto InvalidImageFormat;
> +
> +#ifdef _WIN64
> +       NtHeaders64 = (IMAGE_NT_HEADERS64*)NtHeaders32;
> +       if (NtHeaders64->OptionalHeader.Magic ==
> IMAGE_NT_OPTIONAL_HDR64_MAGIC)
> +       {
> +               if (FileSize < DosHeader->e_lfanew +
> sizeof(IMAGE_NT_HEADERS64) ||
> +                       NtHeaders64->OptionalHeader.NumberOfRvaAndSizes <=
> IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ||
> +
> !NtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
> +                               goto InvalidImageFormat;
> +
> +               goto ValidImage;
> +       }
> +#endif
> +
> +       if (NtHeaders32->OptionalHeader.Magic !=
> IMAGE_NT_OPTIONAL_HDR32_MAGIC ||
> +               NtHeaders32->OptionalHeader.NumberOfRvaAndSizes <=
> IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR ||
> +
> !NtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress)
> +       {
> +InvalidImageFormat:
> +               SetLastError(STATUS_INVALID_IMAGE_FORMAT);
> +               goto UnmapView;
> +       }
> +
> +ValidImage:
> +       UnmapViewOfFile(DosHeader);
> +       CloseHandle(MapHandle);
> +
> +       ModuleHandle = LoadLibrary(FileName);
> +
> +       CloseHandle(FileHandle);
> +       return ModuleHandle;
> +
> +UnmapView:
> +       UnmapViewOfFile(DosHeader);
> +CloseMap:
> +       CloseHandle(MapHandle);
> +CloseFile:
> +       CloseHandle(FileHandle);
> +       return NULL;
> +}
> +
>  typedef struct _EXPORT_FIXUP
>  {
>        LPCSTR Name;
> Index: mono/mono/metadata/coree.h
> ===================================================================
> --- mono/mono/metadata/coree.h  (revision 106858)
> +++ mono/mono/metadata/coree.h  (working copy)
> @@ -28,6 +28,8 @@
>
>  extern HMODULE coree_module_handle MONO_INTERNAL;
>
> +HMODULE WINAPI MonoLoadImage(LPCWSTR FileName) MONO_INTERNAL;
> +
>  gchar* mono_get_module_file_name (HMODULE module_handle) MONO_INTERNAL;
>  void mono_load_coree (const char* file_name) MONO_INTERNAL;
>  void mono_fixup_exe_image (MonoImage* image) MONO_INTERNAL;
>
> _______________________________________________
> Mono-devel-list mailing list
> Mono-devel-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>
>


More information about the Mono-devel-list mailing list