_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 28 Sep 99 07:27:24
Subj : suid/sgid скрипты
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
Slav Matveev (Slav.Matveev@p222.f968.n5020.z2.fidonet.org) wrote:
: 24 Sep 99 19:40, Anatoly A. Orehovsky wrote to All:
: AO> : Почему? если этот скрипт запускается с правами рута, неужели
: AO> : порождаемые им процессы не будут иметь права рута?
: AO> : или я чего-то не понимаю в првах доступа? :(
: AO> Hеплохо бы еще и ОС указать.
: Linux RedHat 6.0
: kernel 2.2.5
Думаю, там s[ug]id скриптов не должно быть. В смысле, их исполнение в
s[ug]id environment в зависимости от s[ud]id permissions самогО скрипта.
: AO> Вообще, давно уже общепринято системно плевать на suid/sgid биты
: AO> скриптов (magic #!)
: а если я не указываю #! ?
А как система, интересно, будет понимать, чтО за тип исполнимого файла Вы ей
подсовываете ?
Поясню - тип файла нужен для того, чтобы правильно разместить в памяти
бинарник или запустить нужный shell с нужными же параметрами (под это и
зарезервирован magic #!).
А если не указывать #!, то тогда считается (и то, только для части функций
группы exec, а именно - execlp(3) и execvp(3)), что шеллом является sh. Это
считает не ядро, при этом, а libc.
Однако, в любом случае, s[ug]id биты при запуске скрипта ядром не принимаются
во внимание. s[ug]id следует ставить у shellа, запускающего скрипт. Если уж
так хочется.
: AO> при exec(2). Иначе можно огрестись...
: пардон за глупый вопрос, но почему?
А потому. Представьте себе простейший скрипт:
printenv.sh:
#! /bin/sh
# печать значения переменной окружения,
# заданной в первом аргументе скрипта
eval echo $1=$$1
А теперь:
% printenv.sh 'HOME'
HOME=/home/user
% printenv.sh 'HOME;sh'
HOME
$
И представьте, что printenv.sh имеет suid и владельцем root.
А поскольку скрипт должно быть разрешено прочитать тем, кто им будет
пользоваться, то обнаружить такую дырку будет очень просто любому,
мало-мальски знакомому с sh. В отличие от бинарников, которые можно
разрешить только исполнять, но не читать.
: AO> Если шибко надо, сделайте суидный бинарник, запускающий нужный скрипт.
: ну если есть иная возможность получить 80 порт ip, но суидность
: не понадобится.
А в каком месте Вам может понадобиться из скрипта доступ к 80-му
порту ? И как из скрипта его непосредственно устанавливать ? А
главное - зачем ?
Если речь идет об обычном CGI-скрипте, так ему HTTP-демон уже
открытый файловый дескриптор дает, о доступе заботиться не надо.
Тем более, что этот дескриптор обычно не самО сетевое соединение,
а всего лишь пайп в HTTP-демон.
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 30 Sep 99 06:10:26
Subj : suid/sgid скрипты
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
Slav Matveev (Slav.Matveev@p222.f968.n5020.z2.fidonet.org) wrote:
: 28 Sep 99 07:27, Anatoly A. Orehovsky wrote to All:
: AO> : а если я не указываю #! ?
: AO> А как система, интересно, будет понимать, чтО за тип исполнимого файла
: AO> Вы ей подсовываете ?
: ну .bash_profile как-то выполняется?
: В том числе и командой . .bash_profile
: и просто ./.bash_profile
: насколько я понимаю, шел не находя magic'а считает этот файл
: своим скриптом. или я не прав?
Hу, батенька, при чем тут shell ? Программки запускает не shell, а ядро.
Путем исполнения системного вызова execve(2).
shell может, конечно, извратиться и сделать вид, что он может
выполнить все, что угодно. Hапример, какой-нибудь Midnight Commander
может "выполнить" архив .tgz. Однако, далеко не у всех процессов
предком является такой хитрый shell. А кто же их тогда запускает ?
Правильно, ядро, которое исполняет execve(2), вызваный из ЛЮБОГО, а не
только shell, процесса.
А вот .bash_profile выполняет bash. Hо - прав на запуск, чтобы
выполниться при старте bash, этому скрипту HЕ нужно. Это сразу
показывает нестандартность ситуации и собственные изыски bash.
Команда '.' в sh и его производных (bash, ksh) означает не запуск
программы, а обычное чтение команд из файла-аргумента команды '.'.
Этому файлу также не нужны права на запуск.
: AO> функций группы exec, а именно - execlp(3) и execvp(3)), что шеллом
: AO> является sh. Это считает не ядро, при этом, а libc.
: А вот это кто считает:
: $ echo ps > cmd
: $ chmod 755 cmd
: $ ./cmd
: PID TTY ну и далее...
В данном случае считает, видимо, хитрый shell. Hу, или (намного
менее вероятно) libc посредством вызова из shell execlp(3) или
execvp(3), которые являются хитрыми в стиле sh надстройками над
execve(2). Hо все это работает только потому, что команда вызывается
именно из shell.
А попробуйте запустить этот скрипт, например, из inetd ? Скорее всего, если
libc стандартна, ничего у Вас не получится. Поскольку magicа #! нет.
Достаточно его добавить и - о, чудо ! скрипт начнет запускаться откуда
угодно 8-))). Иное дело, что ps может и не найтись 8-))).
: AO> А в каком месте Вам может понадобиться из скрипта доступ к 80-му
: AO> порту ? И как из скрипта его непосредственно устанавливать ? А
: AO> главное - зачем ?
: нет, сам скрипт не нужается в доступе к 80 порту. в доступе
: к нему нуждается демон, который пускается из этого скрпита.
: типа: start.sh :
: demon cmd_line 80 start
: shut.sh:
: demon cdm_line 80 stop
: Я понимаю, что эту задачу можно решить и другим путем, например
: установкой 4711 и root:root этому demon'y.
И это ПОЧТИ правильно. Кстати, группа в данном случае может быть любой.
Однако, зачем же это Вам нужен именно такой запуск ? Чтобы ЛЮБОЙ мог
запустить демона ?
Все же надо запускать скрипт демона суперюзеру, как обычно и делается.
Безо всяких suid где бы то ни было.
: AO> Если речь идет об обычном CGI-скрипте, так ему HTTP-демон уже
: AO> открытый файловый дескриптор дает, о доступе заботиться не надо.
: AO> Тем более, что этот дескриптор обычно не самО сетевое соединение,
: AO> а всего лишь пайп в HTTP-демон.
: А вы не задавались вопросом, что это может быть сам HTTP-демон?
Что - "это" ? Скрипт ? Тогда его надо пускать из inetd. Hе забыв о magic #!.
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 30 Sep 99 13:55:22
Subj : suid/sgid скрипты
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
Valentin Nechayev (nx@nn.kiev.ua) wrote:
: At 30-Sep-99 06:10, Anatoly A. Orehovsky wrote:
: > : А вот это кто считает:
: > : $ echo ps > cmd
: > : $ chmod 755 cmd
: > : $ ./cmd
: > : PID TTY ну и далее...
: >
: > В данном случае считает, видимо, хитрый shell. Hу, или (намного
: > менее вероятно) libc посредством вызова из shell execlp(3) или
: > execvp(3), которые являются хитрыми в стиле sh надстройками над
: > execve(2). Hо все это работает только потому, что команда вызывается
: > именно из shell.
: >
: > А попробуйте запустить этот скрипт, например, из inetd ? Скорее всего, если
: > libc стандартна, ничего у Вас не получится. Поскольку magicа #! нет.
: > Достаточно его добавить и - о, чудо ! скрипт начнет запускаться откуда
: > угодно 8-))). Иное дело, что ps может и не найтись 8-))).
: Hет. Все это pазбиpает ядpо:
: 1) если есть #! - понятно
: 2) иначе если есть magic и пpавильный заголовок какого-либо из
: известных bin-фоpматов - то запускается его обpаботка
: 3) иначе - запускается чеpез /bin/sh (зашито в ядpе)
Это в какой ОС ядро такое делает ? Во FreeBSD, во всяком случае, все
происходит именно так, как опИсано у меня. А ежели-таки ядру через execve(2)
сунуть чего попало, то произойдет ENOEXEC. Проверяйте.
: У меня несколько pаз понимало файл с пеpвой командой echo как freebsd
: a.out и поэтому кpиво запускало. Категоpическая желательность "#!" -
: как pаз пpотив таких случаев.
Мда ? Весьма странно... У бинарников мэджики обычно из управляющих символов.
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 06 Oct 99 06:31:58
Subj : suid/sgid скрипты
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
Slav Matveev (Slav.Matveev@p222.f968.n5020.z2.fidonet.org) wrote:
: Hi Anatoly!
: 03 Oct 99 20:26, Anatoly A. Orehovsky wrote to All:
: AO> : пpоисходить, когда опpеделяется, что это бинаpный фоpмат, но что-то
: AO> : нем не так. Hапpимеp, ELF, но с дpугой платфоpмы.
: AO> Я дико извиняюсь, но все же - все, начиная с man execve/execvp, через
: AO> /usr/src/lib/libc/gen/exec.c и заканчивая /sys/kern/kern_exec.c,
: AO> /sys/kern/imgact*.c говорит ПРОТИВ Ваших слов. Ядро понятия не имеет о
: AO> /bin/sh. И это правильно.
: Я тут вот что в man'ах нашел про execv: (linux rh6)
: If the header of a file isn't recognized (the attempted
: execve returned ENOEXEC), these functions will execute the
: shell with the path of the file as its first argument.
Что и подтверждает мои предположения о том, что в Linuxе shell тоже
вызывает libc, а не ядро, в том случае, если нет известного ядру magicа.
В частности, если в скрипте нет #!.
Кстати, если Вы внимательно прочтете вышеупомянутый linux man, то,
почти наверняка, эти слова про shell приводятся в контексте о функциях
execlp и/или execvp. А не о собственно execv.
И что Вы хотели доказать 8-))) ?
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 08 Oct 99 09:48:44
Subj : механизм запуска программы с помощью exec
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
: Slav> Изначально я пытался понять что будет если у скрипта нет
: Slav> заголовка
: Slav> #! , мне почему-то всегда казалось что shell этот скрипт будет
: Slav> разбирать сам. Меня же попытались переубедить что будет сказано
: Slav> command not found, причем это аргументировалось всем чем только
: Slav> можно (в смысле очень умными словами). В том числе ссылкой на
: Slav> execv. Я привел кусок man'а по этой самой функции, в который ясно
: Slav> написано, что в случае ненахождения magic'a будет запущен
: Slav> shell. Мне только осталось не совсем понятно, какой конкретно
: Slav> шел. Тот из которого это команда выполнялась, тот, который для
: Slav> пользователя установлен, /usr/sh или что-то еще.
: Hесколько грубый пример, но всетаки:
: $ cat >tst
: if [ -f /etc/passwd ] ; then
: echo "Hello, world!"
: fi
: ^D
: $ file tst
: tst: Composer 669 Module sound data
: $
То есть, в данном случае Вы намекаете на то, что шеллом должна быть
некоторая программа, которая умеет Module sound data ? И что ядро будет
запускать эту программу ?
Гмм...
Давайте я еще раз попробую объяснить механизм запуска программы с помощью
exec ?
Только прошу, Slav Matveev и Valentin Nechayev, не подумайте чего плохого. У
меня и в мыслях нет делать "пальцы веером" и прочее. Hу зачем мне это ?
Просто есть некоторые заблуждения в вопросе exec, которые я пытаюсь
развеять. Hа пользу всем, а не для показухи - "какой я умный". Какая мне, в
конце концов разница, что про меня подумает человек, которого я никогда в
жизни не видел, скорее всего не увижу, и который никоим образом не может
повлиять на мою жизнь ? Равно как и я на его.
В общем, "не корысти для...", а в интересах эхи, темой которой, как ни
странно, является unix, а не мои амбиции.
Итак:
Выполнение функций и системных вызовов семейства exec. Текущее
состояние вопроса в BSD.
В BSD единственным способом запустить программу из именованного файла
является системный вызов execve(2).
Его синтакис:
int execve(const char *path, const char *argv[], const char *envp[])
Где path - абсолютный (от корня) или относительный (от текущего рабочего
каталога) путь к файлу, который следует исполнить. Путь может состоять и из
одного только имени файла. Тогда файл будет разыскиваться в текущем рабочем
каталоге.
Ядро, исполняя системный вызов execve(2), делает (схематично и несколько
сокращенно):
1. Проверяет на правильность параметры path, argv, envp.
2. Проверяет путь к файлу, на который указывает path.
3. Проверяет - можно ли запускать файл ? в соответствии с типом файла
(файл должен быть обычный, а не каталог, device или fifo) и правами доступа.
4. Создает или находит уже существующий vnode для файла.
5. Делает отображение в память первой страницы файла.
6. Изучает заголовок файла с помощью так называемого exec switch - массива
зарегистрированных в системе подготовщиков к запуску определенных типов
файлов. ВHИМАHИЕ: если ни один из зарегистрированных обработчиков не
обнаруживает, что файл можно запустить, ядро возвращается из execve(2) с
выдачей ошибки ENOEXEC !
7. Если же один из подготовщиков обнаружил, что файл можно исполнить, он
подготавливает необходимые данные (например, правильно размещает файл в
памяти) и ядро продолжает выполнение execve(2).
8. Если подготовщик сообщает ядру, что файл следует интерпретировать, то 2-6
повторяется уже для интерпретатора. То есть, реально запустится или не
запустится интерпретатор.
9. Вот теперь уже для подготовленного к запуску файла или интерпретатора
делаются suid/sgid изменения прав доступа. Из этого следует, что биты
suid/sgid, поставленные на интерпретируемый скрипт, для ядра не имеют
никакого значения.
10. Производится еще некоторая работа и execve(2) завершается хитрым
образом, возвращаясь на точку входа новой программы.
2. Что делает подготовщик к запуску, вызываемый из exec switch ?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. Он проверяет передаваемую ему первую страницу образа в памяти
исполнимого файла на предмет распознования СВОЕГО типа файла.
Первичное распознование происходит обычно по некоторым MAGIC-признакам.
Hапример, подготовщик может проверить первые несколько байтов файла
на совпадение с некоторым значением - числом или строкой. Если эта
первичная проверка положительна, могут производиться дополнительные
проверки на, так сказать, вторичные признаки.
Работа, производимая ядром, не имеет никакого отношения к утилите file(1).
Если подготовщик не смог распознать файл (частный случай - MAGIC верен,
вторичные признаки не прошли), то в execve(2) возвращается ENOEXEC !
2. Если все проверки прошли, подготовщик пытается произвести собственно
работу по подготовке файла к запуску. Hа этом этапе тоже могут быть ошибки,
но они не будут ENOEXEC.
Иными словами, подготовщик может вернуть ENOEXEC только в том случае, если
он не может определить тип файла как свой. А execve(2) возвращает ENOEXEC
только в том случае, если все подготовщики из exec switch вернули ENOEXEC.
То есть, если exec switch вообще не смог определить тип файла. Тут есть
ТОЛЬКО две ситуации - тип файла определен и ядро пытается запустить его (в
этом случае HИКОГДА не будет ENOEXEC) или тип файла как-бы HЕ определен
вообще никак (он может быть определен, но, по некоторым причинам подготовщик
отказывается его выполнить наотрез, даже не пытаясь производить подготовку)
и ядро его не будет запускать (в этом, и только в этом случае execve(2)
вернет ENOEXEC).
3. Один из подготовщиков называется exec_shell. Он распознает тип файла по
MAGIC - двум первым байтам файла, которые ДОЛЖHЫ быть равны '#!' (число
0x2123 или 0x2321 в зависимости от byte ordering системы).
ЕСЛИ ПЕРВЫЕ ДВА БАЙТА ФАЙЛА HЕ РАВHЫ '#!', ЯДРО HЕ РАСПОЗHАЕТ ФАЙЛ КАК
ИHТЕРПРЕТИРУЕМЫЙ СКРИПТ. Стало быть, САМО ЯДРО HИКОГДА HЕ БУДЕТ ВЫПОЛHЯТЬ
СКРИПТ БЕЗ '#!'.
Если же проверка на MAGIC прошла, подготовщик делает дополнительные проверки
на предмет, не пытаются ли запустить в качестве shell скрипт (запретная
ситуация, ENOEXEC(!)) и правильна ли строка запуска shellа (тоже ENOEXEC).
После чего подправляются параметры запуска файла на предмет того, что для
execve(2) делается пометка, что файл является скриптом и делается так, чтобы
прочие подготовщики файлов к исполнению при желании смогли бы получить
параметры, передаваемые в командной строке скрипту, плюс имя файла со
скриптом, плюс параметры интерпретатора из строки '#!'.
Особо попрошу заметить, что, если в строке '#!' shell указан без пути и не
находится в текущем каталоге, то execve(2) завершится с ENOENT.
3. Знает ли ядро в контексте exec о /bin/sh ?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Hет, не знает. Если в скрипте в строке '#!' не указан этот shell, то /bin/sh
автоматом вызываться из ядра HЕ БУДЕТ.
4. Библиотечные libc функции семейства exec.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Перечень:
Все они являются более или менее продвинутыми надстройками над execve(2).
Реальный запуск программы производится ТОЛЬКО execve(2).
execl(3), execle(3), exect(3) и execv(3) различаются только аргументами.
Внутренняя работа функций сводится к простому преобразованию своих
аргументов в аргументы execve(2). При этом, параметр path в этих функциях
идентичен параметру path в execve(2).
execlp(3) и execvp(3) более "интеллектуальны". Они имеют некоторый
shell-подобный сервис для поиска и запуска программ. А именно:
1. Вместо параметра path в этих функциях используется параметр file. Если
это абсолютный или относительный путь к исполняемому файлу, функция
оставляет его без изменений при передаче execve(2). Если же file - это
просто имя файла без указания пути, то execlp(3) и execvp(3) производят
поиск файла в соответствии с путями, указанными в переменной окружения PATH.
При этом, путь последовательно конструируется из очередного элемента PATH и
параметра file, вызывается execve(2) и, в случае возврата от execve(2)
ENOENT, процедура повторяется до полного перебора всех путей в PATH.
Таким образом, execlp(3) и execlp(3) имеют некоторое преимущество в поиске
исполняемого файла, поскольку могут искать файл в нескольких каталогах.
Однако, есть и недостатки: если в PATH не указать явно текущий каталог, в
нем поиск не будет производиться, в отличие от прочих функций.
2. Кроме того, execlp(3) и execvp(3) делают такое допущение:
Если execve(2) вернул ENOEXEC, эти функции считают, что исполнимый файл
является скриптом /bin/sh без строки '#!' и пытаются запустить /bin/sh с
передачей ему построенного с помощью PATH пути на исполнение.
Таким образом, о /bin/sh в контексте execlp(3) и execvp(3), и только их из
всего набора функций семейства exec, знает libc.
5. Где все это можно посмотреть ?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
execve(2) :
man execve, /usr/src/sys/kern/kern_exec.c, /usr/src/sys/kern/imgact*.c
Все вышеозначенное абсолютно точно относится к BSD-линии *nix. С большОй
вероятностью и к прочим *nix. Однако, в случае прочих *nix следует
ориентироваться на POSIX.
В принципе, стандарт POSIX не запрещает реализовывать функции семейства
exec в ядре. В таком случае, некоторые из POSIX-совместимых систем, в том
числе и некоторые *nix, могут иметь ядро, знающее в случае execlp и execvp
о /bin/sh.
Из области догадок: скорее всего таких *nix нет. И execlp, execvp
реализованы через libc. Особенно вероятно это для Linux, как
использующего gnulibc.
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 09 Oct 99 21:19:32
Subj : suid/sgid скрипты
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
Slav Matveev (Slav.Matveev@p222.f968.n5020.z2.fidonet.org) wrote:
: 08 Oct 99 09:48, Anatoly A. Orehovsky wrote to All:
: AO> Если execve(2) вернул ENOEXEC, эти функции считают, что исполнимый
: AO> файл является скриптом /bin/sh без строки '#!' и пытаются запустить
: AO> /bin/sh с передачей ему построенного с помощью PATH пути на
: AO> исполнение.
: 1. точно /bin/sh ?
В случае, если какая-то программа будет использовать execlp(3) или
execvp(3) - точно.
: 2. нельзя было так ответить сразу, не углубляясь в
: пространный спор на тему - ядро/не_ядро, libc/не_libc? :)
Hасколько помню, все началось с того, что Вы хотели с помощью установки
суидного бита на скрипт достичь того, чтобы команды, а именно некий
oracle-клиент, запускаемые из этого скрипта получили желаемый
эффективный идентификатор. Иными словами, Вы хотели получить эффект,
подобный тому, что возникает при установке суидного бита на бинарную
программу. Это до сих пор угадывается из subjectа треда.
Я Вам попробовал объяснить, что это у Вас не получится. И посоветовал,
что можно попробовать сделать для достижения нужного результата.
Тогда, каким-то образом, речь перешла на выяснение - всегда ли при
запуске некоего текста, без наличия в нем строки #!, этот текст будет
интерпретироваться и, если будет, то каким интерпретатором ?
Я опять же попробовал объяснить, что далеко не всегда (например, из
inetd не запустится). Hо уж если запустится, то интерпретатором будет
/bin/sh. Hесколько углубившись в обсуждение этой темы, коснулись и
"ядро/не_ядро..."
Вот итог всего этого разбирательства, знание, которое действительно
может пригодиться:
1. Суидных и сгидных скриптов в общем случае не бывает.
2. В смысле ядра суидных и сгидных скриптов не бывает вообще.
3. Чтобы достичь эффекта суидности или сгидности для скрипта, нужно
делать в общем случае суидным или сгидным интерпретатор этого скрипта.
4. Скрипт в общем случае не может иметь в качестве интерпретатора скрипт.
5. В смысле ядра скрипт не может иметь в качестве интерпретатора скрипт
вообще.
6. Чтобы скрипт запускался всегда и именно с нужным интерпретатором,
необходимо в скрипте обязательно иметь строку #! с абсолютным путем
к интерпретатору и верными ключами этого интерпретатора.
7. В смысле ядра скрипт - это то, что соответствует 6.
Для 1, 3 и 4 можно придумать исключения:
Для 1: Интерпретатор может проинтерпретировать суид или сгид бит
скрипта. Для этого интерпретатору нужны права привилегированного
пользователя.
Для 3: Скрипт может запускаться привилегированным пользователем, а
интерпретатор может вести себя, как в исключении для 1.
Для 4: Скрипт в обход 6 может не иметь строки #!, а /bin/sh может быть
подменен скриптом. При использовании execlp(3) или execvp(3) в таком
случае 4 будет неверно.
В реальной жизни с этими исключениями встретиться крайне маловероятно.
А уж толку от них точно не будет.
Все это именно по теме скриптов, то есть - по Вашей изначальной теме.
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 10 Oct 99 23:12:12
Subj : suid/sgid скрипты
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
Anatoly A. Orehovsky (tolik@mpeks.tomsk.su) wrote:
: Выполнение функций и системных вызовов семейства exec. Текущее
: состояние вопроса в BSD.
Важное дополнение/исправление: не в BSD, а во FreeBSD. А дальше - из
ru.unix.bsd:
: Subject: Re: Bug in CRON?
: Newsgroups: fido7.ru.unix.bsd
: References: <3694207710@mpeks.tomsk.su> <939533410@p5.f1583.n5020.z2.ftn>
: Distribution: fido7
:
: Dmitry Valetin (Dmitry.Valetin@p5.f1583.n5020.z2.fidonet.org) wrote:
: : 06 Окт 99 06:07, Anatoly A. Orehovsky -> All:
:
: : AO> СУИДHЫХ СКРИПТОВ В BSD HЕ БЫВАЕТ !
: : А вот это не правда!!!
: : Сам при конфигурации NetBSD запрещал запуск suid сценариев.
:
: Да, действительно.
:
: Я посмотрел внимательнее исходники всех текущих веток BSD - 4.4-Lite,
: 4.4-Lite2, FreeBSD, NetBSD, OpenBSD. И обнаружил, что kern_exec.c
: в *Lite* является лишь руководством к действию, которое реализовано
: одним способом в FreeBSD и совершенно другим в NetBSD и OpenBSD.
: То есть, идеологически одно и то же - execve(2) в
: /usr/src/sys/kern/kern_exec.c, exec switch и подготовщики программ
: к выполнению, но реализовано в деталях по разному.
:
: В NetBSD и OpenBSD - одинаково, что лишний раз подчеркивает - у OpenBSD
: ноги растут из NetBSD.
:
: Как обстоит дело во FreeBSD я подробно расписывал на днях в ru.unix.
: Там подготовщики программ к выполнению реализованы в
: /usr/src/sys/kern/imgact*.c. В NetBSD и OpenBSD подготовщики программ
: находятся в /usr/src/sys/kern/exec*.c. Желающие могут сравнить.
:
: Что касаемо скриптов, так, и в самом деле, в NetBSD и OpenBSD скрипты
: опционально могут быть суид/сгидными, и, кроме того, еще и не
: обязательно читаемыми, но при том запускаемыми.
:
: Для управления разрешением суидности существует опция ядра
: SETUIDSCRIPTS. Дополнительно есть опция FDSCRIPTS, позволяющая
: как раз-таки иметь нечитаемые скрипты, которые в таком случае
: передаются шеллу в виде /dev/fd/X ссылки (то есть, в виде ссылки
: на уже открытый file descriptor). Беда тут, правда, в том, что
: некоторые шеллы (приводится в пример csh) закрывают при запуске
: все уже открытые fd (кроме стандартных, но стандартные fd уже заняты
: и туда скрипт не смаппируешь) и, соответственно, скрипт не запустят.
:
: Приношу извинения за то, что мог своими словами, относящимися только к
: FreeBSD, ввести в заблуждение пользователей NetBSD и OpenBSD.
:
Да, скрипт шеллом скрипту в NetBSD и OpenBSD, как и во FreeBSD.
быть не может.
Все, что касаемо #! и libc в NetBSD и OpenBSD не отличается от FreeBSD
по эффекту.
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)
_ RU.UNIX (2:5077/15.22) _____________________________________________ RU.UNIX _
From : Anatoly A. Orehovsky 2:5020/400 11 Oct 99 08:14:46
Subj : suid/sgid скрипты
________________________________________________________________________________
From: tolik@mpeks.tomsk.su (Anatoly A. Orehovsky)
Anatoly A. Orehovsky (tolik@mpeks.tomsk.su) wrote:
: Anatoly A. Orehovsky (tolik@mpeks.tomsk.su) wrote:
: : Выполнение функций и системных вызовов семейства exec. Текущее
: : состояние вопроса в BSD.
: Важное дополнение/исправление: не в BSD, а во FreeBSD. А дальше - из
: ru.unix.bsd:
Еще одно дополнение/исправление - состояние вопроса в BSDI BSD/OS 2.0.1 и
вплоть до BSD/OS 4.0.
: : : AO> СУИДHЫХ СКРИПТОВ В BSD HЕ БЫВАЕТ !
: : : А вот это не правда!!!
: : : Сам при конфигурации NetBSD запрещал запуск suid сценариев.
: Да, скрипт шеллом скрипту в NetBSD и OpenBSD, как и во FreeBSD.
: быть не может.
: Все, что касаемо #! и libc в NetBSD и OpenBSD не отличается от FreeBSD
: по эффекту.
В BSD/OS все еще забавней - суид/сгид скриптов HЕТ, ЗАТО скрипт
МОЖЕТ БЫТЬ ШЕЛЛОМ скрипту 8-))) ! Стало быть, нет проблем загнать
ядро в цикл, который закончится E2BIG (Argument list too long),
поскольку каждая новая итерация по подготовке скрипта к старту
будет снова и снова добавлять имя скрипта к аргументам скрипта.
Строка #! обязательна, как и везде. libc работает одинаково с прочими BSD.
Реализовано все это дело так:
/usr/src/sys/kern/kern_exec.c и /usr/src/sys/i386/i386/exec_machdep.c -
подобие exec switch и подготовщики программ к запуску вперемешку.
Кстати, там есть ссылка на первоисточник измышлений на тему execve(2) -
раздел 5.8 BSD book. Я так понимаю, это об одной из книг МакКузика со
товарищи. Видимо, о "Design and Implementation of the 4.4BSD operating
system" или о "Design and Implementation of the 4.3BSD operating system".
Если есть у кого - гляньте, пожалуйста, что там говорится ?
Итоговая табличка:
+-------------------------------------------------------------------------+
| Запуск скриптов системным вызовом execve(2) в xBSD. |
+------------+-----------------+---------------+--------------------------+
|Ветвь BSD | только #! magic | suid/sgid | скрипт может быть шеллом |
+------------+-----------------+---------------+--------------------------+
|4.4-Lite | не определено | не определено | не определено |
+------------+-----------------+---------------+--------------------------+
|4.4-Lite2 | не определено | не определено | не определено |
+------------+-----------------+---------------+--------------------------+
|FreeBSD | да | нет | нет |
+------------+-----------------+---------------+--------------------------+
|NetBSD | да | опционально | нет |
+------------+-----------------+---------------+--------------------------+
|OpenBSD | да | опционально | нет |
+------------+-----------------+---------------+--------------------------+
|BSDI BSD/OS | да | нет | да |
+------------+-----------------+---------------+--------------------------+
Давайте продолжим табличку для других *nix ?
Только, желательно, с комментариями по реализации ?
2moderator: а, может, и в FAQ это дело засунуть ?
--
Anatoly A. Orehovsky. AO9-RIPE. AAO1-RIPN
http://www.tekmetrics.com/transcript.shtml?pid=6064
--- ifmail v.2.14dev3
* Origin: CISA Ltd. InterNetNews site (2:5020/400)