# native-client

Published articles for native-client.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Native Client's NTDLL patch on x86-64 Windows

DevFeed: [Native Client's NTDLL patch on x86-64 Windows](<https://devfeed.tech/articles/native-client-s-ntdll-patch-on-x86-64-windows-21563.md>)

Original publisher: [Read original article](<http://lackingrhoticity.blogspot.com/2012/09/native-clients-ntdll-patch-on-x86-64-windows.html>)

Author: Mark Seaborn (noreply@blogger.com)

Published: 2012-09-29T02:54:00Z

Content type: tutorial

Language: en

Sources: [Mark Seaborn](<https://devfeed.tech/sources/mark-seaborn.md>)

Topics: [Security](<https://devfeed.tech/topics/security.md>), [Windows](<https://devfeed.tech/topics/windows.md>), [x86](<https://devfeed.tech/topics/x86.md>), [Exception](<https://devfeed.tech/topics/exception.md>), [Kernel](<https://devfeed.tech/topics/kernel.md>), [Chrome](<https://devfeed.tech/topics/chrome.md>), [Processes](<https://devfeed.tech/topics/processes.md>), [POSIX](<https://devfeed.tech/topics/posix.md>), [Unix](<https://devfeed.tech/topics/unix.md>)

Tags: [bug](<https://devfeed.tech/tags/bug.md>), [chrome](<https://devfeed.tech/tags/chrome.md>), [code](<https://devfeed.tech/tags/code.md>), [exception](<https://devfeed.tech/tags/exception.md>), [kernel](<https://devfeed.tech/tags/kernel.md>), [native-client](<https://devfeed.tech/tags/native-client.md>), [posix](<https://devfeed.tech/tags/posix.md>), [process](<https://devfeed.tech/tags/process.md>), [security](<https://devfeed.tech/tags/security.md>), [unix](<https://devfeed.tech/tags/unix.md>), [windows](<https://devfeed.tech/tags/windows.md>), [x86-64](<https://devfeed.tech/tags/x86-64.md>)

### AI overview

This technical article explains a security hole in Native Client on 64-bit Windows that could allow escape from the Native Client sandbox. It describes how differences between Windows vectored exception handling and Unix signal handling created the problem, and notes that Native Client used a process-local in-memory patch to NTDLL to prevent it.

### Source excerpt

Last year, I found a security hole in Native Client on 64-bit Windows that could be used to escape from the Native Client sandbox. Fortunately I found the hole before Native Client was enabled by default in Chrome. I recently wrote up the document below to explain the bug and how we fixed it. Native Client currently relies on a small, process-local, in-memory patch to NTDLL on 64-bit versions of Windows in order to prevent a problem that would create a hole in Native Client's x86-64 sandbox. The problem The problem arises because Windows does not have an equivalent of Unix's sigaltstack() system call. On Unix, a POSIX signal handler may be registered using signal() or sigaction(). When a process faults (e.g. as a result of a memory access error or an illegal instruction), the kernel passes control to the signal handler that is registered for the process. Normally, the signal handler is run on the stack of the thread that faulted. However, if an "alternate signal stack" has been registered using sigaltstack(), the signal handler will run on that stack instead. On Windows, "vectored exception handlers" are similar to Unix signal handlers, except that a vectored exception handler always gets run on the thread's current stack. This might have been OK, except that Windows has a different division of responsibility between kernel and userland compared with Unix. Windows does more in userland, and this creates problems for NaCl. On Unix, sigaction() is a syscall that user code calls that records a user-code signal handler function in a kernel data structure. If no signal handler is registered by user code, then when a fault occurs in a process, the kernel never passes control back to userland code in that process. On Windows, AddVectoredExceptionHandler() is provided in userland by a DLL rather than being provided by the kernel. AddVectoredExceptionHandler() adds the handler function to a list in userland memory. When a fault occurs in the process, the Windows kernel passe

## When printf debugging is a luxury

DevFeed: [When printf debugging is a luxury](<https://devfeed.tech/articles/when-printf-debugging-is-a-luxury-21558.md>)

Original publisher: [Read original article](<http://lackingrhoticity.blogspot.com/2010/12/when-printf-debugging-is-luxury.html>)

Author: Mark Seaborn (noreply@blogger.com)

Published: 2010-12-18T19:06:00Z

Content type: tutorial

Language: en

Sources: [Mark Seaborn](<https://devfeed.tech/sources/mark-seaborn.md>)

Topics: [debugging](<https://devfeed.tech/topics/debugging.md>), [Code](<https://devfeed.tech/topics/code.md>), [Linux](<https://devfeed.tech/topics/linux.md>), [Chromium](<https://devfeed.tech/topics/chromium.md>)

Tags: [chromium](<https://devfeed.tech/tags/chromium.md>), [code](<https://devfeed.tech/tags/code.md>), [debugging](<https://devfeed.tech/tags/debugging.md>), [glibc](<https://devfeed.tech/tags/glibc.md>), [libc](<https://devfeed.tech/tags/libc.md>), [linux](<https://devfeed.tech/tags/linux.md>), [native-client](<https://devfeed.tech/tags/native-client.md>), [sandbox](<https://devfeed.tech/tags/sandbox.md>)

### AI overview

This article explains why printf() and assert() may be unavailable in certain low-level programming contexts, including signal handlers, limited-stack environments, and code that cannot use libc. It presents a simple assertion implementation that constructs failure messages at compile time and discusses bypassing libc to invoke Linux system calls when TLS register state makes libc wrappers unusable.

### Source excerpt

Inserting printf() calls is often considered to be a primitive fallback when other debugging tools are not available, such as stack backtraces with source line numbers. But there are some situations in low-level programming where most libc calls don't work and so even printf() and assert() are unavailable luxuries. This can happen: when libc is not properly initialised yet; when we writing code that is called by libc and cannot re-enter libc code; when we are in a signal handler; when only limited stack space is available; when we cannot allocate memory for some reason; or when we are not even linked to libc. Here's a fragment of code that has come in handy in these situations. It provides a simple assert() implementation: #include <string.h> #include <unistd.h> static void debug(const char *msg) { write(2, msg, strlen(msg)); } static void die(const char *msg) { debug(msg); _exit(1); } #define TO_STRING_1(x) #x #define TO_STRING(x) TO_STRING_1(x) #define assert(expr) { \ if (!(expr)) die("assertion failed at " __FILE__ ":" TO_STRING(__LINE__) \ ": " #expr "\n"); } By using preprocessor trickery to construct the assertion failure string at compile time, it avoids having to format the string at runtime. So it does not need to allocate memory, and it doesn't need to do multiple write() calls (which can become interleaved with other output in the multi-threaded case). Sometimes even libc's write() is a luxury. In some builds of GNU libc on Linux, glibc's syscall wrappers use the TLS register (%gs on i386) to fetch the address of a routine for making syscalls. However, if %gs is not set up properly for some reason, this will fail. For example, for Native Client's i386 sandbox, %gs is set to a different value whenever sandboxed code is running, and %gs stays in this state if sandboxed code faults and triggers a signal handler. In Chromium's seccomp-sandbox, %gs is set to zero in the trusted thread. In those situations we have to bypass libc and do the system calls ourselv