LINUX.ORG.RU

Временное повышение привелегий до root в своей программе


0

0

Всем привет.
Пишу программу под embedded linux(очень урезанная система в духе LFS, основанная на busybox), программе иногда нужно иметь права root'а(смонтировать флешку, установить новую дату-время в системе, ...). Над системой имею полный контроль, то есть могу программу запустить с правами root'а из /etc/inittab. Но по секурным причинам этого делать не хочется. Видимо нужно создать пользователя с ограниченными правами и запускать программу от него. А потом в нужные моменты программа должна как-то повысить свои привилегии и соответственно затем - понизить. Может есть какие системные вызовы? Или параллельно главной программе нужно запускать привилегированный процесс и его уже просить сделать нужное?

Вобщем, какие будут соображения?


вызовов нет, логичнее будет написать suid helper и делать приволегированные операции им

Sylvia ★★★★★
()

Написать вторую программу и поставить на неё SUID bit.

tempuser002
()
Ответ на: комментарий от Sylvia

как вариант можно запустить программу от рут, форкнуть рабочий процесс с дропом привилегий, мастер процесс останется работать от root, им и выполнять привилегированные задачи

Sylvia ★★★★★
()
Ответ на: комментарий от Sylvia

>логичнее будет написать suid helper и делать приволегированные операции им

Что такое suid - знаю, а suid helper - нет и ничего не гуглится. Можно подробнее?

gogi
() автор топика
Ответ на: комментарий от gogi

пишете маленькую программку, или suid или запускаете ее вместе с основной

основная программа или вызывает (suid) помощника, который делает то что нужно или обращается к нему через сокет (если он постоянно запущен)

сама по себе реализация несложная, но стоит обратить внимание на механизм защиты, чтобы через хелпер не могли злонамеренно воспользоваться тем что он предоставляет, если это конечно актуально на вашей embedded

Sylvia ★★★★★
()
Ответ на: комментарий от Sylvia

можно написать много хелперов под задачи

helper.mount
helper.settimedate

выставить на них бит suid и вызывать соответственно из вашей основной программы, наиболее простой защитой будет ограничение по группе

например

chown root.suhelper <все программы>
запрещаем выполнение хелперов для тех кто не в группе, ставим suid бит
chmod 4750 helper.*

ставим sgid бит на основную программу

chmod 2750 progname


Sylvia ★★★★★
()

Всё давно предусмотренно, читай про действительный, эффективный и сохранённый ID пользователя и группы, системные вызовы setresuid и setresgid соответственно.

archimag ★★★
()

помнится раньше ping, по крайней мере в FreeBSD делал именно так, так что можешь смотреть сорцы :)

anonymous
()
Ответ на: комментарий от Sylvia

> почему это так нечасто используют?

Думаю, что такое поведение не так часто нужно, потом, модель программирования всё-таки довольно сложная - надо сохранять осторожность и бдить. Про портабельность не в курсе, не интересовался.

archimag ★★★
()
Ответ на: комментарий от Sylvia

Я делал так: в самом начале делал всё что нужно от рута, потом просто вызывал

setuid(getuid());
ну соответсвенно на испол. файл ставил бит suid.

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от archimag

СООТВЕТСТВИЕ СТАНДАРТАМ

Этот вызов является нестандартным.

ПРИМЕЧАНИЯ ПО ИСТОРИИ

Эта функция впервые появилась в HP-UX. В Linux она доступна начиная с Linux 2.1.44. На текущий момент она также существует в FreeBSD (для эмуляции исполняемых файлов Linux).

ЗАМЕЧАНИЯ

В HP-UX и FreeBSD прототип функции находится в <unistd.h>. В Linux прототип задан в glibc, начиная с версии 2.3.2, обеспечивая определение _GNU_SOURCE.

похоже из за того что вызов не описан в стандарте POSIX а так конечно вариант хороший, а бдить везде нужно все равно, в случае с хелпером тоже.

Для не-embedded есть PolicyKit

Sylvia ★★★★★
()
Ответ на: комментарий от Boy_from_Jungle

>в самом начале делал всё что нужно от рута

это хороший вариант если нужны права только в самом начале, а если в процессе выполнения ?)


Sylvia ★★★★★
()
Ответ на: комментарий от Sylvia

а если в процессе выполнения ?)


даже не знаю, ещё не приходилось пока

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Sylvia

если в процессе выполнения, то вариант только один - privilege separation. иначе - ссзб.

val-amart ★★★★★
()

Я бы сделал две отдельные проги, причем вторая с suid'ом.

bk_ ★★
()
Ответ на: комментарий от Sylvia

>запустить программу от рут, форкнуть рабочий процесс с дропом привилегий

Классика. Так сделано в kppp, например.

ttnl ★★★★★
()

как уже сказали смотри на: int seteuid(uid_t euid) и int setegid(gid_t egid);

urezki
()
Ответ на: комментарий от Sylvia

Этот вызов является нестандартным.

Есть еще getre[gu]id/setre[gu]id/gete[gu]id/sete[gu]id, они есть POSIX.1-2001. В принципе, их должно хватить в большинстве случаев.

Польза от getres[gu]id() только в том, что можно получить Saved Set-User/Group-ID, который другими (переносимыми) средствами не получить.

setresuid(ruid, euid, 0) можно переносимо выполнить так:

setreuid(ruid, 0);
seteuid(euid);

вернуть рута, соответственно,

seteuid(0);
setreuid(0, 0);

В принципе, этого должно хватить.

Если программирование чисто под Linux, есть хорошая библиотека libcap (и <sys/capability.h>) — с ее помощью можно сбрасывать все ненужные привилегии.

sjinks ★★★
()
Ответ на: комментарий от archimag

сбросить привилегии ты сможешь, а вот обратно поднять только если posix capabilites заюзать.

true_admin ★★★★★
()
Ответ на: комментарий от xydo

Это embedded. Использовать suid-костыль для вызова костыля требующего рут привилегии. Не проще ли поставить suid на костыль, требующий рута?

azure ★★
()
Ответ на: комментарий от azure

ну, получим на один suid-костыль в системе больше))
насколько это соответствует принятым у ТС правилам безопасности судить не берусь.

xydo ★★
()
Ответ на: комментарий от xydo

просто ТС не придется возиться с переключением пользователя в коде его дополнительных костылей. их вообще не будет.
впрочем, может у ТС ЗП считается в зависимости от количества написанных строк кода))

xydo ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.