28.08.2015 Views

The Design and Implementation of the Anykernel and Rump Kernels

1F3KDce

1F3KDce

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

177<br />

• <strong>The</strong> closefrom() routine closes all file descriptors equal to or greater than<br />

<strong>the</strong> given descriptor number. We h<strong>and</strong>le this operation in two stages. First,<br />

we loop <strong>and</strong> call close() for all descriptors which are not internal to rumpclient.<br />

After we reach <strong>the</strong> highest rumpclient internal descriptor we can<br />

execute a host closefrom() using one greater than <strong>the</strong> highest rumpclient<br />

descriptor as <strong>the</strong> argument. Next, we execute closefrom() for <strong>the</strong> rump<br />

kernel, but this time we avoid closing any dup2’d file descriptors.<br />

Finally, we must deal with asynchronous I/O calls that may have to call both kernels.<br />

For example, in networking clients it is common to pass in one descriptor for <strong>the</strong><br />

client’s console <strong>and</strong> one descriptor for <strong>the</strong> network socket. Since we do not have a<br />

priori knowledge <strong>of</strong> which kernel will have activity first, we must query both. This<br />

simultaneous query is done by creating a thread to call <strong>the</strong> second kernel. Since<br />

only one kernel is likely to produce activity, we also add one host kernel pipe <strong>and</strong><br />

one rump kernel pipe to <strong>the</strong> file descriptor sets being polled. After <strong>the</strong> operation<br />

returns from one kernel, we write to <strong>the</strong> pipe <strong>of</strong> <strong>the</strong> o<strong>the</strong>r kernel to signal <strong>the</strong> end<br />

<strong>of</strong> <strong>the</strong> operation, join <strong>the</strong> thread, collect <strong>the</strong> results, <strong>and</strong> return.<br />

3.12.7 A Tale <strong>of</strong> Two Syscalls: fork() <strong>and</strong> execve()<br />

<strong>The</strong> fork() <strong>and</strong> execve() system calls require extra consideration both on <strong>the</strong> client<br />

side <strong>and</strong> <strong>the</strong> rump kernel side due to <strong>the</strong>ir special semantics. We must preserve those<br />

semantics both for <strong>the</strong> client application <strong>and</strong> <strong>the</strong> rump kernel context. While <strong>the</strong>se<br />

operations are implemented in librumpclient, <strong>the</strong>y are most relevant when running<br />

hijacked clients. Many programs such as <strong>the</strong> OpenSSH [90] sshd or <strong>the</strong> mutt [83]<br />

MUA fail to operate as remote rump clients if support is h<strong>and</strong>led incorrectly.

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

Saved successfully!

Ooh no, something went wrong!