27.10.2014 Views

Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions

Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions

Cracking the Coding Interview, 4 Edition - 150 Programming Interview Questions and Solutions

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Solutions</strong> to Chapter 16 | Low Level<br />

16.6 Discuss how would you make sure that a process doesn’t access an unauthorized part<br />

of <strong>the</strong> stack.<br />

SOLUTION<br />

pg 82<br />

As with any ambiguously worded interview question, it may help to probe <strong>the</strong> interviewer to<br />

underst<strong>and</strong> what specifically you’re intended to solve. Are you trying to prevent code that<br />

has overflowed a buffer from compromising <strong>the</strong> execution by overwriting stack values? Are<br />

you trying to maintain some form of thread-specific isolation between threads? Is <strong>the</strong> code<br />

of interest native code like C++ or running under a virtual machine like Java?<br />

Remember that, in a multi-threaded environment, <strong>the</strong>re can be multiple stacks in a process.<br />

NATIVE CODE<br />

One threat to <strong>the</strong> stack is malicious program input, which can overflow a buffer <strong>and</strong> overwrite<br />

stack pointers, thus circumventing <strong>the</strong> intended execution of <strong>the</strong> program.<br />

If <strong>the</strong> interviewer is looking for a simple method to reduce <strong>the</strong> risk of buffer overflows in<br />

native code, modern compilers provide this sort of stack protection through a comm<strong>and</strong><br />

line option. With Microsoft’s CL, you just pass /GS to <strong>the</strong> compiler. With GCC, you can use<br />

-fstack-protector-all.<br />

For more complex schemes, you could set individual permissions on <strong>the</strong> range of memory<br />

pages representing <strong>the</strong> stack section you care about. In <strong>the</strong> Win32 API, you’d use <strong>the</strong> VirtualProtect<br />

API to mark <strong>the</strong> page PAGE_READONLY or PAGE_NOACCESS. This will cause <strong>the</strong><br />

code accessing <strong>the</strong> region to go through an exception on access to <strong>the</strong> specific section of<br />

<strong>the</strong> stack.<br />

Alternately, you could use <strong>the</strong> HW Debug Registers (DRs) to set a read or write breakpoint<br />

on <strong>the</strong> specific memory addresses of interest. A separate process could be used to debug<br />

<strong>the</strong> process of interest, catch <strong>the</strong> HW exception that would be generated if this section of <strong>the</strong><br />

stack were accessed.<br />

However, it’s very important to note that under normal circumstances, threads <strong>and</strong> processes<br />

are not means of access control. Nothing can prevent native code from writing anywhere<br />

within <strong>the</strong> address space of its process, including to <strong>the</strong> stack. Specifically, <strong>the</strong>re is nothing<br />

to prevent malicious code in <strong>the</strong> process from calling VirtualProtect <strong>and</strong> marking <strong>the</strong> stack<br />

sections of interest PAGE_EXECUTE_READWRITE. Equally so, nothing prevents code from<br />

zeroing out <strong>the</strong> HW debug registers, eliminating your breakpoints. In summary, nothing can<br />

fully prevent native code from accessing memory addresses, including <strong>the</strong> stack, within its<br />

own process space.<br />

MANAGED CODE<br />

CareerCup.com<br />

2 4 2

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!