[Mono-dev] [PATCH] Mixed-mode: Ensure that the image is managed before calling LoadLibrary
Kornél Pál
kornelpal at gmail.com
Mon Jun 30 03:39:58 EDT 2008
OK, thank you very much.
Kornél
Zoltan Varga wrote:
> 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