Ответ 1
сегменты vsyscall и vDSO - это два механизма, используемых для ускорения некоторых системных вызовов в Linux. Например, gettimeofday
обычно вызывается через этот механизм. Первым введенным механизмом был vsyscall, который был добавлен как способ выполнить определенные системные вызовы, для которых не требуется какой-либо реальный уровень привилегий для выполнения, чтобы снизить накладные расходы системного вызова. Следуя предыдущему примеру, все gettimeofday
нужно сделать, это прочитать ядро текущее время. Существуют приложения, которые часто вызывают gettimeofday
(например, для создания временных меток), до такой степени, что им даже немного накладные расходы. Чтобы решить эту проблему, ядро отображает в пространство пользователя страницу, содержащую текущее время и быструю реализацию gettimeofday
(т.е. Просто функцию, которая считывает время, сохраненное в vsyscall). Используя этот виртуальный системный вызов, библиотека C может обеспечить быстрый gettimeofday
, который не имеет накладных расходов, введенных переключателем контекста между пространством ядра и пользовательским пространством, обычно введенным классической моделью системного вызова INT 0x80
или SYSCALL
.
Однако этот механизм vsyscall имеет некоторые ограничения: выделенная память мала и позволяет всего 4 системных вызова, и, что более важно и серьезно, страница vsyscall статически распределяется по одному и тому же адресу в каждом процессе, поскольку местоположение В ядре ABI забивается страница vsyscall. Это статическое распределение vsyscall компрометирует выгоду, которую использует рандомизация пространства памяти, обычно используемая Linux. Злоумышленник после компрометации приложения, используя переполнение стека, может вызывать системный вызов с страницы vsyscall с произвольными параметрами. Все, что ему нужно, это адрес системного вызова, который легко предсказуем, поскольку он статически выделяется (если вы попытаетесь снова запустить свою команду даже в разных приложениях, вы заметите, что адрес vsyscall не изменяется). Было бы неплохо удалить или, по крайней мере, рандомизировать местоположение страницы vsyscall, чтобы помешать такому типу атаки. К сожалению, приложения зависят от существования и точного адреса этой страницы, поэтому ничего нельзя сделать.
Эта проблема безопасности устранена путем замены всех инструкций системного вызова на фиксированные адреса специальной командой trap. Приложение, пытающееся вызвать страницу vsyscall, попадет в ядро, которое затем эмулирует желаемый виртуальный системный вызов в пространстве ядра. Результатом является системный вызов ядра, эмулирующий виртуальный системный вызов, который был поставлен во избежание системного вызова ядра. Результатом является vsyscall, который занимает больше времени для выполнения, но, что важно, не нарушает существующий ABI. В любом случае замедление будет видно только в том случае, если приложение пытается использовать страницу vsyscall вместо vDSO.
vDSO предлагает ту же функциональность, что и vsyscall, преодолевая ее ограничения. Виртуальные динамически связанные общие объекты vDSO - это область памяти, выделенная в пользовательском пространстве, которая безопасно предоставляет некоторые функциональные возможности ядра в пользовательском пространстве.
Это было введено для устранения угроз безопасности, вызванных vsyscall
.
VDSO динамически распределяется, что решает проблемы безопасности и может иметь более 4 системных вызовов. Ссылки vDSO предоставляются через библиотеку glibc. Компонент свяжется в функциональности glibc vDSO, при условии, что такая программа имеет сопутствующую версию vDSO, такую как gettimeofday
. Когда ваша программа выполняется, если ваше ядро не поддерживает vDSO, будет создан традиционный syscall.
Кредиты и полезные ссылки: