В современных Linux x86-64 безопасно ли для пользовательского пространства перезаписывать регистр GS? - PullRequest
2 голосов
/ 07 января 2020

В 64-битной C программе, использующей glib c, pthreads и т. Д. (Ничего exoti c), безопасно ли перезаписывать регистр GS, не восстанавливая его, на текущем ядре и glib c версий? Я знаю, что регистр FS используется pthreads / glib c для указателя на блок локального потока, так что при работе с ним будет разрушено все, что использует TLS, но я не уверен насчет GS

Если нет, безопасно ли сохранить значение, перезаписать его, а затем восстановить значение, если код пользовательской области при перезаписи не выполняет X (что такое X)?

1 Ответ

1 голос
/ 07 января 2020

Не знаю точно; Шут говорит: «Да, но вместо этого вы, вероятно, захотите arch_prctl(ARCH_SET_GS, foo);»

или на процессоре с FSGSBASE, возможно wrgsbase из пространства пользователя, если ядро ​​разрешает что для использования пространства пользователя. (CR4.FSGSBASE[bit 16] должен быть установлен, или он ошибается с #UD).

Я знаю, что x86-64 переключился на использование FS для TLS (32-битный использует GS) из-за того, как точка входа syscall использует swapgs для поиска стека ядра.

Я думаю, что это было просто для согласованности между пользователем и ядром для ядра TLS / на ядро, потому что 32-битные процессы под 64-битным ядром все еще работают используйте GS для TLS. За исключением 32-битных процессов не может использовать syscall (кроме процессоров AMD). Уже одно это не исключает некоторый код, который выполняется только для 64-битного процесса, который может что-то делать с GS, но, вероятно, проблем нет.

swapgs только меняет GS база, а не селектор. Я не знаю, есть ли какие-нибудь точки входа в ядро, которые переписали бы GS с некоторым значением селектора по умолчанию (и затем перезагрузили сохраненную базу GS). Я думаю, нет.

...