Процессы, которые де-эскалируют привилегии через setuid()
и setgid()
, кажется, не наследуют членство в группах установленного ими uid / gid.
У меня есть серверный процесс, который должен быть выполнен от имени пользователя root, чтобы открыть привилегированный порт; после этого он де-эскалирует к определенному непривилегированному uid / gid, 1 - например, к пользователю foo
(UID 73). Пользователь foo
является членом группы bar
:
> cat /etc/group | grep bar
bar:x:54:foo
Следовательно, если я войду в систему как foo
, я могу прочитать файл /test.txt
с этими характеристиками:
> ls -l /test.txt
-rw-r----- 1 root bar 10 Mar 8 16:22 /test.txt
Тем не менее, следующая C-программа (компилируется std=gnu99
) при запуске root:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
int main (void) {
setgid(73);
setuid(73);
int fd = open("/test.txt", O_RDONLY);
fprintf(stderr,"%d\n", fd);
return 0;
}
Всегда сообщает, что в доступе отказано . Я полагаю, что это связано с тем, что это процесс, не связанный с входом в систему, но он вроде подколенного сухожилия, как должны работать разрешения.
1. Что часто является SOP для серверов, и я думаю, что должен быть способ обойти это, поскольку я нашел сообщение о том, что кто-то делает это с apache - apache был добавлен в аудиогруппу и, очевидно, может затем использовать звуковую систему. Конечно, это, скорее всего, происходит в форке, а не в исходном процессе, но на самом деле в моем контексте дело обстоит так же (это дочерний процесс, разветвленный после вызова setuid).
источник
setuid()
/setgid()
вызовы вокруг.setgid(54)
вместоsetgid(73)
(как в/etc/groups
группеbar
есть gid 54), это работает?setuid()
снова после того, как вы это сделаете ... но, хммм ... я думаю, что вы можете сseteuid()
...Ответы:
Проблема заключается в том, что
setuid
иsetgid
не является достаточным , чтобы дать вашему процессу все полномочия, необходимые. Полномочия процесса зависят отСмотрите,
man 7 credentials
чтобы получить более подробный обзор. Итак, в вашем случае проблема заключается в том, что вы правильно установили UID и GID, но не устанавливаете дополнительные группы процесса. И у группыbar
есть GID 54, а не 73, поэтому он не распознается как группа, в которой находится ваш процесс.Ты должен сделать
источник
dialout
группы, и это сработало впервые.ОК, немного побродил по сети. Сначала я думал, что APUE будет содержать все ответы, но ошибся. И моя копия (старая редакция) в работе, так что ... Глава 5 Руководства по администрированию Unix и Linux выглядит многообещающе, но у меня ее нет (просто копия первых двух редакций, также в работе).
В маленьких ресурсах, которые я нашел (google для "unix daemon writing"), все говорится о важных шагах, таких как отсоединение от tty и т. Д. Но ничего о UID / GID. Как ни странно, даже обширная коллекция HOWTO на http://tldp.org, похоже, не содержит подробностей. Только excetion Джейсон Шорты Напишет Linux Daemon - часть I . Полную информацию о том, как работает SUID / SGID и все эти беспорядки, можно найти в демоверсии SUID Чена, Вагнера и Дина (статья в USENIX 2002). Но будьте осторожны, у Linux есть дополнительный UID, FSUID (см. Замечания по совместимости Unix от Wolter : Функции настройки UID для обсуждения).
Демонизация процесса определенно не для слабонервных. Общие соображения безопасности даны в документе « Безопасное программирование D. Wheeler для Linux и Unix HOWTO - Создание безопасного программного обеспечения» . Systemd обещает упростить большую часть этого (и, таким образом, уменьшить пространство для ошибок, которые приводят к проблемам безопасности), см. Руководство к демону .
источник
setuid()
, который позволяет процессу произвольно изменять свой UID. SUID обычно предназначен для разрешения эскалации разрешений (непривилегированный -> привилегированный), тогда какsetuid()
может делать только обратное.