Update TP3
This commit is contained in:
parent
5b03f090fe
commit
50cbff18eb
6 changed files with 181 additions and 29 deletions
92
tutorial/3/seccomp.md
Normal file
92
tutorial/3/seccomp.md
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
\newpage
|
||||
|
||||
Secure Computing Mode
|
||||
=====================
|
||||
|
||||
Plus connue sous l'acronyme *seccomp*, cette fonctionnalité du noyau Linux
|
||||
permet de restreindre les appels systèmes qu'un processus est autorisé à
|
||||
utiliser. En cas d'appel non autorisé, le processus fautif est directement tué
|
||||
(`SIGKILL`) par le noyau, ou, lorsque c'est précisé, un code `errno`
|
||||
particulier peut être renvoyé au programme.
|
||||
|
||||
Depuis la version 3.17 du noyau, l'appel système `seccomp(2)` permet de faire
|
||||
entrer le processus courant dans ce mode. En effet, c'est le processus lui-même
|
||||
qui déclare au noyau qu'il peut désormais se contenter d'une liste réduite
|
||||
d'appel système ; à l'inverse des politiques de sécurité comme SELinux ou
|
||||
AppArmor, qui encapsulent les programmes pour toute la durée de leur exécution.
|
||||
|
||||
*Seccomp* est particulièrement utile lorsqu'un processus a terminé son
|
||||
initialisation (ne dépendant en général pas de données sujettes à
|
||||
l'exploitation de vulnérabilité) et doit commencer à entrer dans des portions
|
||||
de code promptes aux vulnérabilités : c'est notamment le cas des moteurs de
|
||||
rendus des navigateurs Firefox et Chrome.
|
||||
|
||||
|
||||
## Prérequis
|
||||
|
||||
L'utilisation de `seccomp` nécessite d'avoir un noyau compilé avec l'option
|
||||
`CONFIG_SECCOMP`.
|
||||
|
||||
Vous aurez également besoin de la bibliothèque `libseccomp` car l'appel système
|
||||
`seccomp(2)` n'a pas de *wrapper* dans la libc, vous devrez donc passer par
|
||||
cette bibliothèque.
|
||||
|
||||
|
||||
## `MODE_STRICT`
|
||||
|
||||
Le mode traditionnel de *seccomp* est de ne permettre uniquement l'utilisation
|
||||
des appels système `read(2)`, `write(2)` (sur les descripteurs de fichier déjà
|
||||
ouvert), `_exit(2)` et `sigreturn(2)`.
|
||||
|
||||
Historiquement, avant la création de l'appel système `seccomp(2)`, on activait
|
||||
ce mode via :
|
||||
|
||||
<div lang="en-US">
|
||||
```c
|
||||
prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT);
|
||||
```
|
||||
</div>
|
||||
|
||||
Une fois passé cet appel système, toute entrée dans un appel système non
|
||||
autorisé conduit à un `SIGKILL` du processus.
|
||||
|
||||
|
||||
## `MODE_FILTER`
|
||||
|
||||
Plus modulable que le mode strict, le mode de filtrage permet une grande
|
||||
amplitude en permettant au programmeur de définir finement quels appels
|
||||
systèmes le programme est autorisé à faire ou non, et quel sentence est
|
||||
exécutée en cas de faute.
|
||||
|
||||
Notons que les processus fils issus (`fork(2)` ou `clone(2)`) d'un processus
|
||||
auquel est appliqué un filtre `seccomp`, héritent également de ce filtre.
|
||||
|
||||
La construction de ce filtre est faite de manière programatique, via
|
||||
des règles BPF (`Berkeley Packet Filter`). On passe ensuite ce filtre BPF en
|
||||
argument de l'appel système :
|
||||
|
||||
<div lang="en-US">
|
||||
```c
|
||||
struct sock_filter filter[];
|
||||
struct sock_fprog prog = {
|
||||
.len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
|
||||
.filter = filter,
|
||||
};
|
||||
seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
|
||||
```
|
||||
</div>
|
||||
|
||||
|
||||
### Exercice
|
||||
|
||||
Écrivez un programme filtrant un appel système, à l'aide de `seccomp` :
|
||||
|
||||
<div lang="en-US">
|
||||
```
|
||||
42sh$ ./syscall_filter sleep 5
|
||||
sleep: cannot read realtime clock: Operation not permitted
|
||||
42sh$
|
||||
```
|
||||
</div>
|
||||
|
||||
Dans cet exemple, l'appel système filtré est `nanosleep(2)`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue