Что такое 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 for VDSO предоставляет этот википейдж VDSO (с дополнительными ссылками).
Basile Starynkevitch

документацию по 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, попадет в ловушку ядра, которое затем будет имитировать требуемый виртуальный системный вызов в пространстве ядра. Результатом является системный вызов ядра, имитирующий виртуальный системный вызов, который был помещен туда, чтобы избежать системного вызова ядра в первую очередь. Результатом является вызов vsyscall, выполнение которого занимает больше времени, но, что особенно важно, не нарушает существующий ABI. В любом случае замедление будет видно только в том случае, если приложение пытается использовать страницу vsyscall вместо vDSO .

VDSO предлагает ту же функцию, что и vsyscall, преодолевая свои ограничения. VDSO (виртуальные динамически связанные общие объекты) - это область памяти, выделенная в пользовательском пространстве, которая безопасным образом предоставляет некоторые функции ядра в пользовательском пространстве. Это было введено для устранения угроз безопасности, вызванных доменом vsyscall. VDSO выделяется динамически, что решает проблемы безопасности и может иметь более 4 системных вызовов. В vDSO ссылки предоставляются через библиотеку GLibC. Компоновщик свяжет функциональность glibc vDSO при условии, что такая процедура имеет сопутствующую версию vDSO , например gettimeofday. Когда ваша программа выполняется, если в вашем ядре нет vDSO support, будет выполнен традиционный системный вызов.

Источники и полезные ссылки:


3
Почему у vsyscall может быть только 4 системных вызова? Для системных вызовов зарезервировано 8 мегабайт, и используется только 1 страница (на самом деле 3 функции, выровненные по 1024, занимают 1 страницу).
skap 06

9

Я просто хочу добавить, что теперь в новых ядрах vDSOон не используется только для «безопасных» системных вызовов, но используется для определения того, какой механизм системных вызовов является предпочтительным методом для вызова системного вызова в системе.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.