Отладка программы setuid / Отказано в доступе с setuid

На самом деле это вопрос из трех частей, который я объясню ниже, но вопросы таковы:

  • Как с помощью gdb запустить часть программы с root-правами, а остальные с обычными?
  • Почему я получаю «отказ в доступе» с помощью mkstemp для создания файла в /tmp в программе setuid (для root)?
  • Почему «sudo имя_программы» будет работать иначе, чем просто ./имя_программы с setuid для root?

У меня есть программа C, работающая в Linux (несколько дистрибутивов), которая обычно запускается пользователем с обычными привилегиями, но некоторые части программы должны запускаться с правами root. Для этого я использовал флаг set-UID, и он прекрасно работает.

Однако теперь я хотел бы отладить программу с правами обычного пользователя, и обнаружил, что у меня есть уловка-22. Я только что добавил функцию для создания временного файла (/tmp/my_name-XXXXXX), и эта функция вызывается из многих точек программы. По какой-то причине эта функция выдает следующее сообщение при запуске:

sh: /tmp/my_name-hhnNuM: Permission denied

(конечно, фактическое имя может быть разным.) И тем не менее, программа может выполнять необработанные функции сокета, которые, как я точно знаю, не могут быть выполнены другими пользователями, кроме root. (Если я удалю флаг setuid, программа с треском провалится.)

Если я запускаю эту программу через gdb без sudo, она умирает из-за необработанных сокетов (поскольку gdb, по-видимому, не - или, вероятно, не может - учитывать флаг setuid в программе). Если я запускаю его под «sudo gdb», то все работает нормально. Если я запускаю его как «sudo ./my_name, все работает нормально.

Вот вывод ls -l для этой программы:

-rwsr-xr-x 1 root root 48222 Jun 23 08:14 my_name

Итак, мои вопросы в произвольном порядке:

  • (Как) я могу запускать разные части программы с разными эффективными UID в gdb?
  • Почему «sudo ./program» отличается от «./program», если ./program имеет root-uid?
  • Почему mkstemp не работает при вызове обычным пользователем в программе setuid (для root)?

person Dennis    schedule 23.06.2012    source источник


Ответы (1)


1 Единственный способ правильно отладить приложение setuid в gdb — запустить gdb от имени пользователя root. Самый разумный способ сделать это для setuid-приложения — подключиться к приложению после его запуска. Быстрый способ сделать это — добавить строку в приложение setuid:

kill(getpid(), SIGSTOP);

Это приводит к тому, что он останавливается в этот момент, затем вы подключаете gdb, используя:

sudo gdb <application> <pid>

Затем вы присоединяетесь к приложению и можете отлаживать его как обычно.

2 sudo меняет правила, поскольку позволяет экспортировать различные элементы из среды текущего пользователя в среду пользователя root. Это полностью зависит от текущей конфигурации sudo и может оставить вас в совершенно другой среде, чем приложение setuid, поэтому вам нужно полагаться на такие приемы, как остановка приложения и последующее подключение к нему во время выполнения.

Кроме того, в приложении может быть логика для определения того, работает ли оно в среде setuid, что на самом деле не так при запуске под sudo — помните, что sudo устанавливает для всех полей идентификатора процесса (реальный uid, эффективный uid и сохраненный uid) одно и то же. значение, которого нет в setuid (настоящим uid по-прежнему является идентификатор исходного вызывающего объекта). Вы можете использовать getresuid(). вызов для определения состояния трех переменных.

3 Дело в том, что сообщение Permission Denied имеет префикс sh:; похоже, это означает, что выполняется другой подпроцесс, который пытается получить доступ к файлу. После того, как вы вызвали mkstemp, вы можете захотеть ослабить разрешение на чтение файла, чтобы подпроцесс мог прочитать файл.

person Petesh    schedule 23.06.2012
comment
Чудесно! mkstemp() использовался для создания сообщения электронной почты, а затем sendmail должен был прочитать файл и отправить его. Мне и в голову не приходило, что процесс sendmail, конечно же, не принял полномочия своего родителя. (На платформе, для которой я обычно программирую: AS/400 / iSeries / System i, такое внедрение естественно. Это мое оправдание, и я его придерживаюсь!) Спасибо! И спасибо за напоминание о том, как отладить запущенный процесс! - person Dennis; 24.06.2012