Що таке vdso та vsyscall?


89

я зробив sudo cat /proc/1/maps -vv

Я намагаюся зрозуміти вихідні дані. Я бачу, як багато спільних бібліотек відображаються в сегменті відображення пам'яті, як очікувалося.

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

Під кінець є щось на зразок

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]

Що означає vdsoі vsyscallозначає? vsyscall є частиною пам'яті ядра? Було б чудово, якщо хтось зможе пролити світло на цю проблему.


5
Google для VDSO надає цю вікі-сторінку VDSO (що містить додаткові посилання).
Василь Старинкевич

procfs , ознайомтесь із версією цього файлу ядра, щоб дізнатися про особливості вашої системи.
бездумний шум

Я думаю, краще пояснення, що для цієї теми потрібно те, що можна знайти у вікі або в документації procfs.
Джузеппе Пес

Відповіді:


150

У vsyscall і vDSO сегменти два механізми , які використовуються для прискорення деяких системних викликів в Linux. Наприклад, gettimeofdayзазвичай викликається за допомогою цього механізму. Першим введеним механізмом був vsyscall , який був доданий як спосіб виконання конкретних системних викликів, для запуску яких не потрібен реальний рівень привілеїв, щоб зменшити накладні витрати на системний виклик. Наслідуючи попередній приклад, gettimeofdayпотрібно лише прочитати поточний час ядра. Є програми, які gettimeofdayчасто дзвонять (наприклад, для генерації міток часу), аж до того, що вони дбають навіть про невеликі накладні витрати. Щоб вирішити цю проблему, ядро ​​відображає в просторі користувача сторінку, що містить поточний час і швидкийgettimeofdayреалізація (тобто просто функція, яка зчитує час, збережений у vsyscall ). Використовуючи цей віртуальний системний виклик, бібліотека C може забезпечити швидкий, gettimeofdayякий не має накладних витрат, введених контекстним перемикачем між простором ядра та простором користувача, як правило, введеним класичною моделлю системних викликів INT 0x80або SYSCALL.

Однак цей механізм vsyscall має деякі обмеження: виділена пам'ять мала і дозволяє лише 4 системних виклики, і, що більш важливо і серйозно, сторінка vsyscall статично виділяється за однією адресою в кожному процесі, оскільки розташування сторінки vsyscall є прибито в ядро ​​ABI. Це статичне розподіл vsyscall компрометує переваги, введені рандомізацією простору пам'яті, яка зазвичай використовується Linux. Зловмисник після компрометації програми, використовуючи переповнення стека, може викликати системний виклик із vsyscallсторінка з довільними параметрами. Все, що йому потрібно, - це адреса системного виклику, яку легко передбачити, оскільки вона виділена статично (якщо ви спробуєте знову запустити свою команду навіть з різними програмами, ви помітите, що адреса vsyscall не змінюється). Було б непогано видалити або принаймні рандомізувати розташування сторінки vsyscall, щоб зірвати такий тип атаки. На жаль, програми залежать від існування та точної адреси цієї сторінки, тому нічого не можна зробити.

Цю проблему безпеки вирішено шляхом заміни всіх інструкцій системного дзвінка за фіксованими адресами спеціальною інструкцією пастки. Додаток, який намагається зателефонувати на сторінку vsyscall , потрапить у ядро, яке потім буде емулювати бажаний віртуальний системний виклик у просторі ядра. Результат - системний виклик ядра, який емулює віртуальний системний виклик, який був поміщений туди, щоб уникнути системного виклику ядра. Результатом є vyscall, який виконується довше, але, що найважливіше, не порушує існуючий ABI. У будь-якому випадку, уповільнення буде видно лише в тому випадку, якщо програма намагається використовувати сторінку vsyscall замість vDSO .

VDSO пропонує ту ж функцію, що і vsyscall, долаючи свої обмеження. VDSO (віртуальні динамічно пов'язані спільні об'єкти) - це область пам'яті, виділена в просторі користувача, яка безпечно надає деякі функціональні можливості ядра в просторі користувача. Це було введено для вирішення загроз безпеці, викликаних vsyscall. VDSO динамічно розподіляється, що вирішує проблеми безпеки і може мати більше 4 системних викликів. Посилання vDSO надаються через бібліотеку glibc. Посилання зв'язуватиметься у функціональності glibc vDSO , за умови, що така процедура має супровідну версію vDSO , таку як gettimeofday. Коли ваша програма виконується, якщо у вашому ядрі немає vDSO підтримка, буде зроблений традиційний системний виклик.

Подяки та корисні посилання:


3
Чому vsyscall може мати лише 4 системні дзвінки? Для системних дзвінків зарезервовано 8 мегабайт, і використовується лише 1 сторінка (насправді 3 функції, вирівняні до 1024, займають 1 сторінку).
скап

9

Я просто хочу додати, що тепер у нових ядрах vDSOвикористовується не тільки для "безпечних" системних викликів, але він використовується для вирішення, який механізм syscall є найкращим методом для виклику syscall в системі.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.