]> Sergey Matveev's repositories - stargrave-blog.git/commit
Нравится писать privsep/privdrop-oriented программки
authorSergey Matveev <stargrave@stargrave.org>
Sat, 16 Dec 2023 10:29:14 +0000 (13:29 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sat, 16 Dec 2023 10:29:14 +0000 (13:29 +0300)
commit24acdbc75c8ffae0b70fc127118df12434767dd1
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent341b91285d94333cd98c6cf991589e3953616379
Нравится писать privsep/privdrop-oriented программки

Переделывал тут одну программу, которая для случайных данных
использовала getrandom() вызов, не мешающий делать Capsicum и
всякий hardening с privilege drop-ом. А теперь она ещё должна
уметь для случайных данных обращаться по EGD-протоколу к внешнему
демону, что уже не дружит с Capsicum так легко и просто. Он заточен на
то, чтобы заранее открыть все нужные сокеты/файлы, настроить права
доступа на них и перейти в режим ограничений. В FreeBSD можно много чего
делать через файлы и не всё так просто и примитивно, но вот уже создавать
новые EGD соединения не выйдет так легко и просто. Плюс появился
собственный PRNG со своим пулом энтропии и хотелось бы чтобы
fork-ающиеся процессы-клиенты имели централизованный PRNG.

Оказалось не так всё сложно. fork-аемся для создания процесса который
отвечает только за PRNG и общение с EGD, заранее имея с ним socketpair
сокет. Перед fork-ом каждого клиента, тоже делаем пару сокетов, один из
которых будет под контролем процесса-клиента, а другой передаём через
Unix-сокет в PRNG-процесс. В итоге появляется двусторонний канал связи
между PRNG-процессом и клиентским. Клиенту уже не нужно общаться с EGD
или чем-то подобным -- он волен спокойно использовать Capsicum и другие
методы hardening.

Не все люди на работе, которые писали под Unix на Си ещё когда я играл
под Windows, знали про возможность передачи файлов/сокетов через
Unix-сокет. Я это делал впервые на практике, но слышал задолго до этого,
ибо например Tmux это использует в себе и поэтому его сокет просто так
удалённо не пробросить.

Вот только отправку control message с передачей сокета я делал просто
скопировав пример из man-а FreeBSD, где полезная нагрузка явно не
передавалась. Сокет/файл передаются, всё ok. Но вот только если это
засунуть в poll(), то он бесконечно зацикливается: постоянно говорит что
из сокета есть что прочитать, но recvmsg() возвращает ноль. Пришлось
хотя бы один байт полезной нагрузки явно передать, для решения проблемы.
Как себя ведёт kqueue тут не пробовал -- задача достаточно проста чтобы
и просто poll()-ом (ради совместимости с GNU/Linux) обходиться.