Я не знаю issetugid()
, но я могу научиться, читая справочные страницы BSD или Solaris. Функция исходит из OpenBSD.
1) Руководство по OpenBSD для issetugid(2) говорит: «Функция issetugid() возвращает 1, если процесс был сделан setuid или setgid в результате последнего или других предыдущих системных вызовов execve(). В противном случае она возвращает 0». Затем он предлагает использовать issetugid(), чтобы проверить, безопасно ли открывать файлы, указанные в переменных среды.
2) Нет, ваш код Linux и Solaris не эквивалентен. Процесс, выполняющий setuid, может установить свой реальный uid в эффективный uid без очистки переменных среды. Например, uid_t uid = geteuid(); setresuid(uid, uid, uid);
установит как реальный uid, так и сохраненный uid в эффективный uid. Тогда ваш issetugid() в Linux вернет 0, а issetugid() в Solaris вернет 1.
Solaris проверяет флаг процесса SUGID
во время выполнения. Illumos, бесплатный форк Solaris, устанавливает SUGID в src/uts/common/os/exec.c при выполнении файла. OpenBSD имеет аналогичную логику. В руководстве OpenBSD говорится:
Если дочерний процесс выполняет новый исполняемый файл, будет определен новый статус issetugid. Этот статус основан на разрешениях uid, euid, gid и egid существующего процесса, а также на режимах исполняемого файла. Если режимами нового исполняемого файла являются setuid или setgid, или если существующий процесс выполняет новый образ с uid != euid или gid != egid, новый процесс будет считаться issetugid.
Solaris и OpenBSD сравнивают идентификаторы во время выполнения. Ваш код Linux откладывает сравнение до вызова issetugid(), так что это не эквивалентно.
3) Кажется, что функции geteuid()
и getegid()
везде делают одно и то же; они просто возвращают эффективный идентификатор пользователя и эффективный идентификатор группы.
4) Сохраненные идентификаторы не имеют значения. Процесс мог изменить эти идентификаторы без очистки переменных среды. Ни один из реальных, эффективных или сохраненных идентификаторов не говорит нам, кто установил переменные среды для текущего процесса.
5) По крайней мере, в OpenBSD и Solaris процесс, временно удаляющий root, не становится испорченным. На странице руководства OpenBSD говорится:
На результат системного вызова issetugid() не влияют вызовы setuid(), setgid() или другие подобные вызовы. В случае fork() дочерний процесс наследует тот же статус.
На состояние issetugid() влияет только функция execve().
Когда процесс временно удаляет root с помощью setuid() или seteuid(), он не выполняет файл, поэтому его значение issetugid() не изменяется.
Но FreeBSD, DragonFly BSD и NetBSD определяют issetugid() более строго. Руководство по FreeBSD для issetugid( 2) говорит,
Процесс считается испорченным, если он был создан в результате системного вызова execve(2), в котором были установлены биты setuid или setgid (и в результате были предоставлены дополнительные привилегии), или если он изменил какие-либо из своих реальных, эффективных или сохраненные идентификаторы пользователя или группы с момента начала выполнения.
В этих системах процесс, удаляющий корень, принудительно устанавливает значение issetugid() равным 1.
6) Нет, эффективный идентификатор, равный сохраненному идентификатору, не портит процесс. Если бы это было так, то каждый процесс был бы испорчен, потому что каждый процесс имеет свой сохраненный идентификатор, установленный на его эффективный идентификатор во время выполнения.
person
George Koehler
schedule
26.05.2015