248 |
To be written. |
To be written. |
249 |
|
|
250 |
|
|
251 |
\subsection{The \texttt{exec()} function} |
\subsection{The \texttt{exec} functions} |
252 |
\label{exec} |
\label{exec} |
253 |
|
|
254 |
The \texttt{exec()} operation will be done locally in a task. |
The \texttt{exec} operation will be done locally in a task. |
255 |
Traditionally, \texttt{exec()} overlays the same task with a new |
Traditionally, \texttt{exec} overlays the same task with a new |
256 |
process image, because creating a new task and transferring the |
process image, because creating a new task and transferring the |
257 |
associated state is expensive. In L4, only the threads and virtual |
associated state is expensive. In L4, only the threads and virtual |
258 |
memory mappings are actually kernel state associated with a task, and |
memory mappings are actually kernel state associated with a task, and |
259 |
exactly those have to be destroyed by \texttt{exec()} anyway. There |
exactly those have to be destroyed by \texttt{exec} anyway. There |
260 |
is a lot of Hurd specific state associated with a task (capabilities, |
is a lot of Hurd specific state associated with a task (capabilities, |
261 |
for example), but it is difficult to preserve that. There are |
for example), but it is difficult to preserve that. There are |
262 |
security concerns, because POSIX programs do not know about Hurd |
security concerns, because POSIX programs do not know about Hurd |
263 |
features like capabilities, so inheriting all capabilities across |
features like capabilities, so inheriting all capabilities across |
264 |
\texttt{exec()} unconditionally seems dangerous. |
\texttt{exec} unconditionally seems dangerous. |
265 |
|
|
266 |
\begin{comment} |
\begin{comment} |
267 |
One could think that if a program is not Hurd-aware, then it will |
One could think that if a program is not Hurd-aware, then it will |
268 |
not make any use of capabilities except through the normal POSIX |
not make any use of capabilities except through the normal POSIX |
269 |
API, and thus there are no capabilities except those that the GNU C |
API, and thus there are no capabilities except those that the GNU C |
270 |
library uses itself, which \texttt{exec()} can take care of. |
library uses itself, which \texttt{exec} can take care of. |
271 |
However, this is only true if code that is not Hurd-aware is never |
However, this is only true if code that is not Hurd-aware is never |
272 |
mixed with Hurd specific code, even libraries (unless the library |
mixed with Hurd specific code, even libraries (unless the library |
273 |
intimately cooperates with the GNU C library). This would be a high |
intimately cooperates with the GNU C library). This would be a high |
280 |
executable. |
executable. |
281 |
|
|
282 |
For \verb/posix_spawn()/, this is straight-forward. For |
For \verb/posix_spawn()/, this is straight-forward. For |
283 |
\texttt{exec()}, it is not. either specific capabilities could be |
\texttt{exec}, it is not. either specific capabilities could be |
284 |
markes as ``do not close on \texttt{exec()}'', or variants of the |
markes as ``do not close on \texttt{exec}'', or variants of the |
285 |
\texttt{exec()} function could be provided which take further |
\texttt{exec} function could be provided which take further |
286 |
arguments. |
arguments. |
287 |
\end{comment} |
\end{comment} |
288 |
|
|
294 |
snippet that runs during the transition). |
snippet that runs during the transition). |
295 |
|
|
296 |
So the decision was made to always create a new task with |
So the decision was made to always create a new task with |
297 |
\texttt{exec()}, and copy the desired state from the current task to |
\texttt{exec}, and copy the desired state from the current task to the |
298 |
the new task. This is a clean solution, because a new task will |
new task. This is a clean solution, because a new task will always |
299 |
always start out without any capabilities in servers, etc, and thus |
start out without any capabilities in servers, etc, and thus there is |
300 |
there is no need for the old task to try to destroy all unneeded |
no need for the old task to try to destroy all unneeded capabilities |
301 |
capabilities and other local state before \texttt{exec()}. Also, in |
and other local state before \texttt{exec}. Also, in case the |
302 |
case the exec fails, the old program can continue to run, even if the |
\texttt{exec} fails, the old program can continue to run, even if the |
303 |
exec fails at a very late point (there is no ``point of no return'' |
\texttt{exec} fails at a very late point (there is no ``point of no |
304 |
until the new task is actually up and running). |
return'' until the new task is actually up and running). |
305 |
|
|
306 |
For suid and sgid applications, the actual \texttt{exec()} has to be |
For suid and sgid applications, the actual \texttt{exec} has to be |
307 |
done by the filesystem. However, the filesystem can not be bothered |
done by the filesystem. However, the filesystem can not be bothered |
308 |
to also transfer all the user state into the new task. It can not |
to also transfer all the user state into the new task. It can not |
309 |
even do that, because it can not accept capabilities implemented by |
even do that, because it can not accept capabilities implemented by |
313 |
|
|
314 |
\begin{enumerate} |
\begin{enumerate} |
315 |
\item The user creates a new task and a container with a single |
\item The user creates a new task and a container with a single |
316 |
physical page, and makes the \texttt{exec()} call to the file |
physical page, and makes the \texttt{exec} call to the file |
317 |
capability, providing the task control capability. Before that, it |
capability, providing the task control capability. Before that, it |
318 |
creates a task info capability from it for its own use. |
creates a task info capability from it for its own use. |
319 |
\item The filesystem checks permission and then revokes all other |
\item The filesystem checks permission and then revokes all other |
354 |
idea. The details will depend a lot on the actual implementation. |
idea. The details will depend a lot on the actual implementation. |
355 |
|
|
356 |
|
|
357 |
|
\subsubsection{The startup information} |
358 |
|
|
359 |
|
The following information is passed to the new task by the parent (the |
360 |
|
filesystem in the suid case). Every item is a machine word. |
361 |
|
|
362 |
|
\begin{enumerate} |
363 |
|
\item \texttt{magic} |
364 |
|
|
365 |
|
The first four bytes are \texttt{E}, \texttt{X}, \texttt{E}, |
366 |
|
\texttt{C}. |
367 |
|
|
368 |
|
\item \texttt{program header location} |
369 |
|
\item \texttt{program header size} |
370 |
|
|
371 |
|
The location and size of the program header. The meaning of this |
372 |
|
field depends on the binary format. |
373 |
|
|
374 |
|
\item \texttt{feature flags} |
375 |
|
|
376 |
|
This bit-field indicates which of the following information is |
377 |
|
present. If the information is not present, the corresponding |
378 |
|
machine words are undefined. This provides simple version control. |
379 |
|
|
380 |
|
\begin{comment} |
381 |
|
They could also be undefined. |
382 |
|
\end{comment} |
383 |
|
|
384 |
|
\item \texttt{wortel thread ID} |
385 |
|
\item \texttt{wortel control cap ID} |
386 |
|
|
387 |
|
The thread ID of the \texttt{wortel} rootserver, and the local ID of |
388 |
|
the \texttt{wortel} control cap. The \texttt{wortel} control cap |
389 |
|
allows the user to make privileged system calls. This field is only |
390 |
|
present if the user has this capability. Usually, this is only the |
391 |
|
case for some initial servers at bootstrap. |
392 |
|
|
393 |
|
\item \texttt{physmem thread ID} |
394 |
|
\item \texttt{physmem control cap ID} |
395 |
|
|
396 |
|
The thread ID physical memory server, and the local ID of the |
397 |
|
\texttt{physmem} control cap. This cap can be used to manage the |
398 |
|
physical memory of this task. |
399 |
|
|
400 |
|
\item \texttt{physmem startup page container cap ID} |
401 |
|
|
402 |
|
The container cap ID for the startup code, containing this |
403 |
|
information, the initial pager, and other startup code. This |
404 |
|
container is mapped into the address space of the task outside of |
405 |
|
the actual program, and can be unmapped by the program after it has |
406 |
|
used this information and installed its own pager, by destroying |
407 |
|
this container, to reclaim the virtual address space and physical |
408 |
|
memory it occupies. |
409 |
|
|
410 |
|
\item (More to come.) |
411 |
|
\end{enumerate} |
412 |
|
|
413 |
|
|
414 |
\section{Unix Domain Sockets} |
\section{Unix Domain Sockets} |
415 |
\label{unixdomainsockets} |
\label{unixdomainsockets} |
416 |
|
|
546 |
\end{comment} |
\end{comment} |
547 |
|
|
548 |
The actual creation of the child filesystem can be performed much like |
The actual creation of the child filesystem can be performed much like |
549 |
a suid exec, just without any client to follow up with further |
a suid \texttt{exec}, just without any client to follow up with |
550 |
capabilities and startup info. The only problem that remains is how |
further capabilities and startup info. The only problem that remains |
551 |
the parent filesystem can know which thread in the child filesystem |
is how the parent filesystem can know which thread in the child |
552 |
implements the initial handshake protocol for the clients to use. The |
filesystem implements the initial handshake protocol for the clients |
553 |
only safe way here seems to be that the parent filesystem requires the |
to use. The only safe way here seems to be that the parent filesystem |
554 |
child to use the main thread for that, or that the parent filesystem |
requires the child to use the main thread for that, or that the parent |
555 |
creates a second thread in the child at startup (passing its thread ID |
filesystem creates a second thread in the child at startup (passing |
556 |
in the startup data), requiring that this second thread is used. In |
its thread ID in the startup data), requiring that this second thread |
557 |
either case the parent filesystem will know the thread ID in advance |
is used. In either case the parent filesystem will know the thread ID |
558 |
because it created the thread in the first place. This looks a bit |
in advance because it created the thread in the first place. This |
559 |
ugly, and violates good taste, so we might try to look for alternative |
looks a bit ugly, and violates good taste, so we might try to look for |
560 |
solutions. |
alternative solutions. |
561 |
|
|
562 |
|
|
563 |
\subsection{Reparenting} |
\subsection{Reparenting} |