### Системные вызовы Приложения выполняются в так называемом пользовательском пространстве (user space), уровень полномочий которого ниже, чем у ядра операционной системы. Чтобы обратиться к файлу, передать данные по сети или даже узнать время суток, приложению приходится просить ядро выполнить соответствующее действие. Программный интерфейс, с помощью которого код из пользовательского пространства выполняет подобные запросы к ядру, называется интерфейсом системных вызовов (system call). Существует более 300 различных системных вызовов, конкретное количество зависит от версии ядра Linux. Ниже приведены несколько примеров: * read — чтение данных из файла; * write — запись данных в файл; * open — открытие файла для последующего чтения или записи; * execve — запуск исполняемой программы; * chown — изменение владельца файла; * clone — создание нового процесса. ### Права доступа к файлам **Биты setuid и setgid** При обычном выполнении файла запускаемый процесс наследует ваш идентификатор пользователя. Если же у файла установлен бит setuid, то процесс получит идентификатор пользователя владельца файла. В следующем примере задействована копия исполняемого файла sleep, владельцем которого является несуперпользователь: ``` vagrant@vagrant:~$ ls -l `which sleep` -rwxr-xr-x 1 root root 35000 Jan 18 2018 /bin/sleep vagrant@vagrant:~$ cp /bin/sleep ./mysleep vagrant@vagrant:~$ ls -l mysleep -rwxr-xr-x 1 vagrant vagrant 35000 Oct 17 08:49 mysleep ``` Информация, которую выводит ls, показывает, что владельцем этой копии является пользователь vagrant. Запустите данную команду от имени суперпользователя с помощью sudo sleep 100, и во втором терминале сможете посмотреть на работающий процесс — 100 означает, что у вас есть на это100 секунд, прежде чем процесс завершится (чтобы сделать вывод более понятным, я убрала из него несколько строк): ``` vagrant@vagrant:~$ ps ajf PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 1315 1316 1316 1316 pts/0 1502 Ss 1000 0:00 -bash 1316 1502 1502 1316 pts/0 1502 S+ 0 0:00 \_ sudo ./mysleep 100 1502 1503 1502 1316 pts/0 1502 S+ 0 0:00 \_ ./mysleep 100 ``` UID, равный 0, означает, что как процесс sudo, так и процесс mysleep выполняются под UID суперпользователя. Попробуем теперь установить бит setuid: ``` vagrant@vagrant:~$ chmod +s mysleep vagrant@vagrant:~$ ls -l mysleep -rwsr-sr-x 1 vagrant vagrant 35000 Oct 17 08:49 mysleep ``` Снова выполните sudo ./mysleep 100 и опять посмотрите в другом терминале на запущенные процессы: ``` vagrant@vagrant:~$ ps ajf PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 1315 1316 1316 1316 pts/0 1507 Ss 1000 0:00 -bash 1316 1507 1507 1316 pts/0 1507 S+ 0 0:00 \_ sudo ./mysleep 100 1507 1508 1507 1316 pts/0 1507 S+ 1000 0:00 \_ ./mysleep 100 ``` Процесс sudo снова выполняется от имени суперпользователя, а процесс mysleep унаследовал UID от владельца файла.Обычно с помощью этого бита программе предоставляются полномочия, необходимые ей, но недоступные обычным пользователям. Классический пример — команда ping, которой требуется право на открытие сетевых сокетов прямого доступа для отправки сообщений ping. (Для предоставления этого права доступа используется механизм capability, который мы рассмотрим в разделе «Привилегии Linux» на с. 44.) Администратор может не возражать против того, чтобы его пользователи применяли утилиту ping, но отнюдь не разрешать им открывать сокеты прямого доступа для других целей. Поэтому для исполняемого файла ping обычно сразу устанавливается бит setuid и владельцем его является суперпользователь, так что команда ping может использовать полномочия, обычно доступные лишь суперпользователю. Влияние бита setuid на безопасность. Представьте, что получится, если установить бит setuid, скажем, для исполняемого файла bash. Все выполняющие его пользователи окажутся в командной оболочке, работающей от имени суперпользователя. На практике не все так просто, конечно, поскольку большинство командных оболочек ведут себя подобно ping и сбрасывают идентификатор пользователя, чтобы его нельзя было применить для такого очевидного повышения полномочий. Но можно очень легко написать собственную программу, которая бы устанавливала себе бит setuid, после чего, перейдя в статус суперпользователя, запускала командную оболочку