netlib.narod.ru< Назад | Оглавление | Далее >

Возможности

В предшествующем разделе был приведен пример проверки возможностей — фактически, одна и та же возможность проверялась дважды. Этой возможностью была CAP_SYS_NICE (строка 14104), которая управляет тем, должно ли быть позволено процессу устанавливать приоритеты (уровни требовательности) или политики планирования. Поскольку возможность CAP_SYS_NICE применяется не только к уровням требовательности, ее название не совсем правильно — хотя понятно, что установка планировщика — весьма близкое понятие, и что, скорее всего, вряд-ли одна возможность потребуется без другой.

Каждый процесс имеет три набора возможностей, хранящиеся в структуре struct task_struct (и определенные в строках с 16400 по 16401):

Действующий набор возможностей процесса — набор действий, которые ему разрешено выполнять в настоящее время; этот набор проверяется широко используемой функцией capable, которая определяется в строке 16738.

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

Если возможность находится в разрешенном наборе, но не находится в действующем наборе, процесс не имеет данную возможность непосредственно сейчас, но может получить ее, сделав запрос. К чему такое различие? Что ж, при первом освещении возможностей в начале этой главы мы кратко рассмотрели пример долговременного процесса, которому возможность требовалась только периодически, а не постоянно. Для того, чтобы процесс случайно не злоупотребил возможностью, он может дождаться, когда она ему потребуется, запросить ее, выполнить привилегированную операцию, а затем снова утратить возможность. Такой подход гораздо безопасней.

Наследуемый набор — не совсем то, что можно было бы предположить. Это не набор возможностей, которые родительский процесс передает дочерним процессам во время выполнения подпрограммы fork — в действительности в момент создания (т.е. непосредственно после выполнения fork) все три набора возможностей дочернего процесса совпадают с наборами родительского процесса. Наследуемый процесс выступает на сцену во время выполнения exec. Непосредственно перед вызовом exec наследуемый набор процесса помогает определить разрешенный и наследуемый наборы, которые процесс сохранит после выполнения exec — для более подробного ознакомления с этим процессом обратитесь к функции compute_creds (строка 9948). Обратите внимание, что сохранение возможности после выполнения exec лишь частично зависит от наследуемого набора процесса; это зависит также от разрядов возможностей, установленных в самом файле (или, по крайней мере, так планируется — это свойство реализовано еще не полностью).

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

Возможности показаны на рис. 7.4. На этом рисунке показаны три набора возможностей для гипотетического процесса, причем разряды нумеруются справа налево. Процессу разрешено получить возможность CAP_KILL, которая позволяет ему прервать любой другой процесс, независимо от его владельца; но процесс пока не имеет этой возможности и не будет получать ее автоматически во время выполнения exec. В настоящий момент он имеет возможность вставлять и удалять модули ядра (используя CAP_SYS_MODULE), но также не будет получать ее во время выполнения exec. Процесс мог бы получить возможность CAP_SYS_NICE и будет получать ее во время выполнения exec (при условии, что соответствующие разряды возможностей файла установлены). И наконец, непосредственно сейчас процесс может изменить системное время (CAP_SYS_TIME) и будет сохранять эту возможность после выполнения exec (опять таки, при условии, что соответствующие разряды возможностей файла установлены). Ни этот процесс, ни один из тех, которые он может запустить с помощью функции exec, не может получить иные возможности, если только они не обеспечиваются каким-либо другим процессом, имеющим возможность CAP_SETPCAP.


Рис. 7.4. Наборы возможностей

Рис. 7.4. Наборы возможностей


Код, поддерживающий все эти свойства, в основном размещается в файле kernel/capability.c, начинающемся со строки 22460. Двумя основными функциями являются sys_capget (строка 22480), которая считывает возможности, и sys_capset (строка 22592), которая их устанавливает; эти функции освещаются далее в этом разделе. Как уже отмечалось, наследование возможностей после выполнения exec обеспечивается функцией compute_creds файла fs/exec.c (строка 9948).

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

Интересное свойство возможностей состоит в том, что они могут использоваться для изменения «оттенка» системы. Например, установка возможности CAP_SYS_NICE для всех процессов позволила бы всем процессам поднимать свои приоритеты (и устанавливать свои планировщики, и т.п.). При изменении способа использования системы всеми процессами изменяется и сама система. Можете сами придумать новые возможности ядра, которые позволяют полнее использовать систему.

Одно, почти неуловимое преимущество возможностей заключается в том, что они проясняют исходный код. При проверке того, нужно ли разрешать текущему процессу устанавливать системное время, необходимость запрашивать вместо этого, будет ли текущий процесс запускаться привилегированным процессом — не слишком очевидный подход. Возможности позволяют более точно выразить, что имеется в виду. Существование возможностей даже помогает прояснить код, который запрашивает о идентификаторе пользователя или группы процесса, поскольку выполняющий это код предположительно интересует ответ на данный вопрос, а не возможные из него выводы. В противном случае, используя возможности, код запросил бы конкретно интересующие его данные. По мере дальнейшей интеграции возможностей в код ядра Linux это свойство станет более надежным.

sys_capget

sys_capset


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz