Что такое vdso и vsyscall?

Я 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 частью ядра памяти? Было бы здорово, если бы кто-нибудь мог пролить свет на этот вопрос.

2 ответов


на vsyscall и vDSO сегменты-это два механизма, используемые для ускорения определенных системных вызовов в Linux. Например, gettimeofday обычно вызывается через этот механизм. Первый введенный механизм был vsyscall, который был добавлен как способ выполнения определенных системных вызовов, которым не нужен реальный уровень привилегий для запуска, чтобы уменьшить накладные расходы системного вызова. Следуя предыдущему примеру, all gettimeofday нужно сделать прочитайте текущее время ядра. Есть приложения, которые называют gettimeofday часто (e.g для генерации временных меток), до такой степени, что они заботятся даже о немного накладных расходах. Чтобы решить эту проблему, ядро отображает в пользовательское пространство страницу, содержащую текущее время и fast gettimeofday реализация (т. е. просто функция, которая считывает время сохраняться в vsyscall). Используя этот вызов виртуальной системы, библиотека C может обеспечить быстрый gettimeofday, который не имеет накладные расходы, вносимые контекстным переключением между пространством ядра и пользовательским пространством, обычно вводимым классической моделью системных вызовов INT 0x80 или SYSCALL.

, это vsyscall механизм имеет некоторые ограничения: выделенная память небольшая и позволяет только 4 системных вызова, и, что более важно и серьезно,vsyscall страница статически выделяется на один и тот же адрес в каждом процессе, так как местоположение vsyscall страница пригвожден к ядру ABI. Это статическое распределение vsyscall компрометирует преимущество, введенное рандомизацией пространства памяти, обычно используемой Linux. Злоумышленник после компрометации приложения с помощью переполнения стека может вызвать системный вызов из vsyscall страницы с произвольными параметрами. Все, что ему нужно, это адрес системного вызова, который легко предсказать, поскольку он статически выделен (если вы попытаетесь снова запустить свою команду даже с разными приложения, вы заметите, что адрес vsyscall не меняется). Было бы неплохо удалить или, по крайней мере, рандомизировать местоположение страницы vsyscall, чтобы предотвратить этот тип атаки. К сожалению, приложения зависят от наличия и точного адреса этой страницы, поэтому ничего нельзя сделать.

эта проблема безопасности была решена путем замены всех инструкций системного вызова по фиксированным адресам специальной инструкцией trap. Приложение, пытающееся вызвать в vsyscall страница попадет в ядро, которое затем эмулирует требуемый вызов виртуальной системы в пространстве ядра. В результате системный вызов ядра эмулирует вызов виртуальной системы, который был помещен туда, чтобы избежать системного вызова ядра в первую очередь. В результате получается vsyscall который занимает больше времени для выполнения, но, что важно, не нарушает существующий ABI. В любом случае замедление будет видно только в том случае, если приложение пытается использовать vsyscall страница вместо vDSO.

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

кредиты и полезные ссылки :


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