Cosa sono vdso e vsyscall?


89

L'ho fatto sudo cat /proc/1/maps -vv

Sto tentando di dare un senso all'output. Posso vedere molte librerie condivise mappate al segmento di mappatura della memoria come previsto.

7f3c00137000-7f3c00179000 r-xp 00000000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00179000-7f3c00379000 ---p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c00379000-7f3c0037a000 r--p 00042000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037a000-7f3c0037b000 rw-p 00043000 08:01 21233923                   /lib/x86_64-linux-gnu/libdbus-1.so.3.5.8
7f3c0037b000-7f3c00383000 r-xp 00000000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00383000-7f3c00583000 ---p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00583000-7f3c00584000 r--p 00008000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00584000-7f3c00585000 rw-p 00009000 08:01 21237216                   /lib/x86_64-linux-gnu/libnih-dbus.so.1.0.0
7f3c00585000-7f3c0059b000 r-xp 00000000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0059b000-7f3c0079b000 ---p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0
7f3c0079b000-7f3c0079c000 r--p 00016000 08:01 21237220                   /lib/x86_64-linux-gnu/libnih.so.1.0.0

Verso la fine c'è qualcosa di simile

7f3c0165b000-7f3c0177e000 rw-p 00000000 00:00 0                          [heap]
7fff97863000-7fff97884000 rw-p 00000000 00:00 0                          [stack]
7fff97945000-7fff97946000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Cosa significa vdsoe cosa vsyscallsignifica? vsyscall è la parte del kernel della memoria? Sarebbe fantastico se qualcuno potesse fare luce sulla questione.


5
Google for VDSO fornisce questa wikipage VDSO (che contiene ulteriori riferimenti).
Basile Starynkevitch

documentazione procfs , guarda la versione del kernel di questo file per le specifiche del tuo sistema.
rumore senza arte

Penso che una spiegazione migliore del fatto che ciò che può essere trovato nel wiki o nella documentazione di procfs sia necessario per questo argomento.
Giuseppe Pes

Risposte:


150

I segmenti vsyscall e vDSO sono due meccanismi utilizzati per accelerare determinate chiamate di sistema in Linux. Ad esempio, di gettimeofdaysolito viene invocato tramite questo meccanismo. Il primo meccanismo introdotto è stato vsyscall , che è stato aggiunto come un modo per eseguire chiamate di sistema specifiche che non richiedono alcun livello reale di privilegio per essere eseguite al fine di ridurre il sovraccarico delle chiamate di sistema. Seguendo l'esempio precedente, tutto ciò che gettimeofdayoccorre fare è leggere l'ora corrente del kernel. Ci sono applicazioni che chiamano gettimeofdayfrequentemente (ad esempio per generare timestamp), al punto che si preoccupano anche di un po 'di overhead. Per risolvere questo problema, il kernel mappa nello spazio utente una pagina contenente l'ora corrente e un file fastgettimeofdayimplementazione (cioè solo una funzione che legge il tempo risparmiato in vsyscall ). Usando questa chiamata di sistema virtuale, la libreria C può fornire un veloce gettimeofdayche non ha l'overhead introdotto dal cambio di contesto tra lo spazio del kernel e lo spazio utente solitamente introdotto dal modello classico della chiamata di sistema INT 0x80o SYSCALL.

Tuttavia, questo meccanismo vsyscall presenta alcune limitazioni: la memoria allocata è piccola e consente solo 4 chiamate di sistema e, cosa più importante e seria, la pagina vsyscall è staticamente allocata allo stesso indirizzo in ogni processo, poiché la posizione della pagina vsyscall è inchiodato nel kernel ABI. Questa allocazione statica della vsyscall compromette il vantaggio introdotto dalla randomizzazione dello spazio di memoria comunemente usata da Linux. Un utente malintenzionato, dopo aver compromesso un'applicazione sfruttando uno stack overflow, può invocare una chiamata di sistema dal vsyscallpagina con parametri arbitrari. Tutto ciò di cui ha bisogno è l'indirizzo della chiamata di sistema, che è facilmente prevedibile in quanto allocato staticamente (se provi a eseguire nuovamente il tuo comando anche con applicazioni diverse, noterai che l'indirizzo della vsyscall non cambia). Sarebbe bello rimuovere o almeno randomizzare la posizione della pagina vsyscall per contrastare questo tipo di attacco. Sfortunatamente, le applicazioni dipendono dall'esistenza e dall'indirizzo esatto di quella pagina, quindi non è possibile fare nulla.

Questo problema di sicurezza è stato risolto sostituendo tutte le istruzioni di chiamata di sistema a indirizzi fissi con un'istruzione trap speciale. Un'applicazione che tenta di chiamare nella pagina vsyscall si intrappolerà nel kernel, che quindi emulerà la chiamata di sistema virtuale desiderata nello spazio kernel. Il risultato è una chiamata di sistema del kernel che emula una chiamata di sistema virtuale che è stata inserita per evitare la chiamata di sistema del kernel in primo luogo. Il risultato è una vsyscall che richiede più tempo per essere eseguita ma, soprattutto, non interrompe l'ABI esistente. In ogni caso, il rallentamento sarà visibile solo se l'applicazione sta tentando di utilizzare la pagina vsyscall invece di vDSO .

Il vDSO offre le stesse funzionalità del vsyscall, superandone i limiti. Il vDSO (Virtual Dynamically linked Shared Objects) è un'area di memoria allocata nello spazio utente che espone alcune funzionalità del kernel nello spazio utente in modo sicuro. Questo è stato introdotto per risolvere le minacce alla sicurezza causate da vsyscall. Il vDSO viene allocato dinamicamente, il che risolve i problemi di sicurezza e può avere più di 4 chiamate di sistema. I collegamenti vDSO vengono forniti tramite la libreria glibc. Il linker si collegherà alla funzionalità glibc vDSO , a condizione che tale routine abbia una versione vDSO di accompagnamento , come gettimeofday. Quando il tuo programma viene eseguito, se il tuo kernel non ha vDSO supporto, verrà eseguita una chiamata di sistema tradizionale.

Crediti e link utili:


3
Perché vsyscall può avere solo 4 chiamate di sistema? Ci sono 8 megabyte riservati alle chiamate di sistema e viene utilizzata solo 1 pagina (in realtà 3 funzioni, allineate da 1024 e 1 pagina).
skap

9

Voglio solo aggiungere che ora nei nuovi kernel, vDSOnon è usato solo per chiamate di sistema "sicure" ma è usato per decidere quale meccanismo di chiamata di sistema è il metodo preferito per invocare una chiamata di sistema sul sistema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.