diff --git a/SConstruct b/SConstruct index a579737e29..75bb9ecaff 100755 --- a/SConstruct +++ b/SConstruct @@ -637,7 +637,6 @@ nacl_glibc_skiplist = set([ 'run_abi_test', # Syscall wrappers not implemented yet. 'run_sysbasic_test', - 'run_sysbrk_test', # Fails because clock() is not hooked up. 'run_timefuncs_test', # Needs further investigation. @@ -3222,11 +3221,9 @@ irt_only_tests = [ #### ALPHABETICALLY SORTED #### 'tests/elf_loader/nacl.scons', 'tests/irt/nacl.scons', - 'tests/irt_compatibility/nacl.scons', 'tests/irt_entry_alignment/nacl.scons', 'tests/irt_ext/nacl.scons', 'tests/irt_stack_alignment/nacl.scons', - 'tests/sbrk/nacl.scons', 'tests/translator_size_limits/nacl.scons', ] diff --git a/src/trusted/debug_stub/win/platform_impl.cc b/src/trusted/debug_stub/win/platform_impl.cc index 54732b8726..f6ed36da31 100644 --- a/src/trusted/debug_stub/win/platform_impl.cc +++ b/src/trusted/debug_stub/win/platform_impl.cc @@ -21,74 +21,6 @@ * Define the OS specific portions of IPlatform interface. */ - /* - * Find files mappings and replaces them with memory which can be made - * writable. Works only with code regions where debugger need to set - * breakpoints. - */ - -static bool UnmapFiles(struct NaClApp *nap, void *ptr, uint32_t len) { - DWORD old_flags; - uintptr_t max_step; - uintptr_t user_ptr = NaClSysToUser(nap, reinterpret_cast(ptr)); - if (user_ptr + len <= user_ptr || user_ptr + len > nap->dynamic_text_end) { - return false; - } - uintptr_t user_ptr_end = user_ptr + len; - uintptr_t start_page = user_ptr >> NACL_PAGESHIFT; - uintptr_t end_page = ((user_ptr_end - 1) >> NACL_PAGESHIFT) + 1; - uintptr_t page_len = end_page - start_page; - uintptr_t current_page = start_page; - char buf[0x10000]; - while (page_len > 0) { - const NaClVmmapEntry *entry = - NaClVmmapFindPage(&nap->mem_map, current_page); - if (entry == NULL) { - current_page++; - page_len--; - continue; - } - max_step = entry->npages - (current_page - entry->page_num); - if (max_step > page_len) { - max_step = page_len; - } - if (entry->flags != 0) { - for (uintptr_t i = 0; i < max_step; i++) { - void *addr = reinterpret_cast( - NaClUserToSys(nap, (current_page + i) << NACL_PAGESHIFT)); - size_t size = 0x10000; - nacl_off64_t file_size = entry->file_size - - ((current_page + i - entry->page_num) << NACL_PAGESHIFT); - if (static_cast(size) > file_size) { - size = static_cast(file_size); - } - // fill buffer with hlt. - memset(buf, 0xf4, 0x10000); - memcpy(buf, addr, size); - if (!UnmapViewOfFile(addr)) { - return false; - } - if (NULL == VirtualAlloc(addr, 0x10000, - MEM_COMMIT, PAGE_EXECUTE_READWRITE)) { - NaClLog(LOG_FATAL, - "UnmapFiles: VirtualAlloc failed with %d\n", - GetLastError()); - } - memcpy(addr, buf, 0x10000); - if (!VirtualProtect(addr, 0x10000, - PAGE_EXECUTE_READ, &old_flags)) { - NaClLog(LOG_FATAL, - "UnmapFiles: VirtualProtect failed with %d\n", - GetLastError()); - } - } - } - current_page += max_step; - page_len -= max_step; - } - return true; -} - static bool CheckReadRights(void *ptr, uint32_t len) { MEMORY_BASIC_INFORMATION memory_info; SIZE_T offset; @@ -152,14 +84,6 @@ bool IPlatform::SetMemory(struct NaClApp *nap, uint64_t virt, uint32_t len, if (oldFlags == (DWORD) -1) { oldFlags = Reprotect(reinterpret_cast(virt), len, PAGE_WRITECOPY); - if (oldFlags == (DWORD) -1) { - // Windows XP doesn't support PAGE_EXECUTE_WRITECOPY so we fallback to - // unmapping files and mapping normal memory instead. - if (UnmapFiles(nap, reinterpret_cast(virt), len)) { - oldFlags = Reprotect(reinterpret_cast(virt), len, - PAGE_WRITECOPY); - } - } } if (oldFlags == (DWORD) -1) return false; diff --git a/src/trusted/service_runtime/include/sys/nacl_syscalls.h b/src/trusted/service_runtime/include/sys/nacl_syscalls.h index 88bd43afb3..5d338334d1 100644 --- a/src/trusted/service_runtime/include/sys/nacl_syscalls.h +++ b/src/trusted/service_runtime/include/sys/nacl_syscalls.h @@ -32,11 +32,8 @@ extern void null_syscall(void); /** * @nacl - * Sets the system break to the given address and return the address after - * the update. If new_break is NULL, simply returns the current break address. - * @param new_break The address to set the break to. - * @return On success, sysbrk returns the value of the break address. On - * failure, it returns -1 and sets errno appropriately. + * Returns the initial break address if argument is NULL. + * Otherwise it returns an error */ extern void *sysbrk(void *new_break); diff --git a/src/trusted/service_runtime/mmap_test.c b/src/trusted/service_runtime/mmap_test.c index f93e638e4e..1f56e16a6e 100644 --- a/src/trusted/service_runtime/mmap_test.c +++ b/src/trusted/service_runtime/mmap_test.c @@ -393,6 +393,26 @@ int main(int argc, char **argv) { * 4. rw Stack */ + /* + * Check mprotect failures due to partially unmapped regions. + */ + addr = NaClSysMmapIntern(nap, (void *) (500 << 20), + NACL_MAP_PAGESIZE * 10, + NACL_ABI_PROT_READ | NACL_ABI_PROT_WRITE, + NACL_ABI_MAP_ANONYMOUS | NACL_ABI_MAP_PRIVATE | NACL_ABI_MAP_FIXED, + -1, 0); + ASSERT_EQ(addr, 500 << 20); + errcode = NaClSysMprotectInternal(nap, addr - NACL_MAP_PAGESIZE, 3 * NACL_MAP_PAGESIZE, NACL_ABI_PROT_READ); + ASSERT_EQ(errcode, -NACL_ABI_EACCES); + errcode = NaClSysMprotectInternal(nap, addr + 5 * NACL_MAP_PAGESIZE, 6 * NACL_MAP_PAGESIZE, NACL_ABI_PROT_READ); + ASSERT_EQ(errcode, -NACL_ABI_EACCES); + /* Now successful ones */ + errcode = NaClSysMprotectInternal(nap, addr + NACL_MAP_PAGESIZE, 3 * NACL_MAP_PAGESIZE, NACL_ABI_PROT_READ); + ASSERT_EQ(errcode, 0); + errcode = NaClSysMprotectInternal(nap, addr + 5 * NACL_MAP_PAGESIZE, 5 * NACL_MAP_PAGESIZE, NACL_ABI_PROT_READ); + ASSERT_EQ(errcode, 0); + + /* * Check use of hint. */ @@ -443,13 +463,13 @@ int main(int argc, char **argv) { errcode = NaClSysMunmap(natp, initial_addr, 2 * NACL_MAP_PAGESIZE); ASSERT_EQ(errcode, 0); - /* Check that we cannot make the read-only data segment writable */ + /* Make the read-only data segment writable */ ent = mem_map->vmentry[2]; errcode = NaClSysMprotectInternal(nap, (uint32_t) (ent->page_num << NACL_PAGESHIFT), - ent->npages * NACL_MAP_PAGESIZE, + ent->npages * NACL_PAGESIZE, NACL_ABI_PROT_WRITE); - ASSERT_EQ(errcode, -NACL_ABI_EACCES); + ASSERT_EQ(errcode, 0); #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64 CheckForGuardRegion(nap->mem_start - ((size_t) 40 << 30), (size_t) 40 << 30); diff --git a/src/trusted/service_runtime/sel_ldr_standard.c b/src/trusted/service_runtime/sel_ldr_standard.c index bb2a20c099..7f5c90f546 100644 --- a/src/trusted/service_runtime/sel_ldr_standard.c +++ b/src/trusted/service_runtime/sel_ldr_standard.c @@ -278,10 +278,7 @@ NaClErrorCode NaClAppLoadFileAslr(struct NaClDesc *ndp, * page boundary. * * Memory allocation will use NaClRoundPage(nap->break_addr), but - * the system notion of break is always an exact address. Even - * though we must allocate and make accessible multiples of pages, - * the linux-style brk system call (which returns current break on - * failure) permits a non-aligned address as argument. + * the system notion of break is always an exact address. */ nap->break_addr = max_vaddr; nap->data_end = max_vaddr; diff --git a/src/trusted/service_runtime/sel_util-inl.h b/src/trusted/service_runtime/sel_util-inl.h index db900972b1..4f6d591f48 100644 --- a/src/trusted/service_runtime/sel_util-inl.h +++ b/src/trusted/service_runtime/sel_util-inl.h @@ -21,18 +21,10 @@ static INLINE size_t NaClRoundPage(size_t nbytes) { return (nbytes + NACL_PAGESIZE - 1) & ~((size_t) NACL_PAGESIZE - 1); } -static INLINE uint32_t NaClRoundPage32(uint32_t nbytes) { - return (nbytes + NACL_PAGESIZE - 1) & ~((size_t) NACL_PAGESIZE - 1); -} - static INLINE size_t NaClRoundAllocPage(size_t nbytes) { return (nbytes + NACL_MAP_PAGESIZE - 1) & ~((size_t) NACL_MAP_PAGESIZE - 1); } -static INLINE uint32_t NaClRoundAllocPage32(uint32_t nbytes) { - return (nbytes + NACL_MAP_PAGESIZE - 1) & ~((uint32_t)NACL_MAP_PAGESIZE - 1); -} - static INLINE size_t NaClTruncPage(size_t nbytes) { return nbytes & ~((size_t) NACL_PAGESIZE - 1); } @@ -41,10 +33,6 @@ static INLINE size_t NaClTruncAllocPage(size_t nbytes) { return nbytes & ~((size_t) NACL_MAP_PAGESIZE - 1); } -static INLINE size_t NaClBytesToPages(size_t nbytes) { - return (nbytes + NACL_PAGESIZE - 1) >> NACL_PAGESHIFT; -} - static INLINE int /* bool */ NaClIsPageMultiple(uintptr_t addr_or_size) { return 0 == ((NACL_PAGESIZE - 1) & addr_or_size); } diff --git a/src/trusted/service_runtime/sys_memory.c b/src/trusted/service_runtime/sys_memory.c index 45562ea332..2946a61655 100644 --- a/src/trusted/service_runtime/sys_memory.c +++ b/src/trusted/service_runtime/sys_memory.c @@ -45,160 +45,17 @@ static INLINE size_t size_min(size_t a, size_t b) { return (a < b) ? a : b; } +/* + * No changing the break address, only inspecting the initial one. + * This is kept around for some tests that inspect the ELF layout. + */ int32_t NaClSysBrk(struct NaClAppThread *natp, uintptr_t new_break) { struct NaClApp *nap = natp->nap; - uintptr_t break_addr; - int32_t rv = -NACL_ABI_EINVAL; - struct NaClVmmapIter iter; - struct NaClVmmapEntry *ent; - struct NaClVmmapEntry *next_ent; - uintptr_t sys_break; - uintptr_t sys_new_break; - uintptr_t usr_last_data_page; - uintptr_t usr_new_last_data_page; - uintptr_t last_internal_data_addr; - uintptr_t last_internal_page; - uintptr_t start_new_region; - uintptr_t region_size; - - /* - * The sysbrk() IRT interface is deprecated and is not enabled for - * ABI-stable PNaCl pexes, so for security hardening, disable the - * syscall under PNaCl too. - */ - if (nap->pnacl_mode) + if (new_break != 0) return -NACL_ABI_ENOSYS; - break_addr = nap->break_addr; - - NaClLog(3, "Entered NaClSysBrk(new_break 0x%08"NACL_PRIxPTR")\n", - new_break); - - sys_new_break = NaClUserToSysAddr(nap, new_break); - NaClLog(3, "sys_new_break 0x%08"NACL_PRIxPTR"\n", sys_new_break); - - if (kNaClBadAddress == sys_new_break) { - goto cleanup_no_lock; - } - if (NACL_SYNC_OK != NaClMutexLock(&nap->mu)) { - NaClLog(LOG_ERROR, "Could not get app lock for 0x%08"NACL_PRIxPTR"\n", - (uintptr_t) nap); - goto cleanup_no_lock; - } - if (new_break < nap->data_end) { - NaClLog(4, "new_break before data_end (0x%"NACL_PRIxPTR")\n", - nap->data_end); - goto cleanup; - } - if (new_break <= nap->break_addr) { - /* freeing memory */ - NaClLog(4, "new_break before break (0x%"NACL_PRIxPTR"); freeing\n", - nap->break_addr); - nap->break_addr = new_break; - break_addr = new_break; - } else { - /* - * See if page containing new_break is in mem_map; if so, we are - * essentially done -- just update break_addr. Otherwise, we - * extend the VM map entry from the page containing the current - * break to the page containing new_break. - */ - - sys_break = NaClUserToSys(nap, nap->break_addr); - - usr_last_data_page = (nap->break_addr - 1) >> NACL_PAGESHIFT; - - usr_new_last_data_page = (new_break - 1) >> NACL_PAGESHIFT; - - last_internal_data_addr = NaClRoundAllocPage(new_break) - 1; - last_internal_page = last_internal_data_addr >> NACL_PAGESHIFT; - - NaClLog(4, ("current break sys addr 0x%08"NACL_PRIxPTR", " - "usr last data page 0x%"NACL_PRIxPTR"\n"), - sys_break, usr_last_data_page); - NaClLog(4, "new break usr last data page 0x%"NACL_PRIxPTR"\n", - usr_new_last_data_page); - NaClLog(4, "last internal data addr 0x%08"NACL_PRIxPTR"\n", - last_internal_data_addr); - - if (NULL == NaClVmmapFindPageIter(&nap->mem_map, - usr_last_data_page, - &iter) - || NaClVmmapIterAtEnd(&iter)) { - NaClLog(LOG_FATAL, ("current break (0x%08"NACL_PRIxPTR", " - "sys 0x%08"NACL_PRIxPTR") " - "not in address map\n"), - nap->break_addr, sys_break); - } - ent = NaClVmmapIterStar(&iter); - NaClLog(4, ("segment containing current break" - ": page_num 0x%08"NACL_PRIxPTR", npages 0x%"NACL_PRIxS"\n"), - ent->page_num, ent->npages); - if (usr_new_last_data_page < ent->page_num + ent->npages) { - NaClLog(4, "new break within break segment, just bumping addr\n"); - nap->break_addr = new_break; - break_addr = new_break; - } else { - NaClVmmapIterIncr(&iter); - if (!NaClVmmapIterAtEnd(&iter) - && ((next_ent = NaClVmmapIterStar(&iter))->page_num - <= last_internal_page)) { - /* ran into next segment! */ - NaClLog(4, - ("new break request of usr address " - "0x%08"NACL_PRIxPTR" / usr page 0x%"NACL_PRIxPTR - " runs into next region, page_num 0x%"NACL_PRIxPTR", " - "npages 0x%"NACL_PRIxS"\n"), - new_break, usr_new_last_data_page, - next_ent->page_num, next_ent->npages); - goto cleanup; - } - NaClLog(4, - "extending segment: page_num 0x%08"NACL_PRIxPTR", " - "npages 0x%"NACL_PRIxS"\n", - ent->page_num, ent->npages); - /* go ahead and extend ent to cover, and make pages accessible */ - start_new_region = (ent->page_num + ent->npages) << NACL_PAGESHIFT; - ent->npages = (last_internal_page - ent->page_num + 1); - region_size = (((last_internal_page + 1) << NACL_PAGESHIFT) - - start_new_region); - if (0 != NaClMprotect((void *) NaClUserToSys(nap, start_new_region), - region_size, - PROT_READ | PROT_WRITE)) { - NaClLog(LOG_FATAL, - ("Could not mprotect(0x%08"NACL_PRIxPTR", " - "0x%08"NACL_PRIxPTR", " - "PROT_READ|PROT_WRITE)\n"), - start_new_region, - region_size); - } - NaClLog(4, "segment now: page_num 0x%08"NACL_PRIxPTR", " - "npages 0x%"NACL_PRIxS"\n", - ent->page_num, ent->npages); - nap->break_addr = new_break; - break_addr = new_break; - } - /* - * Zero out memory between old break and new break. - */ - CHECK(sys_new_break > sys_break); - memset((void *) sys_break, 0, sys_new_break - sys_break); - } - -cleanup: - NaClXMutexUnlock(&nap->mu); -cleanup_no_lock: - - /* - * This cast is safe because the incoming value (new_break) cannot - * exceed the user address space--even though its type (uintptr_t) - * theoretically allows larger values. - */ - rv = (int32_t) break_addr; - - NaClLog(3, "NaClSysBrk: returning 0x%08"NACL_PRIx32"\n", rv); - return rv; + return (int32_t) NaClUserToSys(nap, nap->break_addr); } int NaClSysCommonAddrRangeContainsExecutablePages(struct NaClApp *nap, diff --git a/src/untrusted/irt/irt.h b/src/untrusted/irt/irt.h index f86f807d3a..7f28d8f025 100644 --- a/src/untrusted/irt/irt.h +++ b/src/untrusted/irt/irt.h @@ -150,50 +150,6 @@ struct nacl_irt_filename { int (*stat)(const char *pathname, nacl_irt_stat_t *); }; -/* - * This old version of irt-memory is disabled under PNaCl because it - * contains sysbrk() (see - * https://code.google.com/p/nativeclient/issues/detail?id=3542). - */ -#define NACL_IRT_MEMORY_v0_1 "nacl-irt-memory-0.1" -struct nacl_irt_memory_v0_1 { - /* - * sysbrk() allocates memory from the "brk" heap. This function is - * deprecated; new programs should use mmap() instead. - * - * If |*newbrk| is NULL, sysbrk() sets |*newbrk| to the current - * break pointer and returns 0. - * - * If |*newbrk| is non-NULL and greater than the current break - * pointer, sysbrk() tries to allocate this memory. If the - * allocation fails, it returns ENOMEM. Otherwise, sysbrk(): - * * ensures the memory between the break pointer and |*newbrk| is - * readable and writable, and zeroes it; - * * sets the current break pointer to |*newbrk|; and - * * returns 0 to indicate success. - * - * If |*newbrk| is non-NULL and less than the current break pointer, - * sysbrk() deallocates this memory. sysbrk() sets the break - * pointer to |*newbrk| and returns 0. If |*newbrk| is less than - * the process's initial break pointer, the behaviour is undefined. - */ - int (*sysbrk)(void **newbrk); - /* Note: this version of mmap silently ignores PROT_EXEC bit. */ - int (*mmap)(void **addr, size_t len, int prot, int flags, int fd, - nacl_irt_off_t off); - int (*munmap)(void *addr, size_t len); -}; - -/* This old version of irt-memory is also disabled under PNaCl. */ -#define NACL_IRT_MEMORY_v0_2 "nacl-irt-memory-0.2" -struct nacl_irt_memory_v0_2 { - int (*sysbrk)(void **newbrk); - int (*mmap)(void **addr, size_t len, int prot, int flags, int fd, - nacl_irt_off_t off); - int (*munmap)(void *addr, size_t len); - int (*mprotect)(void *addr, size_t len, int prot); -}; - #define NACL_IRT_MEMORY_v0_3 "nacl-irt-memory-0.3" struct nacl_irt_memory { int (*mmap)(void **addr, size_t len, int prot, int flags, int fd, diff --git a/src/untrusted/irt/irt_interfaces.c b/src/untrusted/irt/irt_interfaces.c index e9c8cf3a16..9795ac3512 100644 --- a/src/untrusted/irt/irt_interfaces.c +++ b/src/untrusted/irt/irt_interfaces.c @@ -68,15 +68,6 @@ static const struct nacl_irt_interface irt_interfaces[] = { sizeof(nacl_irt_dev_filename_v0_2), file_access_filter }, { NACL_IRT_DEV_FILENAME_v0_3, &nacl_irt_dev_filename, sizeof(nacl_irt_dev_filename), file_access_filter }, - /* - * The old versions of "irt-memory", v0.1 and v0.2, which contain - * the deprecated sysbrk() function, are disabled under PNaCl. See: - * https://code.google.com/p/nativeclient/issues/detail?id=3542 - */ - { NACL_IRT_MEMORY_v0_1, &nacl_irt_memory_v0_1, sizeof(nacl_irt_memory_v0_1), - non_pnacl_filter }, - { NACL_IRT_MEMORY_v0_2, &nacl_irt_memory_v0_2, sizeof(nacl_irt_memory_v0_2), - non_pnacl_filter }, { NACL_IRT_MEMORY_v0_3, &nacl_irt_memory, sizeof(nacl_irt_memory), NULL }, /* * "irt-dyncode" is not supported under PNaCl because dynamically diff --git a/src/untrusted/irt/irt_interfaces.h b/src/untrusted/irt/irt_interfaces.h index c1e9f8e40c..ef4271523e 100644 --- a/src/untrusted/irt/irt_interfaces.h +++ b/src/untrusted/irt/irt_interfaces.h @@ -15,8 +15,6 @@ extern const struct nacl_irt_dev_fdio nacl_irt_dev_fdio; extern const struct nacl_irt_filename nacl_irt_filename; extern const struct nacl_irt_dev_filename_v0_2 nacl_irt_dev_filename_v0_2; extern const struct nacl_irt_dev_filename nacl_irt_dev_filename; -extern const struct nacl_irt_memory_v0_1 nacl_irt_memory_v0_1; -extern const struct nacl_irt_memory_v0_2 nacl_irt_memory_v0_2; extern const struct nacl_irt_memory nacl_irt_memory; extern const struct nacl_irt_dyncode nacl_irt_dyncode; extern const struct nacl_irt_thread nacl_irt_thread; diff --git a/src/untrusted/irt/irt_memory.c b/src/untrusted/irt/irt_memory.c index b3c1a3bef7..aba91f7c64 100644 --- a/src/untrusted/irt/irt_memory.c +++ b/src/untrusted/irt/irt_memory.c @@ -13,27 +13,6 @@ #include "native_client/src/untrusted/irt/irt_private.h" #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h" -static int nacl_irt_sysbrk(void **newbrk) { - /* - * The syscall does not actually indicate error. It just returns the - * new current value, which is unchanged if something went wrong. - * But if the requested value was below the end of the data segment, - * the new value will be greater, but this is not "going wrong". - * Here we just approximate a saner interface: you get what you requested, - * you did a "probe" request passing NULL in, or it's an error. - * TODO(mcgrathr): this interface should just go away!! - */ - void *requested = *newbrk; - void *got = NACL_SYSCALL(brk)(requested); - - if (got == requested || requested == NULL) { - *newbrk = got; - return 0; - } - - return ENOMEM; -} - static int nacl_irt_mmap(void **addr, size_t len, int prot, int flags, int fd, off_t off) { /* @@ -85,15 +64,6 @@ static int nacl_irt_mmap(void **addr, size_t len, return 0; } -/* - * mmap from nacl-irt-memory-0.1 interface should ignore PROT_EXEC bit for - * backward-compatibility reasons. - */ -static int nacl_irt_mmap_v0_1(void **addr, size_t len, - int prot, int flags, int fd, off_t off) { - return nacl_irt_mmap(addr, len, prot & ~PROT_EXEC, flags, fd, off); -} - static int nacl_irt_munmap(void *addr, size_t len) { return -NACL_SYSCALL(munmap)(addr, len); } @@ -102,19 +72,6 @@ static int nacl_irt_mprotect(void *addr, size_t len, int prot) { return -NACL_SYSCALL(mprotect)(addr, len, prot); } -const struct nacl_irt_memory_v0_1 nacl_irt_memory_v0_1 = { - nacl_irt_sysbrk, - nacl_irt_mmap_v0_1, - nacl_irt_munmap, -}; - -const struct nacl_irt_memory_v0_2 nacl_irt_memory_v0_2 = { - nacl_irt_sysbrk, - nacl_irt_mmap, - nacl_irt_munmap, - nacl_irt_mprotect, -}; - const struct nacl_irt_memory nacl_irt_memory = { nacl_irt_mmap, nacl_irt_munmap, diff --git a/src/untrusted/nacl/nacl_irt_init.c b/src/untrusted/nacl/nacl_irt_init.c index f0f02c52a7..d085b28421 100644 --- a/src/untrusted/nacl/nacl_irt_init.c +++ b/src/untrusted/nacl/nacl_irt_init.c @@ -8,10 +8,6 @@ #include "native_client/src/include/elf32.h" #include "native_client/src/untrusted/nacl/nacl_irt.h" -static int __libnacl_irt_mprotect(void *addr, size_t len, int prot) { - return ENOSYS; -} - /* * Scan the auxv for AT_SYSINFO, which is the pointer to the IRT query function. * Stash that for later use. @@ -51,24 +47,6 @@ void __libnacl_irt_init(Elf32_auxv_t *auxv) { } DO_QUERY(NACL_IRT_BASIC_v0_1, basic); - - if (!__libnacl_irt_query(NACL_IRT_MEMORY_v0_3, - &__libnacl_irt_memory, - sizeof(__libnacl_irt_memory))) { - /* Fall back to trying the old version, before sysbrk() was removed. */ - struct nacl_irt_memory_v0_2 old_irt_memory; - if (!__libnacl_irt_query(NACL_IRT_MEMORY_v0_2, - &old_irt_memory, - sizeof(old_irt_memory))) { - /* Fall back to trying an older version, before mprotect() was added. */ - __libnacl_mandatory_irt_query(NACL_IRT_MEMORY_v0_1, - &old_irt_memory, - sizeof(struct nacl_irt_memory_v0_1)); - __libnacl_irt_memory.mprotect = __libnacl_irt_mprotect; - } - __libnacl_irt_memory.mmap = old_irt_memory.mmap; - __libnacl_irt_memory.munmap = old_irt_memory.munmap; - } - + DO_QUERY(NACL_IRT_MEMORY_v0_3, memory); DO_QUERY(NACL_IRT_TLS_v0_1, tls); } diff --git a/src/untrusted/nacl/tls.h b/src/untrusted/nacl/tls.h index 8787ecf068..e88373e272 100644 --- a/src/untrusted/nacl/tls.h +++ b/src/untrusted/nacl/tls.h @@ -12,7 +12,7 @@ void __pthread_initialize(void); /* - * Allocates (using sbrk) and initializes the combined area for the + * Allocates and initializes the combined area for the * main thread. Always called, whether or not pthreads is in use. */ void __pthread_initialize_minimal(size_t tdb_size); diff --git a/tests/irt/irt_interface_prefix_test.c b/tests/irt/irt_interface_prefix_test.c deleted file mode 100644 index 5d9fccc01b..0000000000 --- a/tests/irt/irt_interface_prefix_test.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2013 The Native Client Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "native_client/src/untrusted/irt/irt.h" - -const size_t k64Kbytes = 64 * 1024; -const int kAnonymousFiledesc = -1; - -/* - * Check that the old version of the memory interface is - * a prefix of the new version. - */ -void test_memory_interface_prefix(void) { - struct nacl_irt_memory_v0_1 m1; - struct nacl_irt_memory_v0_2 m2; - struct nacl_irt_memory m3; - void *addr; - int rc; - - rc = nacl_interface_query(NACL_IRT_MEMORY_v0_1, &m1, sizeof m1); - assert(rc == sizeof m1); - - rc = nacl_interface_query(NACL_IRT_MEMORY_v0_2, &m2, sizeof m2); - assert(rc == sizeof m2); - - rc = nacl_interface_query(NACL_IRT_MEMORY_v0_3, &m3, sizeof m3); - assert(rc == sizeof m3); - - /* Verify that v0.1 mmap ignores PROT_EXEC */ - addr = 0; - rc = m1.mmap(&addr, - k64Kbytes, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, - kAnonymousFiledesc, - 0); - /* Return value is actually new address and not a negative return code. */ - assert(0xffff0000u > (uint32_t)rc); - - - /* Verify that v0.2 mmap does not ignore PROT_EXEC */ - addr = 0; - rc = m2.mmap(&addr, - k64Kbytes, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, - kAnonymousFiledesc, - 0); - assert(rc = -EINVAL); - - /* mmap is different, everything else should be the same. */ - m1.mmap = m2.mmap; - assert(memcmp(&m1, &m2, sizeof m1) == 0); - - /* v0.3 is the same as v0.2, but with the deprecated sysbrk() removed. */ - assert(m3.mmap == m2.mmap); - assert(m3.munmap == m2.munmap); - assert(m3.mprotect == m2.mprotect); -} - -int main(void) { - test_memory_interface_prefix(); - - return 0; -} diff --git a/tests/irt/nacl.scons b/tests/irt/nacl.scons index 908ca1763e..a323a0fbd0 100644 --- a/tests/irt/nacl.scons +++ b/tests/irt/nacl.scons @@ -20,20 +20,6 @@ node = env.CommandSelLdrTestNacl( env.AddNodeToTestSuite(node, ['small_tests'], 'run_irt_present_test') -# IRT interface prefix test - -nexe = env.ComponentProgram('irt_interface_prefix_test', - 'irt_interface_prefix_test.c', - EXTRA_LIBS=['${NONIRT_LIBS}'], - ) - -node = env.CommandSelLdrTestNacl( - 'irt_interface_prefix_test.out', - nexe, - ) - -env.AddNodeToTestSuite(node, ['small_tests'], 'run_irt_interface_prefix_test') - # IRT interface dev test interface_dev_test_nexe = env.ComponentProgram('irt_interface_dev_test', diff --git a/tests/irt_compatibility/irt_comp_interfaces.c b/tests/irt_compatibility/irt_comp_interfaces.c deleted file mode 100644 index a80e087e86..0000000000 --- a/tests/irt_compatibility/irt_comp_interfaces.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2013 The Native Client Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include - -#include "native_client/src/include/nacl_macros.h" -#include "native_client/src/untrusted/irt/irt.h" -#include "native_client/src/untrusted/irt/irt_interfaces.h" - -struct nacl_interface_table { - const char *name; - const void *table; - size_t size; -}; - -static const struct nacl_interface_table irt_interfaces[] = { - /* - * We expect current NaCl programs to be able to work with this - * minimal set of IRT interface versions. Some of these are old - * interface versions. - */ - { NACL_IRT_BASIC_v0_1, &nacl_irt_basic, sizeof(nacl_irt_basic) }, - { NACL_IRT_MEMORY_v0_1, &nacl_irt_memory_v0_1, sizeof(nacl_irt_memory_v0_1) }, - { NACL_IRT_TLS_v0_1, &nacl_irt_tls, sizeof(nacl_irt_tls) }, -#if ALLOW_DYNAMIC_LINKING - { NACL_IRT_FILENAME_v0_1, &nacl_irt_filename, sizeof(nacl_irt_filename) }, - { NACL_IRT_DYNCODE_v0_1, &nacl_irt_dyncode, sizeof(nacl_irt_dyncode) }, -#endif - /* - * Nexes should not necessarily require "fdio" at startup, but its - * presence is necessary for hello_world to produce output and so - * for the hello_world test to pass. - */ - { NACL_IRT_FDIO_v0_1, &nacl_irt_fdio, sizeof(nacl_irt_fdio) }, -}; - -size_t nacl_irt_query_core(const char *interface_ident, - void *table, size_t tablesize) { - int i; - for (i = 0; i < NACL_ARRAY_SIZE(irt_interfaces); ++i) { - if (0 == strcmp(interface_ident, irt_interfaces[i].name)) { - const size_t size = irt_interfaces[i].size; - if (size <= tablesize) { - memcpy(table, irt_interfaces[i].table, size); - return size; - } - break; - } - } - return 0; -} diff --git a/tests/irt_compatibility/nacl.scons b/tests/irt_compatibility/nacl.scons deleted file mode 100644 index 32846a13db..0000000000 --- a/tests/irt_compatibility/nacl.scons +++ /dev/null @@ -1,45 +0,0 @@ -# -*- python -*- -# Copyright (c) 2013 The Native Client Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -Import('env') - -# IRT backward compatibility test - -# This test uses a nexe built by another test. Nexes do not get -# staged in pexe mode, so only run this test in nonpexe mode. -if env.Bit('pnacl_generate_pexe'): - Return() - -# The new glibc requires some newer IRT interfaces. -if env.Bit('nacl_glibc') and not env.Bit('build_x86'): - Return() - -blob_env = env['NACL_IRT_ENV'].Clone() -blob_env.Append(LINKFLAGS=['-Wl,-Trodata-segment=${IRT_BLOB_DATA_START}', - '-Wl,-Ttext-segment=${IRT_BLOB_CODE_START}']) - -# Build custom IRT library which provides a minimal subset of old -# interface versions. -blob_env.Append(CPPDEFINES=[['ALLOW_DYNAMIC_LINKING', - str(int(not env.Bit('nacl_static_link')))]]) -irt_comp_test_raw_library = blob_env.ComponentProgram( - 'irt_comp_test_raw', ['irt_comp_interfaces.c'], - EXTRA_LIBS=['irt_support_private']) - -irt_comp_test_library = env.ApplyTLSEdit( - 'irt_comp_test', - irt_comp_test_raw_library) - -# Don't provide IRT, we provide it ourselves via -B. -env.ClearBits('tests_use_irt') - -node = env.CommandSelLdrTestNacl( - 'irt_compatibility_test.out', - env.File('${STAGING_DIR}/hello_world.nexe'), - sel_ldr_flags=['-B', irt_comp_test_library], - stdout_golden=env.File('../hello_world/hello_world.stdout')) - -env.AddNodeToTestSuite(node, ['small_tests', 'nonpexe_tests'], - 'run_irt_compatibility_test') diff --git a/tests/sbrk/nacl.scons b/tests/sbrk/nacl.scons deleted file mode 100644 index 500d168f21..0000000000 --- a/tests/sbrk/nacl.scons +++ /dev/null @@ -1,18 +0,0 @@ -# -*- python -*- -# Copyright (c) 2011 The Native Client Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -Import('env') - -sbrk_nexe = env.ComponentProgram('sbrk_test', - ['sbrk_test.c'], - EXTRA_LIBS=['${NONIRT_LIBS}']) - -node = env.CommandSelLdrTestNacl( - 'sbrk_test.out', - sbrk_nexe, - ) -env.AddNodeToTestSuite(node, - ['small_tests', 'sel_ldr_tests'], - 'run_sbrk_test') diff --git a/tests/sbrk/sbrk_test.c b/tests/sbrk/sbrk_test.c deleted file mode 100644 index cc89331f7d..0000000000 --- a/tests/sbrk/sbrk_test.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2011 The Native Client Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include -#include -#include -#include -#include - -#include "native_client/src/include/nacl_assert.h" -#include "native_client/src/untrusted/irt/irt.h" - -/* - * This test checks that memory allocated via sysbrk() is zeroed, even - * if it was previously allocated and deallocated. - * See http://code.google.com/p/nativeclient/issues/detail?id=2417 - * - * sysbrk() is deprecated, so we test the IRT interface directly - * rather than testing any libc wrappers for it. - */ - -static struct nacl_irt_memory_v0_2 irt_memory; - -static void *get_break(void) { - void *addr = NULL; - int rc = irt_memory.sysbrk(&addr); - ASSERT_EQ(rc, 0); - ASSERT_NE(addr, NULL); - return addr; -} - -static void set_break(void *new_addr) { - void *addr_copy = new_addr; - int rc = irt_memory.sysbrk(&addr_copy); - ASSERT_EQ(rc, 0); - /* Check that sysbrk() does not modify the value in the success case. */ - ASSERT_EQ(addr_copy, new_addr); -} - -#define NUM_WORDS 512 - -int main(void) { - size_t ix; - int status; - - size_t query_result = nacl_interface_query(NACL_IRT_MEMORY_v0_2, - &irt_memory, sizeof(irt_memory)); - ASSERT_EQ(query_result, sizeof(irt_memory)); - - /* Find the current break pointer. */ - int *alloc_start = get_break(); - fprintf(stderr, "initial break is at %p\n", (void *) alloc_start); - - /* We expect that the initial break pointer is word-aligned. */ - ASSERT_EQ((uintptr_t) alloc_start & 3, 0); - - /* Allocate some memory and fill it with data. */ - void *alloc_end = alloc_start + NUM_WORDS; - set_break(alloc_end); - for (ix = 0; ix < NUM_WORDS; ++ix) { - alloc_start[ix] = 0xdeadbeef; - } - /* Deallocate the memory. */ - set_break(alloc_start); - /* Allocate the memory again. The contents should have been zeroed. */ - set_break(alloc_end); - status = 0; - for (ix = 0; ix < NUM_WORDS; ++ix) { - if (0 != alloc_start[ix]) { - fprintf(stderr, "new memory word at %zd contains 0x%04x\n", - ix, alloc_start[ix]); - status = 3; - } - } - return status; -} diff --git a/tests/sysbasic/sysbasic.c b/tests/sysbasic/sysbasic.c index 1c66b77650..216f9f70ff 100644 --- a/tests/sysbasic/sysbasic.c +++ b/tests/sysbasic/sysbasic.c @@ -121,7 +121,7 @@ int main(void) { myprint("\nsysbrk()\n"); i = (int) sysbrk((void *) sysbrkBase); PrintInt(i); - if (sysbrkBase != i) Error("bad sysbrk() value\n"); + if (i != -ENOSYS) Error("sysbrk() didn't return failure value\n"); myprint("\nmmap()\n"); i = (int) mmap(0, kMmapSize, diff --git a/tests/syscalls/nacl.scons b/tests/syscalls/nacl.scons index a897970174..d565debbb9 100644 --- a/tests/syscalls/nacl.scons +++ b/tests/syscalls/nacl.scons @@ -163,24 +163,6 @@ env.AddNodeToTestSuite(node, ['small_tests', 'sel_ldr_tests'], 'run_mem_test') -nonstable_env = env.Clone() -if nonstable_env.SetNonStableBitcodeIfAllowed(): - if nonstable_env.Bit('bitcode'): - # sysbrk_test.cc has an external reference to "end", a symbol - # defined by the native linker, which is disallowed by PNaCl's - # ABI. - nonstable_env.Append(LINKFLAGS=['--pnacl-disable-abi-check']) - sysbrk_test_nexe = nonstable_env.ComponentProgram( - 'sysbrk_test', ['sysbrk_test.cc'], - EXTRA_LIBS=['syscall_test_framework', - '${NONIRT_LIBS}', - 'nacl_sys_private']) - node = nonstable_env.CommandSelLdrTestNacl('sysbrk_test.out', - sysbrk_test_nexe) - nonstable_env.AddNodeToTestSuite(node, - ['small_tests', 'sel_ldr_tests'], - 'run_sysbrk_test') - # additions to add syscall tests 40-42 timefuncs_test_nexe = env.ComponentProgram( 'timefuncs_test', diff --git a/tests/syscalls/sysbrk_test.cc b/tests/syscalls/sysbrk_test.cc deleted file mode 100644 index 272c1a34e6..0000000000 --- a/tests/syscalls/sysbrk_test.cc +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2011 The Native Client Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// These tests exercise NaCl's sysbrk() system call. - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "native_client/src/trusted/service_runtime/include/sys/nacl_syscalls.h" -#include "native_client/tests/syscalls/test.h" - -/* - * This is defined by the linker as the address of the end of our data segment. - * That's where the break starts out by default. - */ -extern "C" { - extern char end; -} - -namespace { -// Note: these parameters to sysbrk are not supposed to be const. - -// The defined error return address. -void* kSysbrkErrorAddress = reinterpret_cast(-1); - -// This is an address outside of the 1Gb address range allowed for NaCl -// modules. -void* kIllegalBreakAddress = reinterpret_cast(~0U); - -// Make sure the current break address is non-0 when using sysbrk(). -int TestCurrentBreakAddr() { - START_TEST("TestCurrentBreakAddr"); - - // Clear errno incase a previous function set it. - errno = 0; - - void* break_addr = sysbrk(NULL); - EXPECT(NULL != break_addr); - EXPECT(kSysbrkErrorAddress != break_addr); - EXPECT(0 == errno); - END_TEST(); -} - - -// Try to reset the program's break address to a legitimate value. -int TestSysbrk() { - // Round up to the end of the page that's our last initial data page. - // Then add 10MB for good measure to be out of the way of any allocations - // that might have been done before we got here. - void* const sysbrkBase = reinterpret_cast - (((reinterpret_cast(&end) + 0xffff) & -0x10000) + (10 << 20)); - - START_TEST("TestSysbrk"); - - // Clear errno incase a previous function set it. - errno = 0; - - void* break_addr = sysbrk(sysbrkBase); - EXPECT(NULL != break_addr); - EXPECT(kSysbrkErrorAddress != break_addr); - EXPECT(sysbrkBase == break_addr); - EXPECT(0 == errno); - END_TEST(); -} - - -// Try to reset the program's break address to something illegal using sysbrk(). -// When sysbrk() fails, it is supposed to return the old break address and set -// |errno| "to an appropriate value" (in this case, EINVAL). -int TestIllegalSysbrk() { - START_TEST("TestIllegalSysbrk"); - - // Clear errno incase a previous function set it. - errno = 0; - - void* current_break = sysbrk(NULL); - void* break_addr = sysbrk(kIllegalBreakAddress); - /* sysbrk does not touch errno, only the sbrk wrapper would */ - EXPECT(0 == errno); - EXPECT(NULL != break_addr); - EXPECT(current_break == break_addr); - END_TEST(); -} -} // namespace - -// Run through the complete sequence of sysbrk tests. Sets the exit code to -// the number of failed tests. Exit code 0 means all passed. -int main() { - int fail_count = 0; - fail_count += TestCurrentBreakAddr(); - fail_count += TestSysbrk(); - fail_count += TestIllegalSysbrk(); - return fail_count; -}