Add Linux kernel part

This commit is contained in:
Yorick Barbanneau 2024-01-15 20:58:29 +01:00
parent eaf2d3f44c
commit bfa1fdb2c5

View file

@ -0,0 +1,101 @@
---
title: "Sécurité système : passage dans le noyau"
date: 2023-11-16
tags: ["Linux", "noyau"]
categories: ["Sécurité système", "Cours"]
mathjax: true
---
Lors du cours sécurité logicielles, nous voulions devenir `root`, maintenant
nous voulons aller dans le noyau! Sur notre machine cible, nous devons donc
devenir `root` si noue ne le sommes pas déjà et ensuite **devenir invisible**.
Les objectifs de cette partie du cours sont :
* Avoir une vision globale de l'architecture du noyau;
* Comprendre ses mécanismes de protections;
* Comprendre les mécanismes de transmissions de données;
* Comprendre les mécanismes fournis par le noyau aux utilisateurs pour leurs
protection.
## Le noyau
Commençons par regarder l'organisation de son code source, voici les dossiers
les plus importants:
* `include/`: les fichiers d'entêtes (`.h`), par exempel celle pour `printk()`;
* `lib/`: les différentes bibliothèques comme par exemple les calculs de CRC ou
les algorithmes de chiffement.
* `arch/`: les codes spécifiques aux architectures spécifiques (`x86`, `x86_54`
`AARCH64`)
* `init/`: le code relatif à l'initialisation du noyau (le code lancé dès le
démarrage)
* `kernel/`: fourre-tout non lié au matériel,
[les signaux]({{<ref "progsys/4_les-signaux/index.md">}}) par exemple;
* `mm/`: tout ce qui est relatif à la gestion de la mémoire comme les accès,
les permissions, la swap etc.
* `block/`: code relatif aux périphérique de type *block* (stockage);
* `fs`: code relatif aux systèmes de fichiers;
* `net`: code relatif à la gestion du réseau;
* `sound`: code relatif à la gestion du son;
* `drivers/`: tous les pilotes non présent dans les 4 catégories ci-dessus.
C'est ici la partie la plus importante, mais aussi celle avec le
plus de bugs[^bugs];
## Le passage en mode noyau
Lors d'un appel système, nous passons de l'autre côté de la barrière : du mode
utilisateur nous passons en mode noyau. `malloc()` par exemple fait appel à
`sbrk` côté noyau (comme appel système). Les différents composants su mode noyau
sont:
* L'ordonanceur (*scheduler*);
* Le hestionnaire de memoire (*memory managment*);
* Les pilotes (*drivers*);
* VFS pour Virtual Files System: c'est un composant central du noyau
(n'oublions pas la philosophie Unix : *tout est fichiers*). VFS accède
ensuite à *BlkDev* ou *NetDev* (mais aussi dans le *MemoryManager*).
## Les points d'entrées
Le noyau comporte plusieurs point d'entrées:
* Demarrage du noyau: `start_kernel` lorsque le bootloadeur du matériel passe
la main au noyau;
* Les appels système, comme par exemple `sys_open`, `sys_read` etc.
* Les appels au *VFS*, comme `vfs_read` ou `vfs_open`... *VFS* utilise aussi un
cache en mémoire;
* Les systèmes de fichiers comme `ext2_file_read_iter`. Nous verrons en TD
`unlock_ioctl`, véritable couteau suisse non factorisé pour certaines
actions sur les systèmes de fichiers.
* Les sockets (réseau ou non) avec entre autres `inet_accept`, `inet_sendmsg`
## Objets du noyau
Le code source de *Linux* est écrit en C orienté objets (`structs`) :
```c
// fichier
struct file * f
// répertoire
struct dentry * d
// socket
struct socket * s
// répertoire ouvert
struct dir_context * d
// inode
struct inode * i
// buffer réseau
struct sk_buf * n
```
Toutes ces structures peuvent pointer les unes les autres, voir se contenir (il
est possible de trouver les conteneurs avec `container_of`).
[^bugs]: On parle bien ici en proportion du nombre de lignes de code