/*
 * 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);
}
Beispiel #3
0
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);
}