Как sigreturn блокирует все сигналы, кроме SIGKILL и SIGSTOP в SECCOMP_SET_MODE_STRICT? - PullRequest
0 голосов
/ 29 ноября 2018

В секции SECCOMP_SET_MODE_STRICT из man 2 seccomp сказано, что:

Обратите внимание, что хотя вызывающий поток больше не может вызывать sigprocmask(2), он может использовать sigreturn (2), чтобы заблокировать все сигналы, кроме SIGKILL и SIGSTOP.

Я не могу понять, как это сделать.sigreturn - это syscall, который

Этот вызов sigreturn () отменяет все, что было сделано - изменение маски сигнала процесса, переключение стеков сигналов (см. Sigaltstack (2)) - для вызоваобработчик сигнала.

Более конкретно:

Используя ранее сохраненную информацию в стеке пользовательского пространства
sigreturn () восстанавливает маску сигнала процесса,переключает стеки и восстанавливает контекст процесса (флаги и регистры процессора, включая указатель стека и указатель инструкций),

Информация сохраняется:

Сохраненный процессконтекстная информация помещается в структуру ucontext_t (см.).Эта структура видна в обработчике сигналов как третий аргумент обработчика, установленного через sigaction (2) с флагом SA_SIGINFO.

Я посчитал это невозможным, потому что следующие 2 причины:

  1. Поскольку действие TERM для сигнала не нужно возвращать в пространство пользователя, нет способа предотвратить dying с помощью atexit или чего-либо подобного.

    2.Хотя можно заполнить ucontext_t с помощью man 2 getcontext или man 3 makecontext , что не поможет процессу заблокировать сигнал, так как всесистемный вызов для установки обработчика и маскирования сигнала отключен (если sigreturn не выполняет сам маску siganl) .

1 Ответ

0 голосов
/ 02 декабря 2018

Да, sigreturn() действительно заставляет ядро ​​изменить маску сигнала для вызывающего потока.

Вот как и почему:

  1. Процесс создаеткадр стека, который выглядит точно так же, как и кадр, который ядро ​​делает, когда обработчик сигнала только что вернулся из доставленного сигнала.

    Этот кадр стека содержит исходную маску сигнала для потока, используемого для доставки сигнала, и адресгде этот поток был прерван доставкой сигнала.(При нормальной работе в текущей активной маске сигналов блокируются дополнительные сигналы; в том числе и доставляемый сигнал.)

    Процесс устанавливает маску сигналов на ту, которую он предпочитает.

  2. Процесс вызывает sigreturn().

    Ядро проверяет кадр стека, замечает старую маску сигнала и восстанавливает ее.Он также очищает кадр стека и возвращает управление обратно в код пользовательского пространства.(Кадр стека содержал адрес следующей команды, которая должна быть выполнена.)

  3. Этот поток продолжает выполнение по адресу, указанному в этом кадре стека, теперь со своей предпочтительной маской сигналаустановлен.

sigreturn() не может быть заблокирован seccomp, потому что это требуется для нормальной работы.(Тем не менее, обратите внимание, что sigreturn() вызов не требуется после доставки сигнала; в определенных пределах процесс пространства пользователя может продолжить выполнение через siglongjmp(). siglongjmp() не является системным вызовом, простофункция пространства пользователя. Это означает, что ядро ​​ограничено таким поведением, если только оно не отличается от поведения POSIX.1.)

Ядро 1 не различает контекст, созданныйсам пользовательский процесс и контекст, созданный ядром в стеке процессов.Поскольку контекст содержит маску сигналов, восстановленную ядром как часть обработки sigreturn(), sigreturn() позволит потоку изменять свою маску сигналов.

Обратите внимание, что SIGKILL и SIGSTOP не являютсязатронут, потому что они являются двумя сигналами, которые применяет ядро.Все остальные сигналы следует рассматривать только как запросы и уведомления, при этом получатель всегда может их блокировать или игнорировать.

1 Если * сигнальные куки или аналогичный стек sigreturnиспользуется метод проверки кадра.

...