---
# System prepended metadata

title: NSE- 1
tags: [' moemoea.fierin', NSE1]

---

---
title: NSE- 1
tags: NSE1, moemoea.fierin
date: 19/10/2020
cours: 1
---

# <span style="color: red">Syscall</span>

:::info
**Memoire**

| kernel |<--
|   ..   |  | syscall 
|  code  | _|

:::

++**Un syscall c'est quoi?**++
- **API exposée par le kernel**
- **Dans ma memoire:**
    - en haut un mapping kernel
    - plus bas, code
    - qu'est-ce qui m'empêche de call? car interdit aux users et puisque 0 protection si on fait ça
- **Comment fonctionne la protection depuis le code où je ne peux pas appeler le Kernel ?**
    - param au niveau des pages ("ring" askip)
    - Histoire de ring 0(kernel) à 3(code/user)
- **Du coup, le call qu'on fait**
    - int $0x80 : pour une interuption logicielle, elles sont mappées sur une table d'interuption et celle-ci dit où appeler. syscall(2) eax SYS_NR. 
        - cette strat est lente asf
        - va avec une autre fonction (iret)
        - iret, ça fait la même chose que syscall/sysret mais avec une valeur en plus (nom du segment, les iflags, adr piles, ..)
    - syscall (amd) / sysret : ils ont besoin de plus de registres
        - ils utilisent des registres comparé 
    - sysenter (intel) / sysexit : même chose
- **Comment on fait pour avoir un truc intelligent ?**
    - pour régler ça, on peut utiliser VDSO (Virtual Dynamic Shared Object)
- **Comment marche les distrib linux:**
    - je veux du x86 (sur intel ou amd)
    - pour appeler tjrs la plus rapide, si je suis sur x86, j'appelle ca sinon ça ...=> nope 
    - autre methode: mon kernel va mappé une zone memoire (VDSO) en RO et il met du code dedans avec une fonction qui s'appelle "vsyscall"
    - la libc appelle vsyscall et elle va faire le travail de quelle version on va appeler. Libc plus de problème pour savoir qui elle appelle.
    - en plus du vsyscall on ajoute une page de DATA en RO avec l'heure (le kernel écrira l'heure dedans) comme ça on gratte un syscall pour que l'utilisateur sache l'heure plutôt que de changer de contexte. En effet les fonctions graphiques appelle souvent gettimeofday(2) et c'est couteux, c'est pk on a ça.
    - comment faire pour etre RO en user et RW en kernel ?
        - ou sont les droits user et les droits kernel ? y'a qu'un seul set de droit, le kernel va passer RW, écrit l'heure et puis repasser RO.

Syscall registre:
RAX
RDI
RBI
RDX
R10 RCX
R8
R9
ROI


--PARENTHÈSE MSR--
- c'est un registre
- MSR = Machine Specific Register
- crX : registres de contrôle sur x86 (intel) du CPU (exemple: cr1, cr2, cr3)
- idée des MSR : on a 2 instructions qui prennent le num de la MSR pour connaître le jeu d'instruction. On a des MSR specifiques pour tel ou tel addr

--PARENTHESE FIN MSR--

ssize_t write(int fd, const void *buf, size_t sz);
Si on pointe vers une page non mappée, on se prend un PageFault


Si on deref sur une zone non-mappée -> segV master
il va falloir être plus malin que ça: **dès que j'ai un pointeur comme ça, je fais quoi :**
- est ce qu'il est mappé (au bon endroit)
- est-ce qu'il a les bons droits
- est-ce qu'il a une taille correcte

**comment on check tout ça du coup?** 
- on regarde le ring dans la page -> ca a l'air lourd comme check : obligé de parcourir toute ma mémoire pour check chaque page (c'est lent)
    - surtout que les cas ou le check va rater est rare donc le check ne sera utile que très rarement.
    - On rajoute un qualifier pour dire que c'est --user

tant pis on va pas faire le check a priori et le faire uniquement a posteriori.
-   au pire on aura un pagefault
-   on va du coup check si je suis dans un copy-from-user puis on va retourne l'erreur (?)

--PARENTHESE SPARSE--
c'est un compilateur C frontend pour check la semantique des program C et vérifier que le user ne deref jamais ses pointeurs. :ok_hand: 

PARENTHESE COPY-FROM-USER
copy un block de data depuis le user-space

```
unsigned long __copy_from_user (void * to, const void __user * from, unsigned long n);
```

qu'est ce qu'on fait avec les section quand on link - on les concatenes 
- on peut parcourir le tableau de data generer avec cette section la et retrouver si j'ai la bonne addresse de trame

TLB => cache pour les entrees des page table / on recup pour tel addr virt l'addr phy qui lui correspond

