/* * Allocates a selector whose size is specified in bytes. */ uint16_t NaClLdtAllocateByteSelector(NaClLdtDescriptorType type, int read_exec_only, void* base_addr, uint32_t size_in_bytes) { return NaClLdtAllocateSelector(-1, 0, type, read_exec_only, base_addr, size_in_bytes - 1); }
/* * Change a selector whose size is specified in bytes. */ uint16_t NaClLdtChangeByteSelector(int32_t entry_number, NaClLdtDescriptorType type, int read_exec_only, void* base_addr, uint32_t size_in_bytes) { if ((uint32_t) entry_number >= LDT_ENTRIES) { return 0; } return NaClLdtAllocateSelector(entry_number, 0, type, read_exec_only, base_addr, size_in_bytes - 1); }
int NaClLdtInitPlatformSpecific(void) { HMODULE hmod = GetModuleHandleA("ntdll.dll"); /* * query_information_process is used to examine LDT entries to find a free * selector, etc. */ query_information_process = (NTQUERY)(GetProcAddress(hmod, "NtQueryInformationProcess")); if (query_information_process == 0) { /* * Unable to get query_information_process, which is needed for querying * the LDT. */ return 0; } /* * set_information_process is one of the methods used to update an LDT * entry for a given selector. */ set_information_process = (NTSETINFO)(GetProcAddress(hmod, "ZwSetInformationProcess")); /* * set_ldt_entries is the other method used to update an LDT entry for a * given selector. */ set_ldt_entries = (NTSETLDT)(GetProcAddress(hmod, "NtSetLdtEntries")); if (NULL == set_ldt_entries) { set_ldt_entries = (NTSETLDT)(GetProcAddress(hmod, "ZwSetLdtEntries")); } if ((NULL == set_ldt_entries) && (NULL == set_information_process)) { /* * Unable to locate either method for setting the LDT. */ return 0; } if (!NaClMutexCtor(&nacl_ldt_mutex)) { return 0; } /* * Allocate the last LDT entry to force the LDT to grow to its maximum size. */ return NaClLdtAllocateSelector(LDT_ENTRIES - 1, 0, NACL_LDT_DESCRIPTOR_DATA, 0, 0, 0); }