Есть ли разница между использованием setuid () / setgid () внутри программы и вызовом его с помощью sudo -u xxx -g xxx?

Рассмотрим этот скрипт python, который вызывает HandBrakeCLI, программу, которая пытается прочитать с диска dvd:

invoke.py

#!/usr/bin/python

import sys
import os
import subprocess as subp
import pprint

#immediately switch users
os.setgid(1002) #gid of "media"
os.setuid(1005) #uid of "jack"

#verify the switch worked
print os.getuid(), os.geteuid()
print os.getgid(), os.getegid()

#clear up any possible env var diffs
os.environ['USER'] = 'jack'
os.environ['USERNAME'] = 'jack'
os.environ['LOGNAME'] = 'jack'

#output env variables to see if there's anything different:
ff = open('env_%s.log' % sys.argv[1], 'w')
ff.write(pprint.pformat(dict(os.environ)))
ff.write("\n")
ff.close()

#call the program
p = subp.Popen(["HandBrakeCLI", "-i", "/dev/sr0", "-t", "0"])
p.communicate()

sys.exit(p.returncode)

Следующий («A») преуспевает:

sudo -u jack -g media HandBrakeCLI -i /dev/sr0 -t 0

, как и это («B»):

sudo -u jack -g media ./invoke.py jack

, но это («C») терпит неудачу:

sudo ./invoke.py root

и печатает ошибки, указывающие на то, что HandBrakeCLI не смог получить доступ к компакт-диску. Операторы печати подтверждают, что UID / GID были успешно изменены на носитель: media. Если я удалю setuid / setgid и вызову HandBrakeCLI из invoke.py как root, он снова будет работать.

. Разница показывает, что среды по существу одинаковы:

$ diff env_root.log env_jack.log
8c8
<  'SUDO_COMMAND': './invoke.py root',
---
>  'SUDO_COMMAND': './invoke.py jack',

После вызывая setuid и setgid, есть ли «память» исходного вызывающего пользователя? Если нет, что может быть HandBrake, возможно, различаться между «B» и «C»?

Я запускаю 10.04 на безголовом сервере, к которому я обращаюсь через ssh.

2
задан 2 January 2012 в 08:08

1 ответ

Это действительно имеет значение, поскольку можно определить, были ли привилегии подняты (suid case), который отличается от прогона через sudo. Это потому, что весь процесс работает как «jack» в случае sudo (и никогда не возвращает uid: процесс просто завершается), тогда как suid case «запоминает» исходный uid и изменяется только эффективный uid.

Ваша ситуация немного отличается, но вот тестовый скрипт, который определяет каждую комбинацию sudo / suid: test_privs.sh Аналогичный код теперь используется на сервере X11 для обнаружения повышенных привилегий: обсуждение xorg-devel

[d4 ] Я не смотрел ваши конкретные потребности в устройстве / ручном тормозе, но это должно поставить вас на правильный путь.

2
ответ дан 25 May 2018 в 15:31
  • 1
    Спасибо, это полезно. Мой собственный тестовый скрипт сообщает, что реальные / эффективные gid / uid одинаковы; и "getresuid" тест в вашем примере не работает. Я предполагаю, что Ubuntu не поддерживает его. Единственное, что я могу догадаться, это другое (основанное на вашем примере) - результат issetuid (). Я вообще не могу найти документацию по этому поводу. Какие последствия он может иметь при разрешении / программном поведении? Как я могу очистить его, чтобы увидеть, если это моя проблема? Является ли это безопасным? Если нет, как правильно отказаться от привилегий root? – trbabb 12 January 2012 в 06:29
  • 2
    Насколько я знаю, вы не можете сбросить issetuid (). Если ваш двоичный файл является suid-root, я считаю, что этот флаг будет установлен до его завершения. – totaam 12 January 2012 в 12:47

Другие вопросы по тегам:

Похожие вопросы: