Czym są vdso i vsyscall?

Zrobiłem sudo cat /proc/1/maps -vv

Staram się zrozumieć wyjście.Widzę, że wiele bibliotek współdzielonych jest mapowanych do segmentu mapowania pamięci zgodnie z oczekiwaniami.

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

Pod koniec jest coś takiego

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]

Co oznacza vdso i vsyscall? czy vsyscall jest częścią pamięci jądra? Byłoby wspaniale, gdyby ktoś mógł rzucić trochę światła na ten temat.

Author: VividD, 2013-11-12

2 answers

Segmentyvsyscall ivdso są dwoma mechanizmami używanymi do przyspieszania pewnych wywołań systemowych w Linuksie. Na przykład, gettimeofday jest zwykle wywoływane przez ten mechanizm. Pierwszym wprowadzonym mechanizmem był vsyscall, który został dodany jako sposób wykonywania określonych wywołań systemowych, które nie wymagają żadnego rzeczywistego poziomu uprawnień do uruchomienia w celu zmniejszenia narzutu wywołań systemowych. Idąc za poprzednim przykładem, wszystko gettimeofday musi zrobić, to odczytać bieżące jądro czas. Istnieją aplikacje, które często wywołują gettimeofday (np. w celu wygenerowania znaczników czasu), do tego stopnia, że dbają o nawet odrobinę narzutu. Aby rozwiązać ten problem, jądro mapuje w przestrzeni użytkownika stronę zawierającą bieżący czas i szybką implementację gettimeofday (tzn. funkcję, która odczytuje zaoszczędzony czas w vsyscall). Korzystając z tego wirtualnego wywołania systemowego, biblioteka C może zapewnić szybką gettimeofday , która nie ma narzutu wprowadzanego przez przełącznik kontekstowy między przestrzeń jądra i przestrzeń użytkownika Zwykle wprowadzana przez klasyczny model wywołania systemowego INT 0x80 lub SYSCALL.

Ten mechanizmvsyscall ma jednak pewne ograniczenia: przydzielana pamięć jest mała i umożliwia tylko 4 wywołania systemowe, a co ważniejsze, stronavsyscall jest statycznie przydzielana do tego samego adresu w każdym procesie, ponieważ lokalizacja stronyvsyscall jest przybita w jądrze ABI. Ta statyczna alokacja vsyscall kompromituje korzyść wprowadzona przez randomizację przestrzeni pamięci powszechnie stosowaną przez Linuksa. Atakujący, po narażeniu aplikacji przez wykorzystanie przepełnienia stosu, może wywołać wywołanie systemowe ze strony vsyscall z dowolnymi parametrami. Wszystko, czego potrzebuje, to adres wywołania systemowego, który można łatwo przewidzieć, ponieważ jest przydzielany statycznie (jeśli spróbujesz ponownie uruchomić polecenie nawet z różnymi aplikacjami, zauważysz, że adres vsyscall nie zmiana). Byłoby miło usunąć lub przynajmniej randomizować lokalizację strony vsyscall, aby udaremnić ten rodzaj ataku. Niestety, aplikacje zależą od istnienia i dokładnego adresu tej strony, więc nic nie można zrobić.

Ten problem bezpieczeństwa został rozwiązany poprzez zastąpienie wszystkich instrukcji wywołania systemowego na stałych adresach specjalną instrukcją trap. Aplikacja próbująca wywołać Stronę vsyscall zostanie uwięziona w jądrze, które następnie emuluje pożądane wirtualne wywołanie systemowe w przestrzeni jądra. Rezultatem jest wywołanie systemowe jądra emulujące wirtualne wywołanie systemowe, które zostało tam umieszczone, aby uniknąć wywołania systemowego jądra. Rezultatem jest vsyscall, który trwa dłużej, ale co najważniejsze, nie łamie istniejącego ABI. W każdym razie spowolnienie będzie widoczne tylko wtedy, gdy aplikacja próbuje użyć strony vsyscallzamiast strony vDSO.

vDSO oferuje to samo funkcjonalność jako vsyscall, pokonując jednocześnie jego ograniczenia. VDSO (Virtual dynamicznie linked Shared Objects) jest obszarem pamięci przydzielonym w przestrzeni użytkownika, który w bezpieczny sposób eksponuje niektóre funkcje jądra w przestrzeni użytkownika. Zostało to wprowadzone w celu rozwiązania zagrożeń bezpieczeństwa spowodowanych przez vsyscall. Vdso jest przydzielane dynamicznie, co rozwiązuje problemy związane z bezpieczeństwem i może mieć więcej niż 4 wywołania systemowe. Łącza vDSO są dostarczane za pośrednictwem biblioteki glibc. Łącznik połączy w funkcji glibc vdso, pod warunkiem, że taka procedura ma towarzyszącą wersję vdso, taką jak gettimeofday. Gdy twój program zostanie uruchomiony, jeśli twoje jądro nie ma wsparcia vDSO, zostanie wykonany tradycyjny syscall.

Napisy i przydatne linki:

 120
Author: Giuseppe Pes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-20 20:52:37

Chcę tylko dodać, że teraz w nowych jądrach, vDSO nie jest używany tylko do" bezpiecznych " syscalli, ale jest używany do decydowania, który mechanizm syscall jest preferowaną metodą wywoływania syscall w systemie.

 5
Author: shami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-01 15:57:28