169 views
owned this note
# TD Virtualisation
## 1. Catégorisation d'hyperviseurs
> 1.1 Pour chaque type de virtualisation du CPU et de virtualisation mémoire présent sur le tableau ci-dessous, préciser quel composant est en charge du basculement VM/hyperviseur (OS, hyperviseur, CPU réel ?)
Full virtu / binary translation : Hyperviseur (catch les fautes que le CPU retourne), décode les instructions qui arrivent de la VM.
Full virtu / virtu matérielle : le CPU physique
Para virtualisation: VM : OS virtualisé qui est modifié: Utilisation d'hypercall
Shadow Page Tables : Logiciel : c'est le VMM qui s'en occupe
Nested Page Tables (ou Extended PT) : CPU -> nested CR3
cf https://notes.ar-lacroix.fr/s/cOhd9uNfx#Shadow-Page-Tables
> 1.2 Ranger les hyperviseurs par catégorie: type 1/type 2:
| Nom | Type | Binary translation | Virt matérielle | Para-virt | SPT | NPT/SPT |
| :---:| :---:| :---------------: | :-------------: | :-------: | :---: | :-----: |
| utilise : | | VMM | proc CPU | OS |logiciel|CPU NCR3|
| Ramooflax | 1 | | x | | | x |
| VMware ESXi| 1 | x | x | | (x) | x |
| KVM | 1 | | x | | x | x |
| Xen | 1 | | x | x | x | x |
| ACRN (IoT)| 1 | | x | | | x |
| Hyper-V | 1 | | x | | | x |
| VMware workstation| 2 | x | x | | x | x |
| VirtualBox| 2 | x | x | | x | x |
:::info
**VMM** = Virtual Machine Monitor
**Full Virtualisation** = Binary translation OU Virt matérielle
- On a une VM qui ne sait pas qu'elle est virtualisée
[ACRN](https://projectacrn.github.io/latest/introduction/index.html): IoT
:::
## 2. La virtualisation matérielle pas à pas
> 2.1 Rappeler quelle instruction x86 Intel VT-x permet d'activer la virtualisation matérielle. Dans quel mode sera alors le CPU ?
`VMXON`, le CPU sera alors en mode virtualisé (ne pas oublier avant de positionner le flag de contrôle CR4)
```c
({ulong_t cr4 = get_cr4(); set_cr4(cr4|0x2000UL);}) ⇒ positionne des flags de contrôle
```
:::warning
*NB : VMLAUNCH c’est pour lancer une VM*
:::
> 2.2 Une fois activé, l'hyperviseur va remplir pas à pas les champs de la [VMCS](#VMCS-Virtual-Machine-Control-Structure). A partir de quoi sont initialisés les champs de la zone Host de la VMCS ?
Les valeurs sont lues directement à partir du CPU courant, vu que ces champ renseignent sur le contexte d’exécution du VMM.
> 2.3 Suposons que l'adresse du point d'entrée de la VM soit à 0x000600. Dans quel champ de la VMCS doit-on renseigner le point d'entrée ?
Dans le champ rip de la partie guest de la VMCS.
Une fois qu'on aura démaré la VM on prendra cette valeur pour la charger dans le CPU.
```c
guest.rip = VM_ENTRY_POINT
```
> 2.4 On suppose ensuite que les champs cs, ss et ds de la zone guest de la VMCS sont intialisés de la manière suivante:
>> vm_state.cs.attributes.rax = VMX_CODE_1_RO_CO_ATTR;
>> vm_state.cs.attributes.rax = VMX_CODE_1_RO_ATTR;
>> vm_state.cs.attributes.rax = VMX_CODE_1_R3_ATTR;
Dans quel mode va ainsi démarre la VM ? Avec quel niveau de privilège ?
Réponse : on commence en mode réel, la VM passera ensuite en mode protégé
Pas de notions de privilèges en mode réel, c'était une question piège !
> 2.5 Une fois tous les champsde la VMCS iniatilisés, l'hyperviseur va pouvoir passer la main à la VM et la laisser s'éxecuter. Quel instruction VT-X le permet ? Dans quel mode sera alors le CPU?
```VMLAUNCH```
Le CPU sera en mode virtualisé (VMX_NON_ROOT) mais la VM croira qu'elle est en mode réel.
> 2.6 Une des premières choses que la VM va vouloir faire est de configurer sa propre GDT. Pour cela, elle va notamment vouloir accéder à une nouvelle zone mémoire puis exécuter l'instruction LGDT. Que va t-il se passer ?
Elle va exécuter une instruction privilégié donc cette instruction va être capturée par le VMM après avoir levé une exception. Le VMM va alors créer une GDT virtuelle dans la VMCS.
> 2.7 Plus tard, la VM tente d'effectuer l'instruction `mov CR0, eax` (écriture de CR0) depuis une de ses tâches utilisatrices. Que devrait-il se passer si la VM s'exécutait sur une machine physique ?
L'écriture de CR0 est une instruction sensible vu qu'on touche au registre de contrôle, on devrait lever une #GP.
> 2.8 Il se trouve que notre hyperviseur met simplement à jour le cr0 de la région guest de la VMS de la manière suivante:
> ```c
> mov_cro_handler (val) {
> vm_state.cr0.attributes.raw = val;
> }
> ```
> Que manque-t-il à ce handler pour être conforme à un CPU Physique ? En quoi cela pourrait être problématique en termes de sécurité ?
Dans la vraie vie : GP car on est en ring 3 et on veut exécuter une instruction de ring 0.
On ne check pas :
- valeur d'entrée
- si on est en ring 0
Augmente la surface d'attaque, élévation de privilèges locale (dans la VM).
> 2.9 Comment se passe le retour à l'exécution de la VM, une fois l'instruction sensible traitée.
```VM_RESUME``` (qui génère un event de type VM_Entry): (equivalent du iret pour une interruption), on rend la main à la VM
## Etude du fonctionnement de snapshot de VM
### Sauvegarde de la mémoire de la VM
#### Méthode "ctrl-c / ctrl-v"
> Une première méthode, qu'on appellera ici "ctrl-c / ctrl-v", consiste à allouer un nouveau blob de mémoire physique pour y copier l'état de la RAM au moment du snapshot avant de porusuivre l'éxécution de la VM.
> 3.1.1.1 Qu'est ce que cela signifie concrétement, au niveau de la system RAM ?
## Annexes
### VMCS: Virtual Machine Control Structure
Ce sont les metadonnées associées à chaque VM (voir diapo 20 et suivantes du cours)
- Guest-state area (état CPU sauvé lors du VM_EXIT, chargé lors du VM_ENTRY)
- Host-state area (état CPU à charger au moment du VM_EXIT)
- VM-execution control fields (information de cause de VM_EXIT)
- VM-exit control fields (nature des données du host à recharger lors du VM_EXIT)
- VM-entry control fields (ce qui doit être chargé dans le CPU)
- VM-exit information fields
Une région VMCS par VM, modifiable par les instructions ```VMCLEAR```, ```VMPTRLD``` (Load Pointer to Virtual-Machine Control Structure), ```VMREAD```, ```VMWRITE```
