Обычно это делается путем создания вашего двоичного suid-корня.
Один из способов справиться с этим, чтобы атаки на вашу программу были сложными, состоит в том, чтобы минимизировать код, который запускается от имени пользователя root, следующим образом:
int privileged_server(int argc, char **argv);
int unprivileged_client(int argc, char **argv, int comlink);
int main(int argc, char **argv) {
int sockets[2];
pid_t child;
socketpair(AF_INET, SOCK_STREAM, 0); /* or is it AF_UNIX? */
child = fork();
if (child < 0) {
perror("fork");
exit(3);
} elseif (child == 0) {
close(sockets[0]);
dup2(sockets[1], 0);
close(sockets[1]);
dup2(0, 1);
dup2(0, 2); /* or not */
_exit(privileged_server(argc, argv));
} else {
close(sockets[1]);
int rtn;
setuid(getuid());
rtn = unprivileged_client(argc, argv, sockets[0]);
wait(child);
return rtn;
}
}
Теперь непривилегированный код общается с привилегированным кодом через fd comlink (который является подключенным сокетом). Соответствующий привилегированный код использует stdin / stdout в качестве конца comlink.
Привилегированный код должен проверять безопасность каждой операции, которую он должен выполнять, но, поскольку этот код невелик по сравнению с непривилегированным кодом, это должно быть достаточно просто.