KasperskyOS Community Edition 1.3

Разыменование дескрипторов

Разыменование дескриптора – это операция, при которой клиент отправляет серверу дескриптор, а сервер получает указатель на контекст передачи ресурса, маску прав отправленного дескриптора и предка отправленного клиентом дескриптора, которым сервер уже владеет. Разыменование выполняется, когда потребитель ресурсов, вызывая методы работы с ресурсом (например, чтение, запись, закрытие доступа), передает поставщику ресурсов дескриптор, который был получен от этого поставщика ресурсов при открытии доступа к ресурсу.

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

  1. Клиент упаковывает дескриптор в поле структуры IPC-запросов *_req типа nk_handle_desc_t.
  2. Клиент вызывает интерфейсный метод для отправки дескриптора серверу с целью выполнения действий с ресурсом. При вызове этого метода выполняется системный вызов Call().
  3. Сервер принимает IPC-запрос, выполнив системный вызов Recv().
  4. Диспетчер на стороне сервера вызывает метод, который соответствует IPC-запросу. Этот метод проверяет, что выполнена именно операция разыменования, а не передача дескриптора. Затем вызванный метод опционально проверяет, что права доступа разыменованного дескриптора (который отправлен клиентом) разрешают запрашиваемые действия с ресурсом, и извлекает указатель на контекст передачи ресурса из поля структуры запросов *_req типа nk_handle_desc_t.

Для выполнения проверок сервер использует функции nk_is_handle_dereferenced() и nk_get_badge_op(), которые объявлены в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK.

types.h (фрагмент)

/** * Функция возвращает отличное от нуля значение, если * дескриптор в транспортном контейнере дескриптора * desc получен в результате операции разыменования * дескриптора. Функция возвращает нуль, если дескриптор * в транспортном контейнере дескриптора desc получен * в результате операции передачи дескриптора. */ static inline nk_bool_t nk_is_handle_dereferenced(const nk_handle_desc_t *desc) /** * Функция извлекает указатель на контекст передачи ресурса * badge из транспортного контейнера дескриптора desc, * если в маске прав, которая помещена в транспортном * контейнере дескриптора desc, установлены флаги operation. * В случае успеха функция возвращает NK_EOK, иначе возвращает код ошибки. */ static inline nk_err_t nk_get_badge_op(const nk_handle_desc_t *desc, nk_rights_t operation, nk_badge_t *badge)

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