Глава 6. Фреймворк TrustedBSD MAC

Этот перевод может быть устаревшим. Для того, чтобы помочь с переводом, пожалуйста, обратитесь к Сервер переводов FreeBSD.

Этот документ был разработан для проекта FreeBSD Крисом Костелло из Safeport Network Services и Network Associates Laboratories, подразделения исследований безопасности Network Associates, Inc., по контракту DARPA/SPAWAR N66001-01-C-8035 ("CBOSS") в рамках исследовательской программы DARPA CHATS.

Redistribution and use in source (SGML DocBook) and 'compiled' forms (SGML, HTML, PDF, PostScript, RTF and so forth) with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code (SGML DocBook) must retain the above copyright notice, this list of conditions and the following disclaimer as the first lines of this file unmodified.

  2. Распространение в скомпилированной форме (преобразованное в другие DTD, конвертированное в PDF, PostScript, RTF и другие форматы) должно включать указанное выше уведомление об авторских правах, данный список условий и следующий отказ от ответственности в документации и/или других материалах, предоставляемых вместе с распространением.

ЭТА ДОКУМЕНТАЦИЯ ПРЕДОСТАВЛЯЕТСЯ NETWORKS ASSOCIATES TECHNOLOGY, INC «КАК ЕСТЬ», И ЛЮБЫЕ ЯВНЫЕ ИЛИ ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ ТОВАРНОЙ ПРИГОДНОСТИ И ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ ОТРИЦАЮТСЯ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ NETWORKS ASSOCIATES TECHNOLOGY, INC НЕ НЕСЕТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЯМЫЕ, КОСВЕННЫЕ, СЛУЧАЙНЫЕ, СПЕЦИАЛЬНЫЕ, ШТРАФНЫЕ ИЛИ КОСВЕННЫЕ УБЫТКИ (ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ, ЗАТРАТЫ НА ЗАМЕНУ ТОВАРОВ ИЛИ УСЛУГ; ПОТЕРЮ ИСПОЛЬЗОВАНИЯ, ДАННЫХ ИЛИ ПРИБЫЛИ; ЛИБО ПРЕРЫВАНИЕ БИЗНЕСА), ВЫЗВАННЫЕ ЛЮБЫМ ОБРАЗОМ И НА ОСНОВАНИИ ЛЮБОЙ ТЕОРИИ ОТВЕТСТВЕННОСТИ, БУДЬ ТО В РАМКАХ ДОГОВОРА, СТРОГОЙ ОТВЕТСТВЕННОСТИ ИЛИ ДЕЛИКТА (ВКЛЮЧАЯ НЕБРЕЖНОСТЬ ИЛИ ИНОЕ), ВОЗНИКШИЕ ВСЛЕДСТВИЕ ИСПОЛЬЗОВАНИЯ ЭТОЙ ДОКУМЕНТАЦИИ, ДАЖЕ ЕСЛИ БЫЛО ПРЕДУПРЕЖДЕНИЕ О ВОЗМОЖНОСТИ ТАКИХ УБЫТКОВ.

6.2. Обзор

FreeBSD включает экспериментальную поддержку нескольких политик обязательного контроля доступа, а также инфраструктуру для расширяемости безопасности ядра — TrustedBSD MAC Framework. MAC Framework представляет собой модульную инфраструктуру контроля доступа, позволяющую легко встраивать новые политики безопасности в ядро, загружать их при старте системы или динамически во время работы. Инфраструктура предоставляет множество возможностей для упрощения реализации новых политик безопасности, включая возможность легко присваивать метки безопасности (например, информацию о конфиденциальности) объектам системы.

Эта глава представляет фреймворк политик MAC и содержит документацию для образца модуля политики MAC.

6.3. Введение

Фреймворк TrustedBSD MAC предоставляет механизм для расширения модели контроля доступа ядра во время компиляции или выполнения. Новые политики системы могут быть реализованы в виде модулей ядра и связаны с ним; если присутствуют несколько модулей политик, их результаты будут объединены. Фреймворк MAC предоставляет различные инфраструктурные сервисы контроля доступа для помощи разработчикам политик, включая поддержку временных и постоянных меток безопасности объектов, не зависящих от политик. В настоящее время эта поддержка считается экспериментальной.

Эта глава предоставляет информацию, предназначенную для разработчиков модулей политик, а также потенциальных пользователей сред с поддержкой MAC, чтобы узнать о том, как MAC Framework поддерживает расширение контроля доступа в ядре.

6.4. Общие сведения о политиках

Мандатное управление доступом (MAC — Mandatory Access Control) относится к набору политик контроля доступа, которые в обязательном порядке применяются операционной системой к пользователям. Политики MAC можно противопоставить защите на основе дискреционного управления доступом (DAC — Discretionary Access Control), при которой непривилегированные пользователи могут (по своему усмотрению) защищать объекты. В традиционных UNIX-системах защита DAC включает права доступа к файлам и списки контроля доступа; защита MAC включает управление процессами, предотвращающее отладку между пользователями, и межсетевые экраны. Различные политики MAC были разработаны создателями операционных систем и исследователями безопасности, включая политику конфиденциальности многоуровневой безопасности (MLS — Multi-Level Security), политику целостности Biba, управление доступом на основе ролей (RBAC — Role-Based Access Control), принудительное применение доменов и типов (DTE — Domain and Type Enforcement) и принудительное применение типов (TE — Type Enforcement). Каждая модель основывает решения на различных факторах, включая идентификатор пользователя, роль и уровень доступа, а также метки безопасности на объектах, представляющих такие концепции, как конфиденциальность и целостность данных.

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

6.5. Архитектура MAC Framework в ядре

Фреймворк TrustedBSD MAC позволяет модулям ядра расширять политику безопасности операционной системы, а также предоставляет функциональность инфраструктуры, необходимую многим модулям контроля доступа. Если одновременно загружено несколько политик, фреймворк MAC полезным образом (в некотором смысле полезным) объединит результаты этих политик.

6.5.1. Элементы ядра

В рамках MAC Framework реализован ряд элементов ядра:

  • Интерфейсы управления фреймворком

  • Параллелизм и примитивы синхронизации.

  • Регистрация политики

  • Расширяемая метка безопасности для объектов ядра

  • Операторы композиции точки входа политики

  • Примитивы управления метками

  • Точка входа API, вызываемая службами ядра

  • Точка входа API для модулей политик

  • Реализации точек входа (жизненный цикл политики, жизненный цикл объекта/управление метками, проверки контроля доступа).

  • Системные вызовы, независимые от политик, для управления метками

  • mac_syscall() мультиплексный системный вызов

  • Различные политики безопасности, реализованные в виде модулей политики MAC

6.5.2. Интерфейсы управления фреймворком

Фреймворком TrustedBSD MAC можно напрямую управлять с помощью sysctl, параметров загрузчика и системных вызовов.

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

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

6.5.3. Список политик параллелизма и синхронизации

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

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

Поскольку MAC Framework не может блокировать некоторые точки входа, обычная блокировка сна не может быть использована; в результате попытка загрузки или выгрузки может блокироваться на значительное время, ожидая, пока фреймворк станет свободным.

6.5.4. Синхронизация меток

Поскольку к объектам ядра обычно может обращаться более одного потока одновременно, и допускается одновременный вход нескольких потоков в MAC Framework, хранение атрибутов безопасности, поддерживаемое MAC Framework, тщательно синхронизировано. Как правило, существующая синхронизация ядра для данных объектов ядра используется для защиты меток безопасности MAC Framework на объекте: например, метки MAC на сокетах защищаются с помощью существующего мьютекса сокета. Аналогично, семантика параллельного доступа обычно идентична семантике контейнерных объектов: для учетных данных поддерживается семантика копирования при записи для содержимого меток, как и для остальной структуры учетных данных. MAC Framework устанавливает необходимые блокировки на объекты при вызове с ссылкой на объект. Авторам политик необходимо учитывать эти семантики синхронизации, так как они иногда ограничивают типы доступа к меткам: например, когда ссылка только для чтения на учетные данные передается политике через точку входа, разрешены только операции чтения для состояния метки, прикрепленного к учетным данным.

6.5.5. Синхронизация политики и параллелизм

Модули политик должны быть написаны с учетом того, что множество потоков ядра могут одновременно войти в одну или несколько точек входа политики из-за параллельной и вытесняющей природы ядра FreeBSD. Если модуль политики использует изменяемое состояние, это может потребовать применения примитивов синхронизации внутри политики, чтобы предотвратить несогласованные представления этого состояния, ведущие к некорректной работе политики. Политики, как правило, могут использовать существующие примитивы синхронизации FreeBSD для этой цели, включая мьютексы, блокировки с ожиданием, условные переменные и счётные семафоры. Однако политики должны быть написаны так, чтобы применять эти примитивы осторожно, соблюдая существующие порядки блокировок в ядре и учитывая, что некоторые точки входа не допускают ожидания, ограничивая использование примитивов в этих точках входа мьютексами и операциями пробуждения.

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

6.5.6. Регистрация политики

Фреймворк MAC поддерживает два списка активных политик: статический список и динамический список. Списки отличаются только в отношении их семантики блокировки: для использования статического списка не требуется повышенный счетчик ссылок. Когда загружаются модули ядра, содержащие политики фреймворка MAC, модуль политики использует SYSINIT для вызова функции регистрации; когда модуль политики выгружается, SYSINIT аналогично вызывает функцию отмены регистрации. Регистрация может завершиться неудачей, если модуль политики загружается более одного раза, если для регистрации недостаточно ресурсов (например, политика может требовать маркировки, а доступного состояния маркировки может быть недостаточно), или другие предварительные условия политики могут не выполняться (некоторые политики могут быть загружены только до загрузки системы). Аналогично, отмена регистрации может завершиться неудачей, если политика помечена как невыгружаемая.

6.5.7. Точки входа

Ядро взаимодействует с MAC Framework двумя способами: вызывает набор API для уведомления фреймворка о соответствующих событиях и предоставляет указатель на структуру меток, не зависящую от политики, в объектах, связанных с безопасностью. Указатель метки управляется MAC Framework через точки входа управления метками, что позволяет фреймворку предоставлять службу маркировки модулям политик с относительно минимальными изменениями в подсистеме ядра, управляющей объектом. Например, указатели меток были добавлены к процессам, учетным данным процессов, сокетам, каналам, vnode, Mbuf, сетевым интерфейсам, очередям сборки IP-пакетов и множеству других структур, связанных с безопасностью. Ядро также вызывает MAC Framework при принятии важных решений по безопасности, позволяя модулям политик дополнять эти решения на основе собственных критериев (включая, возможно, данные, хранящиеся в метках безопасности). Большинство этих критически важных решений по безопасности будут явными проверками контроля доступа; однако некоторые влияют на более общие функции принятия решений, такие как сопоставление пакетов для сокетов и переход меток при выполнении программы.

6.5.8. Композиция политик

Когда в ядро загружено более одного модуля политики одновременно, результаты работы модулей политики будут объединены фреймворком с использованием оператора композиции. Этот оператор в настоящее время жёстко закодирован и требует, чтобы все активные политики одобрили запрос для возврата успешного результата. Поскольку политики могут возвращать различные условия ошибки (успех, доступ запрещён, объект не существует, …​), оператор старшинства выбирает результирующую ошибку из набора ошибок, возвращаемых политиками. В общем случае, ошибки, указывающие на то, что объект не существует, будут предпочтительнее ошибок, указывающих на запрет доступа к объекту. Хотя не гарантируется, что результирующая композиция будет полезной или безопасной, мы обнаружили, что это так для многих полезных наборов политик. Например, традиционные доверенные системы часто поставляются с двумя или более политиками, использующими аналогичную композицию.

6.5.9. Поддержка меток

Поскольку многие интересные расширения контроля доступа зависят от меток безопасности объектов, MAC Framework предоставляет набор системных вызовов для управления метками, не зависящих от политик, охватывающих различные объекты, доступные пользователю. Общие типы меток включают идентификаторы разделов, метки конфиденциальности, метки целостности, отделы (compartment), домены, роли и типы. Под "не зависящими от политик" подразумевается, что модули политик могут полностью определять семантику метаданных, связанных с объектом. Модули политик участвуют в интернализации и экстернализации строковых меток, предоставляемых пользовательскими приложениями, и могут при необходимости предоставлять приложениям несколько элементов меток.

Метки в памяти хранятся в struct label, выделяемой через slab-аллокатор. Эта структура состоит из массива фиксированной длины, содержащего объединения, каждое из которых хранит указатель void * и значение типа long. Политикам, регистрирующим хранилище меток, назначается идентификатор "слота", который может использоваться для разыменования хранилища меток. Семантика хранилища полностью определяется модулем политики: модулям предоставляется набор точек входа, связанных с жизненным циклом объектов ядра, включая инициализацию, связывание/создание и уничтожение. Используя эти интерфейсы, можно реализовать подсчёт ссылок и другие модели хранения. Прямой доступ к структуре объекта, как правило, не требуется модулям политики для получения метки, поскольку MAC Framework обычно передаёт в точки входа как указатель на объект, так и прямой указатель на метку объекта. Основным исключением из этого правила являются учётные данные процесса, для доступа к метке которых требуется ручное разыменование. Это может измениться в будущих версиях MAC Framework.

Входные точки инициализации часто включают флаг режима сна, указывающий, разрешено ли инициализации переходить в режим сна; если сон не разрешен, может быть возвращена ошибка для отмены выделения метки (и, следовательно, объекта). Это может произойти, например, в сетевом стеке во время обработки прерывания, где сон не разрешен, или пока вызывающий удерживает мьютекс. Из-за затрат производительности на поддержание меток на передаваемых сетевых пакетах (Mbuf), политики должны явно объявлять требование о выделении меток для Mbuf. Динамически загружаемые политики, использующие метки, должны быть способны обрабатывать случай, когда их функция инициализации не была вызвана для объекта, так как объекты могут уже существовать при загрузке политики. MAC Framework гарантирует, что неинициализированные слоты меток будут содержать значение 0 или NULL, что политики могут использовать для обнаружения неинициализированных значений. Однако, поскольку выделение меток для Mbuf условно, политики также должны быть способны обрабатывать указатель на метку NULL для Mbuf, если они были загружены динамически.

В случае меток файловых систем предусмотрена специальная поддержка для постоянного хранения меток безопасности в расширенных атрибутах. Там, где это возможно, используются транзакции расширенных атрибутов, чтобы обеспечить согласованные составные обновления меток безопасности на vnode — в настоящее время такая поддержка присутствует только в файловой системе UFS2. Авторы политик могут выбрать реализацию многометочных меток объектов файловой системы с использованием одного (или нескольких) расширенных атрибутов. По соображениям эффективности метка vnode (v_label) является кэшем любой метки на диске; политики могут загружать значения в кэш при создании vnode и обновлять кэш по мере необходимости. В результате нет необходимости напрямую обращаться к расширенному атрибуту при каждой проверке контроля доступа.

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

6.5.10. Системные вызовы

В рамках MAC Framework реализован ряд системных вызовов: большинство из них поддерживают API для получения и управления метками, не зависящий от политики и доступный пользовательским приложениям.

Вызовы управления метками принимают структуру описания метки struct mac, которая содержит серию элементов метки MAC. Каждый элемент содержит строку с именем и строку со значением. Каждой политике будет предоставлена возможность запросить определённое имя элемента, позволяя политикам предоставлять несколько независимых элементов, если это необходимо. Модули политик выполняют интернализацию и экстернализацию между метками ядра и метками, предоставленными пользователем, через точки входа, что позволяет использовать различные семантики. Системные вызовы управления метками обычно обёрнуты в функции пользовательской библиотеки для выполнения выделения памяти и обработки ошибок, упрощая пользовательские приложения, которые должны управлять метками.

В ядре FreeBSD есть следующие системные вызовы, связанные с MAC:

  • mac_get_proc() может использоваться для получения метки текущего процесса.

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

  • mac_get_fd() может использоваться для получения метки объекта (файл, сокет, канал, …​), на который ссылается файловый дескриптор.

  • mac_get_file() может использоваться для получения метки объекта, на который ссылается путь в файловой системе.

  • mac_set_fd() может использоваться для запроса изменения метки объекта (файл, сокет, канал, …​), на который ссылается файловый дескриптор.

  • mac_set_file() может использоваться для запроса изменения метки объекта, указанного по пути в файловой системе.

  • mac_syscall() позволяет модулям политик создавать новые системные вызовы без изменения таблицы системных вызовов; она принимает имя целевой политики, номер операции и непрозрачный аргумент для использования политикой.

  • mac_get_pid() может использоваться для запроса метки другого процесса по его идентификатору.

  • mac_get_link() идентична mac_get_file(), но не переходит по символической ссылке, если она является конечным элементом пути, поэтому может использоваться для получения метки на символьной ссылке.

  • mac_set_link() идентична mac_set_file(), за исключением того, что она не следует по символической ссылке, если это конечный элемент пути, поэтому может использоваться для изменения метки на символьной ссылке.

  • mac_execve() идентична системному вызову execve(), но также принимает запрошенную метку, которая будет установлена для процесса при начале выполнения новой программы. Это изменение метки при выполнении называется "переходом".

  • mac_get_peer(), фактически реализованный через параметр сокета, извлекает метку удалённого узла на сокете, если она доступна.

В дополнение к этим системным вызовам, сетевые ioctl-команды SIOCSIGMAC и SIOCSIFMAC позволяют получать и устанавливать метки на сетевых интерфейсах.

6.6. Архитектура политик MAC

Политики безопасности либо непосредственно встроены в ядро, либо скомпилированы в загружаемые модули ядра, которые могут быть загружены при загрузке системы или динамически с использованием системных вызовов загрузки модулей во время выполнения. Модули политик взаимодействуют с системой через набор объявленных точек входа, предоставляя доступ к потоку системных событий и позволяя политике влиять на решения контроля доступа. Каждая политика содержит ряд элементов:

  • Необязательные параметры конфигурации для политики.

  • Централизованная реализация логики политики и параметров.

  • Необязательная реализация событий жизненного цикла политики, таких как инициализация и уничтожение.

  • Необязательная поддержка инициализации, обслуживания и удаления меток на выбранных объектах ядра.

  • Дополнительная поддержка проверки процессов пользователя и изменения меток на выбранных объектах.

  • Реализация выбранных точек входа контроля доступа, представляющих интерес для политики.

  • Объявление идентификатора политики, точек входа модуля и свойств политики.

6.6.1. Объявление политики

Модули могут быть объявлены с использованием макроса MAC_POLICY_SET(), который задаёт имя политики, предоставляет ссылку на вектор точек входа MAC, указывает флаги загрузки, определяющие, как фреймворк политик должен обрабатывать политику, и при необходимости запрашивает выделение состояния метки фреймворком.

static struct mac_policy_ops mac_policy_ops =
{
        .mpo_destroy = mac_policy_destroy,
        .mpo_init = mac_policy_init,
        .mpo_init_bpfdesc_label = mac_policy_init_bpfdesc_label,
        .mpo_init_cred_label = mac_policy_init_label,
/* ... */
        .mpo_check_vnode_setutimes = mac_policy_check_vnode_setutimes,
        .mpo_check_vnode_stat = mac_policy_check_vnode_stat,
        .mpo_check_vnode_write = mac_policy_check_vnode_write,
};

The MAC policy entry point vector, macpolicyops in this example, associates functions defined in the module with specific entry points. A complete listing of available entry points and their prototypes may be found in the MAC entry point reference section. Of specific interest during module registration are the .mpo_destroy and .mpo_init entry points. .mpo_init will be invoked once a policy is successfully registered with the module framework but prior to any other entry points becoming active. This permits the policy to perform any policy-specific allocation and initialization, such as initialization of any data or locks. .mpo_destroy will be invoked when a policy module is unloaded to permit releasing of any allocated memory and destruction of locks. Currently, these two entry points are invoked with the MAC policy list mutex held to prevent any other entry points from being invoked: this will be changed, but in the mean time, policies should be careful about what kernel primitives they invoke so as to avoid lock ordering or sleeping problems.

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

6.6.2. Флаги политик

Поле флагов объявления политики позволяет модулю предоставлять фреймворку информацию о своих возможностях во время загрузки модуля. В настоящее время определены три флага:

MPC_LOADTIME_FLAG_UNLOADOK

Этот флаг указывает, что модуль политики может быть выгружен. Если этот флаг не указан, то фреймворк политики отклонит запросы на выгрузку модуля. Этот флаг может использоваться модулями, которые выделяют состояние метки и не могут освободить это состояние во время выполнения.

MPC_LOADTIME_FLAG_NOTLATE

Этот флаг указывает, что модуль политики должен быть загружен и инициализирован на раннем этапе процесса загрузки. Если флаг указан, попытки зарегистрировать модуль после загрузки будут отклонены. Флаг может использоваться политиками, которые требуют повсеместной маркировки всех системных объектов и не могут обрабатывать объекты, не прошедшие надлежащую инициализацию политикой.

MPC_LOADTIME_FLAG_LABELMBUFS

Этот флаг указывает, что модуль политики требует маркировки Mbuf, и память всегда должна выделяться для хранения меток Mbuf. По умолчанию MAC Framework не выделяет память для хранения меток Mbuf, если хотя бы одна загруженная политика не установила этот флаг. Это заметно улучшает производительность сети, когда политики не требуют маркировки Mbuf. Существует опция ядра MAC_ALWAYS_LABEL_MBUF, которая заставляет MAC Framework выделять память для хранения меток Mbuf независимо от установки этого флага, и может быть полезной в некоторых средах.

Политики, использующие MPC_LOADTIME_FLAG_LABELMBUFS без установленного флага MPC_LOADTIME_FLAG_NOTLATE, должны корректно обрабатывать переданные NULL указатели меток Mbuf в точках входа. Это необходимо, так как Mbuf в процессе передачи без хранилища меток могут сохраняться после загрузки политики, включающей маркировку Mbuf. Если политика загружена до активации сетевой подсистемы (т.е. политика не загружается поздно), то все Mbuf гарантированно имеют хранилище меток.

6.6.3. Точки входа политики

Четыре класса точек входа предоставляются политикам, зарегистрированным в рамках системы: точки входа, связанные с регистрацией и управлением политиками, точки входа, обозначающие инициализацию, создание, уничтожение и другие события жизненного цикла объектов ядра, события, связанные с решениями контроля доступа, на которые политика может влиять, и вызовы, связанные с управлением метками на объектах. Кроме того, предоставляется точка входа mac_syscall(), позволяющая политикам расширять интерфейс ядра без регистрации новых системных вызовов.

Авторы модулей политик должны быть осведомлены о стратегии блокировок в ядре, а также о том, какие блокировки объектов доступны на различных точках входа. Им следует избегать сценариев взаимоблокировок, не захватывая нелистовые блокировки внутри точек входа, а также соблюдать протокол блокировок для доступа и изменения объектов. В частности, авторы должны учитывать, что хотя необходимые блокировки для доступа к объектам и их меткам обычно удерживаются, достаточные блокировки для изменения объекта или его метки могут отсутствовать для всех точек входа. Информация о блокировках аргументов документирована в описании точек входа фреймворка MAC.

Точки входа политики будут передавать ссылку на метку объекта вместе с самим объектом. Это позволяет помеченным политикам не знать внутренней структуры объекта, но при этом принимать решения на основе метки. Исключением из этого являются учетные данные процесса, для которые предполагается, что политики понимают их, как объект безопасности первого класса в ядре.

6.7. Справочник по точкам входа политики MAC

6.7.1. Общие точки входа модуля

6.7.1.1. mpo_init

void mpo_init(struct mac_policy_conf *conf);
ПараметрОписаниеБлокировка

conf

Определение политики MAC

Событие загрузки политики. Мьютекс списка политик удерживается, поэтому операции ожидания выполнить нельзя, а вызовы других подсистем ядра должны осуществляться с осторожностью. Если во время инициализации политики требуются потенциально блокирующие выделения памяти, их следует выполнять с использованием отдельного модуля SYSINIT().

6.7.1.2. mpo_destroy

void mpo_destroy(struct mac_policy_conf *conf);
ПараметрОписаниеБлокировка

conf

Определение политики MAC

Событие загрузки политики. Мьютекс списка политик удерживается, поэтому следует соблюдать осторожность.

6.7.1.3. mpo_syscall

int mpo_syscall(struct thread *td, int call, void *arg);
ПараметрОписаниеБлокировка

td

Вызывающий поток

call

Номер системного вызова, зависящий от политики

arg

Указатель на аргументы системного вызова

Этот точку входа предоставляет мультиплексированный системный вызов на основе политик, что позволяет политикам предоставлять дополнительные сервисы пользовательским процессам без регистрации конкретных системных вызовов. Имя политики, указанное при регистрации, используется для демультиплексирования вызовов из пользовательского пространства, а аргументы будут переданы в эту точку входа. При реализации новых сервисов модули безопасности должны убедиться, что вызывают соответствующие проверки контроля доступа из MAC-фреймворка по мере необходимости. Например, если политика реализует расширенную функциональность сигналов, она должна вызывать необходимые проверки контроля доступа сигналов для задействования MAC-фреймворка и других зарегистрированных политик.

Модули в настоящее время должны самостоятельно выполнять copyin() для данных системного вызова.

6.7.1.4. mpo_thread_userret

void mpo_thread_userret(struct thread *td);
ПараметрОписаниеБлокировка

td

Возвращающий поток

Этот точка входа позволяет модулям политики выполнять события, связанные с MAC, когда поток возвращается в пользовательское пространство, через возврат системного вызова, возврат из ловушки или иным образом. Это необходимо для политик, имеющих плавающие метки процессов, так как не всегда возможно получить блокировку процесса в произвольных точках стека во время обработки системного вызова; метки процессов могут представлять традиционные данные аутентификации, информацию об истории процесса или другие данные. Для использования этого механизма предполагаемые изменения метки учётных данных процесса могут быть сохранены в p_label, защищённом спин-блокировкой для каждой политики, а затем установить флаг TDF_ASTPENDING для потока и флаг PS_MACPENDM для процесса, чтобы запланировать вызов точки входа userret. С этой точки входа политика может создать замену учётных данных с меньшими опасениями относительно контекста блокировки. Авторам политик следует учитывать, что порядок событий, связанных с планированием AST и выполнением AST, может быть сложным и переплетённым в многопоточных приложениях.

6.7.2. Операции с метками

6.7.2.1. mpo_init_bpfdesc_label

void mpo_init_bpfdesc_label(struct label *label);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

Инициализировать метку на только что созданном bpfdesc (дескрипторе BPF). Разрешено использование режима сна.

6.7.2.2. mpo_init_cred_label

void mpo_init_cred_label(struct label *label);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

Инициализировать метку для вновь созданных учетных данных пользователя. Разрешено приостанавливать выполнение.

6.7.2.3. mpo_init_devfsdirent_label

void mpo_init_devfsdirent_label(struct label *label);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

Инициализировать метку на только что созданной записи devfs. Разрешено использование режима сна.

6.7.2.4. mpo_init_ifnet_label

void mpo_init_ifnet_label(struct label *label);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

Инициализировать метку на только что созданном сетевом интерфейсе. Разрешено приостанавливать выполнение.

6.7.2.5. mpo_init_ipq_label

void mpo_init_ipq_label(struct label *label, int flag);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

flag

Спящий/неспящий malloc(9); см. ниже

Инициализировать метку в только что созданной очереди сборки IP-фрагментов. Поле flag может принимать одно из значений M_WAITOK или M_NOWAIT и должно использоваться, чтобы избежать выполнения "спящего" malloc(9) во время этого вызова инициализации. Выделение очереди сборки IP-фрагментов часто происходит в средах, чувствительных к производительности, и реализация должна избегать "спящих" или длительных операций. Этой точке входа разрешено завершаться неудачей, что приведёт к невозможности выделения очереди сборки IP-фрагментов.

6.7.2.6. mpo_init_mbuf_label

void mpo_init_mbuf_label(int flag, struct label *label);
ПараметрОписаниеБлокировка

flag

Спящий/неспящий malloc(9); см. ниже

label

Метка политики для инициализации

Инициализировать на только что созданном заголовке пакета mbuf метку (mbuf). Поле flag может принимать одно из значений M_WAITOK или M_NOWAIT и должно использоваться, чтобы избежать выполнения "спящего" malloc(9) во время этого вызова инициализации. Выделение mbuf часто происходит в чувствительных к производительности средах, и реализация должна избегать "спящего" режима или длительных операций. Этой точке входа разрешено завершаться неудачей, что приведёт к невозможности выделения заголовка mbuf.

6.7.2.7. mpo_init_mount_label

void mpo_init_mount_label(struct label *mntlabel, struct label *fslabel);
ПараметрОписаниеБлокировка

mntlabel

Метка политики для инициализации самой точки монтирования

fslabel

Метка политики для инициализации файловой системы

Инициализировать метки на новой точке монтирования. Разрешено приостанавливать выполнение.

6.7.2.8. mpo_init_mount_fs_label

void mpo_init_mount_fs_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка для инициализации

Инициализировать метку на только что смонтированной файловой системе. Разрешено приостановление работы

6.7.2.9. mpo_init_pipe_label

void mpo_init_pipe_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка для заполнения

Инициализировать метку для только что созданного канала. Разрешено приостановление выполнения.

6.7.2.10. mpo_init_socket_label

void mpo_init_socket_label(struct label *label, int flag);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

flag

флаги malloc(9)

Инициализировать метку для нового сокета. Поле flag может принимать одно из значений M_WAITOK или M_NOWAIT и должно использоваться, чтобы избежать выполнения спящего malloc(9) во время этого вызова инициализации.

6.7.2.11. mpo_init_socket_peer_label

void mpo_init_socket_peer_label(struct label *label, int flag);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

flag

флаги malloc(9)

Инициализировать метку однорангового узла (peer) для вновь созданного сокета. Поле flag может принимать одно из значений M_WAITOK или M_NOWAIT и должно использоваться для избежания выполнения спящего malloc(9) во время этого вызова инициализации.

6.7.2.12. mpo_init_proc_label

void mpo_init_proc_label(struct label *label);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

Инициализировать метку для вновь созданного процесса. Разрешено приостановление выполнения.

6.7.2.13. mpo_init_vnode_label

void mpo_init_vnode_label(struct label *label);
ПараметрОписаниеБлокировка

label

Новая метка для инициализации

Инициализировать метку на только что созданном vnode. Разрешено приостанавливать выполнение.

6.7.2.14. mpo_destroy_bpfdesc_label

void mpo_destroy_bpfdesc_label(struct label *label);
ПараметрОписаниеБлокировка

label

bpfdesc label

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

6.7.2.15. mpo_destroy_cred_label

void mpo_destroy_cred_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка уничтожается

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

6.7.2.16. mpo_destroy_devfsdirent_label

void mpo_destroy_devfsdirent_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка уничтожается

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

6.7.2.17. mpo_destroy_ifnet_label

void mpo_destroy_ifnet_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка уничтожается

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

6.7.2.18. mpo_destroy_ipq_label

void mpo_destroy_ipq_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка уничтожается

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

6.7.2.19. mpo_destroy_mbuf_label

void mpo_destroy_mbuf_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка уничтожается

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

6.7.2.20. mpo_destroy_mount_label

void mpo_destroy_mount_label(struct label *label);
ПараметрОписаниеБлокировка

label

Точка монтирования метки уничтожается

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

6.7.2.21. mpo_destroy_mount_label

void mpo_destroy_mount_label(struct label *mntlabel, struct label *fslabel);
ПараметрОписаниеБлокировка

mntlabel

Точка монтирования метки уничтожается

fslabel

Метка файловой системы уничтожается

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

6.7.2.22. mpo_destroy_socket_label

void mpo_destroy_socket_label(struct label *label);
ПараметрОписаниеБлокировка

label

Уничтожение метки сокета

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

6.7.2.23. mpo_destroy_socket_peer_label

void mpo_destroy_socket_peer_label(struct label *peerlabel);
ПараметрОписаниеБлокировка

peerlabel

Сокет: метка однорангового узла уничтожается

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

6.7.2.24. mpo_destroy_pipe_label

void mpo_destroy_pipe_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка канала (pipe)

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

6.7.2.25. mpo_destroy_proc_label

void mpo_destroy_proc_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка процесса

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

6.7.2.26. mpo_destroy_vnode_label

void mpo_destroy_vnode_label(struct label *label);
ПараметрОписаниеБлокировка

label

Метка процесса

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

6.7.2.27. mpo_copy_mbuf_label

void mpo_copy_mbuf_label(struct label *src, struct label *dest);
ПараметрОписаниеБлокировка

src

Метка источника

dest

Метка назначения

Скопировать информацию метки из src в dest.

6.7.2.28. mpo_copy_pipe_label

void mpo_copy_pipe_label(struct label *src, struct label *dest);
ПараметрОписаниеБлокировка

src

Метка источника

dest

Метка назначения

Скопировать информацию метки из src в dest.

6.7.2.29. mpo_copy_vnode_label

void mpo_copy_vnode_label(struct label *src, struct label *dest);
ПараметрОписаниеБлокировка

src

Метка источника

dest

Метка назначения

Скопировать информацию метки из src в dest.

6.7.2.30. mpo_externalize_cred_label

int mpo_externalize_cred_label(struct label *label, char *element_name,
    struct sbuf *sb, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для вынесения во внешний ресурс

element_name

Имя политики, метка которой должна быть вынесена во внешний ресурс

sb

Буфер строки для заполнения текстовым представлением метки

claimed

Должно быть увеличено, когда element_data может быть заполнено.

Создать внешнее представление метки на основе переданной структуры метки. Внешнее представление метки состоит из текстового представления содержимого метки, которое может использоваться пользовательскими приложениями и прочитано пользователем. В настоящее время будут вызываться точки входа externalize всех политик, поэтому реализация должна проверить содержимое element_name перед попыткой заполнить sb. Если element_name не соответствует имени вашей политики, просто верните 0. Возвращайте ненулевое значение только в случае ошибки при внешнем представлении данных метки. После того как политика заполнит element_data, *claimed должен быть увеличен.

6.7.2.31. mpo_externalize_ifnet_label

int mpo_externalize_ifnet_label(struct label *label, char *element_name,
    struct sbuf *sb, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для вынесения во внешний ресурс

element_name

Имя политики, метка которой должна быть вынесена во внешний ресурс

sb

Буфер строки для заполнения текстовым представлением метки

claimed

Должно быть увеличено, когда element_data может быть заполнено.

Создать внешнее представление метки на основе переданной структуры метки. Внешнее представление метки состоит из текстового представления содержимого метки, которое может использоваться пользовательскими приложениями и прочитано пользователем. В настоящее время будут вызываться точки входа externalize всех политик, поэтому реализация должна проверить содержимое element_name перед попыткой заполнить sb. Если element_name не соответствует имени вашей политики, просто верните 0. Возвращайте ненулевое значение только в случае ошибки при внешнем представлении данных метки. После того как политика заполнит element_data, *claimed должен быть увеличен.

6.7.2.32. mpo_externalize_pipe_label

int mpo_externalize_pipe_label(struct label *label, char *element_name,
    struct sbuf *sb, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для вынесения во внешний ресурс

element_name

Имя политики, метка которой должна быть вынесена во внешний ресурс

sb

Буфер строки для заполнения текстовым представлением метки

claimed

Должно быть увеличено, когда element_data может быть заполнено.

Создать внешнее представление метки на основе переданной структуры метки. Внешнее представление метки состоит из текстового представления содержимого метки, которое может использоваться пользовательскими приложениями и прочитано пользователем. В настоящее время будут вызываться точки входа externalize всех политик, поэтому реализация должна проверить содержимое element_name перед попыткой заполнить sb. Если element_name не соответствует имени вашей политики, просто верните 0. Возвращайте ненулевое значение только в случае ошибки при внешнем представлении данных метки. После того как политика заполнит element_data, *claimed должен быть увеличен.

6.7.2.33. mpo_externalize_socket_label

int mpo_externalize_socket_label(struct label *label, char *element_name,
    struct sbuf *sb, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для вынесения во внешний ресурс

element_name

Имя политики, метка которой должна быть вынесена во внешний ресурс

sb

Буфер строки для заполнения текстовым представлением метки

claimed

Должно быть увеличено, когда element_data может быть заполнено.

Создать внешнее представление метки на основе переданной структуры метки. Внешнее представление метки состоит из текстового представления содержимого метки, которое может использоваться пользовательскими приложениями и прочитано пользователем. В настоящее время будут вызываться точки входа externalize всех политик, поэтому реализация должна проверить содержимое element_name перед попыткой заполнить sb. Если element_name не соответствует имени вашей политики, просто верните 0. Возвращайте ненулевое значение только в случае ошибки при внешнем представлении данных метки. После того как политика заполнит element_data, *claimed должен быть увеличен.

6.7.2.34. mpo_externalize_socket_peer_label

int mpo_externalize_socket_peer_label(struct label *label, char *element_name,
    struct sbuf *sb, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для вынесения во внешний ресурс

element_name

Имя политики, метка которой должна быть вынесена во внешний ресурс

sb

Буфер строки для заполнения текстовым представлением метки

claimed

Должно быть увеличено, когда element_data может быть заполнено.

Создать внешнее представление метки на основе переданной структуры метки. Внешнее представление метки состоит из текстового представления содержимого метки, которое может использоваться пользовательскими приложениями и прочитано пользователем. В настоящее время будут вызываться точки входа externalize всех политик, поэтому реализация должна проверить содержимое element_name перед попыткой заполнить sb. Если element_name не соответствует имени вашей политики, просто верните 0. Возвращайте ненулевое значение только в случае ошибки при внешнем представлении данных метки. После того как политика заполнит element_data, *claimed должен быть увеличен.

6.7.2.35. mpo_externalize_vnode_label

int mpo_externalize_vnode_label(struct label *label, char *element_name,
    struct sbuf *sb, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для вынесения во внешний ресурс

element_name

Имя политики, метка которой должна быть вынесена во внешний ресурс

sb

Буфер строки для заполнения текстовым представлением метки

claimed

Должно быть увеличено, когда element_data может быть заполнено.

Создать внешнее представление метки на основе переданной структуры метки. Внешнее представление метки состоит из текстового представления содержимого метки, которое может использоваться пользовательскими приложениями и прочитано пользователем. В настоящее время будут вызываться точки входа externalize всех политик, поэтому реализация должна проверить содержимое element_name перед попыткой заполнить sb. Если element_name не соответствует имени вашей политики, просто верните 0. Возвращайте ненулевое значение только в случае ошибки при внешнем представлении данных метки. После того как политика заполнит element_data, *claimed должен быть увеличен.

6.7.2.36. mpo_internalize_cred_label

int mpo_internalize_cred_label(struct label *label, char *element_name,
    char *element_data, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для заполнения

element_name

Имя политики, метка которой должна быть приведена к внутреннему представлению

element_data

Текстовые данные для преобразования к внутреннему представлению

claimed

Должно увеличиваться, когда данные могут быть успешно преобразовываться вовнутреннее представление.

Создать внутреннюю структуру меток на основе данных метки вов нешнем представлении в текстовом формате. В настоящее время, при запросе преобразования во внутреннее представление вызываются точки входа internalize всех политик, поэтому реализация должна сравнивать содержимое element_name со своим именем, чтобы убедиться, что она должна преобразовывать данные в element_data. Как и в точках входа externalize, точка входа должна возвращать 0, если element_name не совпадает с её собственным именем, или когда данные могут быть успешно преобразованы, в этом случае *claimed должен быть увеличен.

6.7.2.37. mpo_internalize_ifnet_label

int mpo_internalize_ifnet_label(struct label *label, char *element_name,
    char *element_data, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для заполнения

element_name

Имя политики, метка которой должна быть приведена к внутреннему представлению

element_data

Текстовые данные для преобразования к внутреннему представлению

claimed

Должно увеличиваться, когда данные могут быть успешно преобразовываться вовнутреннее представление.

Создать внутреннюю структуру меток на основе данных метки вов нешнем представлении в текстовом формате. В настоящее время, при запросе преобразования во внутреннее представление вызываются точки входа internalize всех политик, поэтому реализация должна сравнивать содержимое element_name со своим именем, чтобы убедиться, что она должна преобразовывать данные в element_data. Как и в точках входа externalize, точка входа должна возвращать 0, если element_name не совпадает с её собственным именем, или когда данные могут быть успешно преобразованы, в этом случае *claimed должен быть увеличен.

6.7.2.38. mpo_internalize_pipe_label

int mpo_internalize_pipe_label(struct label *label, char *element_name,
    char *element_data, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для заполнения

element_name

Имя политики, метка которой должна быть приведена к внутреннему представлению

element_data

Текстовые данные для преобразования к внутреннему представлению

claimed

Должно увеличиваться, когда данные могут быть успешно преобразовываться вовнутреннее представление.

Создать внутреннюю структуру меток на основе данных метки вов нешнем представлении в текстовом формате. В настоящее время, при запросе преобразования во внутреннее представление вызываются точки входа internalize всех политик, поэтому реализация должна сравнивать содержимое element_name со своим именем, чтобы убедиться, что она должна преобразовывать данные в element_data. Как и в точках входа externalize, точка входа должна возвращать 0, если element_name не совпадает с её собственным именем, или когда данные могут быть успешно преобразованы, в этом случае *claimed должен быть увеличен.

6.7.2.39. mpo_internalize_socket_label

int mpo_internalize_socket_label(struct label *label, char *element_name,
    char *element_data, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для заполнения

element_name

Имя политики, метка которой должна быть приведена к внутреннему представлению

element_data

Текстовые данные для преобразования к внутреннему представлению

claimed

Должно увеличиваться, когда данные могут быть успешно преобразовываться вовнутреннее представление.

Создать внутреннюю структуру меток на основе данных метки вов нешнем представлении в текстовом формате. В настоящее время, при запросе преобразования во внутреннее представление вызываются точки входа internalize всех политик, поэтому реализация должна сравнивать содержимое element_name со своим именем, чтобы убедиться, что она должна преобразовывать данные в element_data. Как и в точках входа externalize, точка входа должна возвращать 0, если element_name не совпадает с её собственным именем, или когда данные могут быть успешно преобразованы, в этом случае *claimed должен быть увеличен.

6.7.2.40. mpo_internalize_vnode_label

int mpo_internalize_vnode_label(struct label *label, char *element_name,
    char *element_data, int *claimed);
ПараметрОписаниеБлокировка

label

Метка для заполнения

element_name

Имя политики, метка которой должна быть приведена к внутреннему представлению

element_data

Текстовые данные для преобразования к внутреннему представлению

claimed

Должно увеличиваться, когда данные могут быть успешно преобразовываться вовнутреннее представление.

Создать внутреннюю структуру меток на основе данных метки вов нешнем представлении в текстовом формате. В настоящее время, при запросе преобразования во внутреннее представление вызываются точки входа internalize всех политик, поэтому реализация должна сравнивать содержимое element_name со своим именем, чтобы убедиться, что она должна преобразовывать данные в element_data. Как и в точках входа externalize, точка входа должна возвращать 0, если element_name не совпадает с её собственным именем, или когда данные могут быть успешно преобразованы, в этом случае *claimed должен быть увеличен.

6.7.3. События метки

Этот класс точек входа используется фреймворком MAC для разрешения политикам поддерживать информацию о метках на объектах ядра. Для каждого помеченного объекта ядра, представляющего интерес для политики MAC, могут быть зарегистрированы точки входа для соответствующих событий жизненного цикла. Все объекты реализуют хуки инициализации, создания и уничтожения. Некоторые объекты также реализуют перемаркировку, позволяя пользовательским процессам изменять метки на объектах. Некоторые объекты также реализуют специфичные для объекта события, такие как события меток, связанные с повторной сборкой IP. Типичный помеченный объект будет иметь следующий жизненный цикл точек входа:

Label initialization          o
(object-specific wait)         \
Label creation                  o
                                 \
Relabel events,                   o--<--.
Various object-specific,          |     |
Access control events             ~-->--o
                                         \
Label destruction                         o

Инициализация меток позволяет политикам выделять память и устанавливать начальные значения для меток без контекста использования объекта. Слот метки, выделенный для политики, по умолчанию будет обнулен, поэтому некоторым политикам может не потребоваться выполнять инициализацию.

Создание метки происходит, когда структура ядра связывается с реальным объектом ядра. Например, Mbuf могут быть выделены и оставаться неиспользованными в пуле до тех пор, пока они не понадобятся. Выделение mbuf приводит к инициализации метки на mbuf, но создание mbuf происходит, когда mbuf связывается с датаграммой. Обычно для события создания предоставляется контекст, включая обстоятельства создания и метки других значимых объектов в процессе создания. Например, когда mbuf создаётся из сокета, сокет и его метка будут переданы зарегистрированным политикам в дополнение к новому mbuf и его метке. Выделение памяти в событиях создания не рекомендуется, так как это может происходить в чувствительных к производительности участках ядра; кроме того, вызовы создания не могут завершиться неудачей, поэтому невозможность выделить память не может быть сообщена.

События, привящанные к объектам, обычно не попадают в другие классы событий меток, но, как правило, предоставляют возможность изменить или обновить метку объекта на основе дополнительного контекста. Например, метка в очереди сборки IP-фрагментов может быть обновлена во время точки входа MAC_UPDATE_IPQ в результате принятия дополнительного mbuf в эту очередь.

События контроля доступа подробно рассматриваются в следующем разделе.

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

В дополнение к меткам, связанным с определёнными объектами ядра, существует дополнительный класс меток: временные метки. Эти метки используются для хранения информации об обновлениях, отправляемых пользовательскими процессами. Они инициализируются и уничтожаются так же, как и другие типы меток, но событие создания — это MAC_INTERNALIZE, которое принимает пользовательскую метку для преобразования во внутреннее представление в ядре.

6.7.3.1. Действия с событиями меток объектов файловой системы

6.7.3.1.1. mpo_associate_vnode_devfs
void mpo_associate_vnode_devfs(struct mount *mp, struct label *fslabel,
    struct devfs_dirent *de, struct label *delabel, struct vnode *vp,
    struct label *vlabel);
ПараметрОписаниеБлокировка

mp

Точка монтирования devfs

fslabel

Метка файловой системы devfs (mp→mnt_fslabel)

de

Запись каталога devfs

delabel

Метка политики, связанная с de

vp

узел vnode, связанный с de

vlabel

Метка политики, связанная с vp

Заполнить метку (vlabel) для только что созданного devfs vnode на основе записи каталога devfs, переданной в de, и её метки.

6.7.3.1.2. mpo_associate_vnode_extattr
int mpo_associate_vnode_extattr(struct mount *mp, struct label *fslabel,
    struct vnode *vp, struct label *vlabel);
ПараметрОписаниеБлокировка

mp

Точка монтирования файловой системы

fslabel

Метка файловой системы

vp

Узел vnode для метки

vlabel

Метка политики, связанная с vp

Попытка получить метку для vp из расширенных атрибутов файловой системы. В случае успеха возвращается значение 0. Если получение расширенных атрибутов не поддерживается, допустимым резервным вариантом является копирование fslabel в vlabel. В случае ошибки должно быть возвращено соответствующее значение errno.

6.7.3.1.3. mpo_associate_vnode_singlelabel
void mpo_associate_vnode_singlelabel(struct mount *mp, struct label *fslabel,
    struct vnode *vp, struct label *vlabel);
ПараметрОписаниеБлокировка

mp

Точка монтирования файловой системы

fslabel

Метка файловой системы

vp

Узел vnode для метки

vlabel

Метка политики, связанная с vp

На файловых системах без поддержки multilabel эта точка входа вызывается для установки метки политики для vp на основе метки файловой системы fslabel.

6.7.3.1.4. mpo_create_devfs_device
void mpo_create_devfs_device(dev_t dev, struct devfs_dirent *devfs_dirent,
    struct label *label);
ПараметрОписаниеБлокировка

dev

Устройство, соответствующее devfs_dirent

devfs_dirent

Запись в каталоге devfs, для которой создается метка.

label

Метка для devfs_dirent, которую нужно заполнить.

Заполнить метку на devfs_dirent, создаваемом для переданного устройства. Этот вызов будет выполнен при монтировании файловой системы устройств, её восстановлении или при появлении нового устройства.

6.7.3.1.5. mpo_create_devfs_directory
void mpo_create_devfs_directory(char *dirname, int dirnamelen,
    struct devfs_dirent *devfs_dirent, struct label *label);
ПараметрОписаниеБлокировка

dirname

Имя создаваемого каталога

namelen

Длина строки dirname

devfs_dirent

Запись в devfs для создаваемого каталога.

Заполнить метку на devfs_dirent, создаваемом для переданного каталога. Этот вызов будет выполнен при монтировании файловой системы устройств, её восстановлении или при появлении нового устройства, требующего определённой иерархии каталогов.

void mpo_create_devfs_symlink(struct ucred *cred, struct mount *mp,
    struct devfs_dirent *dd, struct label *ddlabel, struct devfs_dirent *de,
    struct label *delabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

mp

Точка монтирования devfs

dd

Назначения cсылки

ddlabel

Метка, связанная с dd

de

Символьная ссылка записи

delabel

Метка, связанная с de

Заполнить метку (delabel) для новой структуры devfs(5) символьной ссылки.

6.7.3.1.7. mpo_create_vnode_extattr
int mpo_create_vnode_extattr(struct ucred *cred, struct mount *mp,
    struct label *fslabel, struct vnode *dvp, struct label *dlabel,
    struct vnode *vp, struct label *vlabel, struct componentname *cnp);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

mount

Точка монтирования файловой системы

label

Метка файловой системы

dvp

Родительский каталог vnode

dlabel

Метка, связанная с dvp

vp

Вновь созданная vnode

vlabel

Метка политики, связанная с vp

cnp

Название компонента для vp

Записать метку для vp в соответствующий расширенный атрибут. Если запись прошла успешно, заполняет vlabel меткой и возвращает 0. В противном случае вернет соответствующую ошибку.

6.7.3.1.8. mpo_create_mount
void mpo_create_mount(struct ucred *cred, struct mount *mp, struct label *mnt,
    struct label *fslabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

mp

Объект; файловая система, которая монтируется

mntlabel

Метка политики для заполнения в mp

fslabel

Метка политики для файловой системы, монтируемой в mp.

Заполнить метки на точке монтирования, создаваемой переданными учетными данными субъекта. Этот вызов будет выполнен при монтировании новой файловой системы.

6.7.3.1.9. mpo_create_root_mount
void mpo_create_root_mount(struct ucred *cred, struct mount *mp,
    struct label *mntlabel, struct label *fslabel);
ПараметрОписаниеБлокировка

См. mpo_create_mount.

Заполнить метки на точке монтирования, создаваемой переданными учетными данными субъекта. Этот вызов будет выполнен при монтировании корневой файловой системы после mpo_create_mount;.

6.7.3.1.10. mpo_relabel_vnode
void mpo_relabel_vnode(struct ucred *cred, struct vnode *vp,
    struct label *vnodelabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

vnode для перемаркировки

vnodelabel

Существующая метка политики для vp

newlabel

Новая, возможно частичная метка для замены vnodelabel

Обновить метку на переданном vnode с учетом переданной обновленной метки vnode и переданных учетных данных субъекта.

6.7.3.1.11. mpo_setlabel_vnode_extattr
int mpo_setlabel_vnode_extattr(struct ucred *cred, struct vnode *vp,
    struct label *vlabel, struct label *intlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

vnode, для которой записывается метка

vlabel

Метка политики, связанная с vp

intlabel

Метка для записи

Записать политику из intlabel в расширенный атрибут. Этот метод вызывается из vop_stdcreatevnode_ea.

6.7.3.1.12. mpo_update_devfsdirent
void mpo_update_devfsdirent(struct devfs_dirent *devfs_dirent,
    struct label *direntlabel, struct vnode *vp, struct label *vnodelabel);
ПараметрОписаниеБлокировка

devfs_dirent

Объект; каталожная запись devfs

direntlabel

Метка политики для devfs_dirent, которая будет обновлена.

vp

Родительский vnode

Заблокирован

vnodelabel

Метка политики для vp

Обновить метку devfs_dirent из переданной метки devfs vnode. Этот вызов будет выполнен, когда devfs vnode успешно перемаркирован, чтобы зафиксировать изменение метки, чтобы оно сохранилось, даже если vnode будет переиспользован. Он также будет выполнен при создании символьной ссылки в devfs после вызова mac_vnode_create_from_vnode для инициализации метки vnode.

6.7.3.2. Действия с событиями меток объектов IPC

6.7.3.2.1. mpo_create_mbuf_from_socket
void mpo_create_mbuf_from_socket(struct socket *so, struct label *socketlabel,
    struct mbuf *m, struct label *mbuflabel);
ПараметрОписаниеБлокировка

socket

Сокет

Блокировка сокетов — работа в процессе

socketlabel

Метка политики для socket

m

Объект; mbuf

mbuflabel

Метка политики для заполнения для m

Установить метку на только что созданном заголовке mbuf из переданной метки сокета. Этот вызов выполняется, когда новый датаграмма или сообщение генерируется сокетом и сохраняется в переданном mbuf.

6.7.3.2.2. mpo_create_pipe
void mpo_create_pipe(struct ucred *cred, struct pipe *pipe,
    struct label *pipelabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

pipelabel

Метка политики, связанная с pipe

Установить метку на только что созданном канале из переданных учетных данных субъекта. Этот вызов выполняется при создании нового канала.

6.7.3.2.3. mpo_create_socket
void mpo_create_socket(struct ucred *cred, struct socket *so,
    struct label *socketlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Неизменяемый

so

Объект; сокет для добавления метки

socketlabel

Метка для заполнения для so

Установить метку на новом сокете из переданных учетных данных субъекта. Этот вызов выполняется при создании сокета.

6.7.3.2.4. mpo_create_socket_from_socket
void mpo_create_socket_from_socket(struct socket *oldsocket,
    struct label *oldsocketlabel, struct socket *newsocket,
    struct label *newsocketlabel);
ПараметрОписаниеБлокировка

oldsocket

Сокет, вызвавший listen

oldsocketlabel

Метка политики, связанная с oldsocket

newsocket

Новый сокет

newsocketlabel

Метка политики, связанная с newsocketlabel

Создать метку сокета newsocket, только что принявшему соединение через accept(2), на основе сокета oldsocket, вызвавшего listen(2) .

6.7.3.2.5. mpo_relabel_pipe
void mpo_relabel_pipe(struct ucred *cred, struct pipe *pipe,
    struct label *oldlabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

oldlabel

Текущая метка политики, связанная с pipe

newlabel

Обновление метки политики для применения к pipe

Применить новую метку newlabel к pipe.

6.7.3.2.6. mpo_relabel_socket
void mpo_relabel_socket(struct ucred *cred, struct socket *so,
    struct label *oldlabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Неизменяемый

so

Объект; сокет

oldlabel

Текущая метка для so

newlabel

Метка обновления для so

Обновить метку на сокете из переданного обновления метки сокета.

6.7.3.2.7. mpo_set_socket_peer_from_mbuf
void mpo_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct label *mbuflabel,
    struct label *oldlabel, struct label *newlabel);
ПараметрОписаниеБлокировка

mbuf

Первый датаграмм, полученный через сокет

mbuflabel

Метка для mbuf

oldlabel

Текущая метка для сокета

newlabel

Метка политики для заполнения сокета

Установить метку однорангового узла на потоковом сокете из переданной метки mbuf. Этот вызов будет выполнен при получении первого датаграммы потоковым сокетом, за исключением сокетов домена Unix.

6.7.3.2.8. mpo_set_socket_peer_from_socket
void mpo_set_socket_peer_from_socket(struct socket *oldsocket,
    struct label *oldsocketlabel, struct socket *newsocket,
    struct label *newsocketpeerlabel);
ПараметрОписаниеБлокировка

oldsocket

Локальный сокет

oldsocketlabel

Метка политики для oldsocket

newsocket

Сокет однорангового узла (peer socket)

newsocketpeerlabel

Метка политики для заполнения для newsocket

Установите метку однорангового узла на потоковом UNIX-сокете из переданной конечной точки удаленного сокета. Этот вызов будет выполнен при соединении пары сокетов и будет произведен для обеих конечных точек.

6.7.3.3. Действия с событиями меток сетевых объектов

6.7.3.3.1. mpo_create_bpfdesc
void mpo_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d,
    struct label *bpflabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Неизменяемый

bpf_d

Объект; дескриптор bpf

bpf

Метка политики для заполнения для bpf_d

Установить метку на новом дескрипторе BPF из переданных учётных данных субъекта. Этот вызов будет выполнен при открытии узла устройства BPF процессом с переданными учётными данными субъекта.

6.7.3.3.2. mpo_create_ifnet
void mpo_create_ifnet(struct ifnet *ifnet, struct label *ifnetlabel);
ПараметрОписаниеБлокировка

ifnet

Сетевой интерфейс

ifnetlabel

Метка политики для заполнения для ifnet

Установить метку на вновь созданном интерфейсе. Этот вызов может быть выполнен, когда новое физическое устройство становится доступным системе, или когда псевдо-интерфейс создаётся во время загрузки или в результате действия пользователя.

6.7.3.3.3. mpo_create_ipq
void mpo_create_ipq(struct mbuf *fragment, struct label *fragmentlabel,
    struct ipq *ipq, struct label *ipqlabel);
ПараметрОписаниеБлокировка

fragment

Первый полученный IP-фрагмент

fragmentlabel

Метка политики для fragment

ipq

Очередь повторной сборки IP, которой добавляетя метка

ipqlabel

Метка политики для заполнения в ipq

Установить метку на вновь созданной очереди сборки IP-фрагментов из заголовка mbuf первого полученного фрагмента.

6.7.3.3.4. mpo_create_datagram_from_ipq
void mpo_create_create_datagram_from_ipq(struct ipq *ipq,
    struct label *ipqlabel, struct mbuf *datagram, struct label *datagramlabel);
ПараметрОписаниеБлокировка

ipq

Очередь повторной сборки IP

ipqlabel

Метка политики для ipq

datagram

Датаграмма для добавления метки

datagramlabel

Метка политики для заполнения в datagramlabel

Установите метку на вновь собранный IP-датаграмму из очереди сборки IP-фрагментов, из которой он был сгенерирован.

6.7.3.3.5. mpo_create_fragment
void mpo_create_fragment(struct mbuf *datagram, struct label *datagramlabel,
    struct mbuf *fragment, struct label *fragmentlabel);
ПараметрОписаниеБлокировка

datagram

Датаграмма

datagramlabel

Метка политики для datagram

fragment

Фрагмент, которому будет установлена метка

fragmentlabel

Метка политики для заполнения для datagram

Установить метку на заголовке mbuf вновь созданного IP-фрагмента из метки на заголовке mbuf датаграммы, из которой он был сгенерирован.

6.7.3.3.6. mpo_create_mbuf_from_mbuf
void mpo_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct label *oldmbuflabel,
    struct mbuf *newmbuf, struct label *newmbuflabel);
ПараметрОписаниеБлокировка

oldmbuf

Существующий (исходный) mbuf

oldmbuflabel

Метка политики для oldmbuf

newmbuf

Новый mbuf для добавления метки

newmbuflabel

Метка политики для заполнения в newmbuf

Установить метку в заголовке mbuf для вновь созданной датаграммы на основе заголовка mbuf существующей датаграммы. Этот вызов может быть выполнен в ряде ситуаций, включая случаи, когда для mbuf заново выделяется память для целей выравнивания.

6.7.3.3.7. mpo_create_mbuf_linklayer
void mpo_create_mbuf_linklayer(struct ifnet *ifnet, struct label *ifnetlabel,
    struct mbuf *mbuf, struct label *mbuflabel);
ПараметрОписаниеБлокировка

ifnet

Сетевой интерфейс

ifnetlabel

Метка политики для ifnet

mbuf

заголовок mbuf для новой датаграммы

mbuflabel

Метка политики для заполнения для mbuf

Установить метку в заголовке mbuf для вновь созданной датаграммы, сгенерированного для целей ответа на канальном уровне для переданного интерфейса. Этот вызов может быть выполнен в ряде ситуаций, включая ответы ARP или ND6 в стеках IPv4 и IPv6.

6.7.3.3.8. mpo_create_mbuf_from_bpfdesc
void mpo_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct label *bpflabel,
    struct mbuf *mbuf, struct label *mbuflabel);
ПараметрОписаниеБлокировка

bpf_d

Дескриптор BPF

bpflabel

Метка политики для bpflabel

mbuf

Новый mbuf для добавления метки

mbuflabel

Метка политики для заполнения mbuf

Установить метку на заголовок mbuf вновь созданной датаграммы, сгенерированной с использованием переданного дескриптора BPF. Этот вызов выполняется при записи в устройство BPF, связанное с переданным дескриптором BPF.

6.7.3.3.9. mpo_create_mbuf_from_ifnet
void mpo_create_mbuf_from_ifnet(struct ifnet *ifnet, struct label *ifnetlabel,
    struct mbuf *mbuf, struct label *mbuflabel);
ПараметрОписаниеБлокировка

ifnet

Сетевой интерфейс

ifnetlabel

Метка политики для ifnetlabel

mbuf

заголовок mbuf для новой датаграммы

mbuflabel

Метка политики для заполнения для mbuf

Установить метку на заголовке mbuf вновь созданной датаграммы, сгенерированной из переданного сетевого интерфейса.

6.7.3.3.10. mpo_create_mbuf_multicast_encap
void mpo_create_mbuf_multicast_encap(struct mbuf *oldmbuf,
    struct label *oldmbuflabel, struct ifnet *ifnet, struct label *ifnetlabel,
    struct mbuf *newmbuf, struct label *newmbuflabel);
ПараметрОписаниеБлокировка

oldmbuf

Заголовок mbuf для существующего датаграммы

oldmbuflabel

Метка политики для oldmbuf

ifnet

Сетевой интерфейс

ifnetlabel

Метка политики для ifnet

newmbuf

Заголовок mbuf для пометки новой датаграммы

newmbuflabel

Метка политики для заполнения в newmbuf

Установить метку в заголовке mbuf для вновь созданной датаграммы, сгенерированной из существующей переданной датаграммы, при её обработке переданным интерфейсом мультикастовой инкапсуляции. Этот вызов происходит при доставке mbuf с использованием виртуального интерфейса.

6.7.3.3.11. mpo_create_mbuf_netlayer
void mpo_create_mbuf_netlayer(struct mbuf *oldmbuf, struct label *oldmbuflabel,
    struct mbuf *newmbuf, struct label *newmbuflabel);
ПараметрОписаниеБлокировка

oldmbuf

Полученная датаграмма

oldmbuflabel

Метка политики для oldmbuf

newmbuf

Вновь созданная датаграмма

newmbuflabel

Метка политики для newmbuf

Установить метку на заголовок mbuf вновь созданной датаграммы, сгенерированной стеком IP в ответ на полученную датаграмму (oldmbuf). Этот вызов может быть выполнен в различных ситуациях, включая ответ на датаграммы ICMP-запросов.

6.7.3.3.12. mpo_fragment_match
int mpo_fragment_match(struct mbuf *fragment, struct label *fragmentlabel,
    struct ipq *ipq, struct label *ipqlabel);
ПараметрОписаниеБлокировка

fragment

Фрагмент IP-датаграммы

fragmentlabel

Метка политики для fragment

ipq

Очередь сборки IP-фрагментов

ipqlabel

Метка политики для ipq

Определить, соответствует ли заголовок mbuf, содержащий фрагмент IP-датаграммы (fragment), метке переданной очереди сборки IP-фрагментов (ipq). Возвращает (1) при успешном совпадении или (0) при отсутствии совпадения. Этот вызов выполняется, когда IP-стек пытается найти существующую очередь сборки фрагментов для вновь полученного фрагмента; если поиск не удаётся, для фрагмента может быть создана новая очередь сборки. Политики могут использовать эту точку входа, чтобы предотвратить сборку в остальном подходящих IP-фрагментов, если политика не разрешает их сборку на основе метки или другой информации.

6.7.3.3.13. mpo_relabel_ifnet
void mpo_relabel_ifnet(struct ucred *cred, struct ifnet *ifnet,
    struct label *ifnetlabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

ifnet

Объект; Сетевой интерфейс

ifnetlabel

Метка политики для ifnet

newlabel

Метка обновления для применения к ifnet

Обновить метку сетевого интерфейса, ifnet, на основе переданной новой метки, newlabel, и переданных учетных данных субъекта, cred.

6.7.3.3.14. mpo_update_ipq
void mpo_update_ipq(struct mbuf *fragment, struct label *fragmentlabel,
    struct ipq *ipq, struct label *ipqlabel);
ПараметрОписаниеБлокировка

mbuf

IP фрагмент

mbuflabel

Метка политики для mbuf

ipq

Очередь сборки IP-фрагментов

ipqlabel

Метка политики для обновления для ipq

Обновить метку в очереди сборки IP-фрагментов (ipq) на основе принятия переданного заголовка IP-фрагмента mbuf (mbuf).

6.7.3.4. Действия с событиями меток процессов

6.7.3.4.1. mpo_create_cred
void mpo_create_cred(struct ucred *parent_cred, struct ucred *child_cred);
ПараметрОписаниеБлокировка

parent_cred

Учетные данные субъекта‐родителя

child_cred

Учётные данные дочернего субъекта

Установить метку вновь созданного субъекта из переданного субъекта. Этот вызов будет выполнен при вызове crcopy(9) для только что созданной структуры struct ucred. Этот вызов не следует путать с событием создания или ветвления процесса.

6.7.3.4.2. mpo_execve_transition
void mpo_execve_transition(struct ucred *old, struct ucred *new,
    struct vnode *vp, struct label *vnodelabel);
ПараметрОписаниеБлокировка

old

Учетные данные существующего субъекта

Неизменяемый

new

Учетные данные нового субъекта для добавления метки

vp

Файл для выполнения

Заблокирован

vnodelabel

Метка политики для vp

Обновить метку учетных данных вновь созданного субъекта (new) на основе переданных учетных данных существующего субъекта (old) в соответствии с переходом метки, вызванным выполнением переданного vnode (vp). Этот вызов происходит, когда процесс выполняет переданный vnode, и одна из политик возвращает успех из точки входа mpo_execve_will_transition. Политики могут выбрать реализацию этого вызова просто путем вызова mpo_create_cred и передачи двух субъектов учетных данных, чтобы не реализовывать событие перехода. Политики не должны оставлять эту точку входа нереализованной, если они реализуют mpo_create_cred, даже если они не реализуют mpo_execve_will_transition.

6.7.3.4.3. mpo_execve_will_transition
int mpo_execve_will_transition(struct ucred *old, struct vnode *vp,
    struct label *vnodelabel);
ПараметрОписаниеБлокировка

old

Учетные данные субъекта перед execve(2)

Неизменяемый

vp

Файл для выполнения

vnodelabel

Метка политики для vp

Определить, будет ли политика выполнять событие перехода в результате выполнения переданного vnode с использованием переданных учетных данных субъекта. Вернуть 1, если переход требуется, и 0, если нет. Даже если политика возвращает 0, она должна корректно обрабатывать неожиданный вызов mpo_execve_transition, так как этот вызов может произойти из-за запроса перехода другой политикой.

6.7.3.4.4. mpo_create_proc0
void mpo_create_proc0(struct ucred *cred);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта для заполнения

Создать учетные данные субъекта процесса 0, родителя всех процессов ядра.

6.7.3.4.5. mpo_create_proc1
void mpo_create_proc1(struct ucred *cred);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта для заполнения

Создать учетные данные субъекта процесса 1, родителя всех пользовательских процессов.

6.7.3.4.6. mpo_relabel_cred
void mpo_relabel_cred(struct ucred *cred, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

newlabel

Обновление метки для применения к cred

Обновить метку на учетных данных субъекта из переданной обновляемой метки.

6.7.4. Проверки контроля доступа

Точки входа контроля доступа позволяют модулям политики влиять на решения по контролю доступа, принимаемые ядром. Обычно, хотя и не всегда, аргументы точки входа контроля доступа включают одно или несколько удостоверяющих полномочий, информацию (возможно, включая метку) для любых других объектов, участвующих в операции. Точка входа контроля доступа может вернуть 0 для разрешения операции или значение ошибки errno(2). Результаты вызова точки входа через различные зарегистрированные модули политики будут объединены следующим образом: если все модули разрешают успешное выполнение операции, будет возвращен успех. Если один или несколько модулей возвращают ошибку, будет возвращена ошибка. Если более одного модуля возвращают ошибку, значение errno, которое будет возвращено пользователю, выбирается с использованием следующего приоритета, реализованного функцией error_select() в kern_mac.c:

Наивысший приоритет

EDEADLK

EINVAL

ESRCH

EACCES

Наименьший приоритет

EPERM

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

6.7.4.1. mpo_check_bpfdesc_receive

int mpo_check_bpfdesc_receive(struct bpf_d *bpf_d, struct label *bpflabel,
    struct ifnet *ifnet, struct label *ifnetlabel);
ПараметрОписаниеБлокировка

bpf_d

Субъект; Дескриптор BPF

bpflabel

Метка политики для bpf_d

ifnet

Объект; сетевой интерфейс

ifnetlabel

Метка политики для ifnet

Определить, должен ли framework MAC разрешать доставку датаграмм с переданного интерфейса в буферы переданного BPF-дескриптора. Возвращает (0) при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии меток, EPERM при отсутствии привилегий.

6.7.4.2. mpo_check_kenv_dump

int mpo_check_kenv_dump(struct ucred *cred);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Определить, следует ли разрешить субъекту получать доступ к окружению ядра (см. kenv(2)).

6.7.4.3. mpo_check_kenv_get

int mpo_check_kenv_get(struct ucred *cred, char *name);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

name

Имя переменной окружения ядра

Определить, следует ли разрешить субъекту получать значение указанной переменной окружения ядра.

6.7.4.4. mpo_check_kenv_set

int mpo_check_kenv_set(struct ucred *cred, char *name);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

name

Имя переменной окружения ядра

Определить, следует ли разрешить субъекту устанавливать указанную переменную окружения ядра.

6.7.4.5. mpo_check_kenv_unset

int mpo_check_kenv_unset(struct ucred *cred, char *name);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

name

Имя переменной окружения ядра

Определить, следует ли разрешить субъекту сбросить указанную переменную окружения ядра.

6.7.4.6. mpo_check_kld_load

int mpo_check_kld_load(struct ucred *cred, struct vnode *vp,
    struct label *vlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

vnode модуля ядра

vlabel

Метка, связанная с vp

Определить, следует ли разрешить субъекту загружать указанный файл модуля.

6.7.4.7. mpo_check_kld_stat

int mpo_check_kld_stat(struct ucred *cred);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Определить, следует ли разрешить субъекту получать список загруженных файлов модулей ядра и связанную с ними статистику.

6.7.4.8. mpo_check_kld_unload

int mpo_check_kld_unload(struct ucred *cred);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Определить, следует ли разрешить субъекту выгружать модуль ядра.

6.7.4.9. mpo_check_pipe_ioctl

int mpo_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
    struct label *pipelabel, unsigned long cmd, void *data);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

pipelabel

Метка политики, связанная с pipe

cmd

команда nioctl(2)

data

данные ioctl(2)

Определить, следует ли разрешить субъекту выполнять указанный вызов ioctl(2).

6.7.4.10. mpo_check_pipe_poll

int mpo_check_pipe_poll(struct ucred *cred, struct pipe *pipe,
    struct label *pipelabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

pipelabel

Метка политики, связанная с pipe

Определить, следует ли разрешить субъекту опрашивать pipe.

6.7.4.11. mpo_check_pipe_read

int mpo_check_pipe_read(struct ucred *cred, struct pipe *pipe,
    struct label *pipelabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

pipelabel

Метка политики, связанная с pipe

Определить, следует ли разрешить субъекту доступ на чтение к pipe.

6.7.4.12. mpo_check_pipe_relabel

int mpo_check_pipe_relabel(struct ucred *cred, struct pipe *pipe,
    struct label *pipelabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

pipelabel

Текущая метка политики, связанная с pipe

newlabel

Обновление метки до pipelabel

Определить, следует ли разрешить субъекту изменять метку pipe.

6.7.4.13. mpo_check_pipe_stat

int mpo_check_pipe_stat(struct ucred *cred, struct pipe *pipe,
    struct label *pipelabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

pipelabel

Метка политики, связанная с pipe

Определить, следует ли разрешить субъекту получать статистику, связанную с pipe.

6.7.4.14. mpo_check_pipe_write

int mpo_check_pipe_write(struct ucred *cred, struct pipe *pipe,
    struct label *pipelabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

pipe

Канал

pipelabel

Метка политики, связанная с pipe

Определить, следует ли разрешить субъекту запись в pipe.

6.7.4.15. mpo_check_socket_bind

int mpo_check_socket_bind(struct ucred *cred, struct socket *socket,
    struct label *socketlabel, struct sockaddr *sockaddr);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

socket

Сокет для привязки

socketlabel

Метка политики для socket

sockaddr

Адрес socket

6.7.4.16. mpo_check_socket_connect

int mpo_check_socket_connect(struct ucred *cred, struct socket *socket,
    struct label *socketlabel, struct sockaddr *sockaddr);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

socket

Сокет для подключения

socketlabel

Метка политики для socket

sockaddr

Адрес socket

Определить, может ли субъект с учётными данными (cred) подключить переданный сокет (socket) к переданному адресу сокета (sockaddr). Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии меток, EPERM при отсутствии прав.

6.7.4.17. mpo_check_socket_receive

int mpo_check_socket_receive(struct ucred *cred, struct socket *so,
    struct label *socketlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

so

Сокет

socketlabel

Метка политики, связанная с so

Определить, следует ли разрешить субъекту получать информацию из сокета so.

6.7.4.18. mpo_check_socket_send

int mpo_check_socket_send(struct ucred *cred, struct socket *so,
    struct label *socketlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

so

Сокет

socketlabel

Метка политики, связанная с so

Определить, следует ли разрешить субъекту передавать информацию через сокет so.

6.7.4.19. mpo_check_cred_visible

int mpo_check_cred_visible(struct ucred *u1, struct ucred *u2);
ПараметрОписаниеБлокировка

u1

Учетные данные субъекта

u2

Учетные данные объекта

Определить, может ли субъект с учётными данными u1 "видеть" другие субъекты с переданными учётными данными u2. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии меток, EPERM при отсутствии привилегий или ESRCH для скрытия видимости. Этот вызов может выполняться в различных ситуациях, включая системные вызовы состояния межпроцессного взаимодействия, используемые ps, и при поиске в procfs.

6.7.4.20. mpo_check_socket_visible

int mpo_check_socket_visible(struct ucred *cred, struct socket *socket,
    struct label *socketlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

socket

Объект; сокет

socketlabel

Метка политики для socket

6.7.4.21. mpo_check_ifnet_relabel

int mpo_check_ifnet_relabel(struct ucred *cred, struct ifnet *ifnet,
    struct label *ifnetlabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

ifnet

Объект; сетевой интерфейс

ifnetlabel

Существующая метка политики для ifnet

newlabel

Обновление метки политики для последующего применения к ifnet

Определить, может ли учетные данные субъекта перемаркировать переданный сетевой интерфейс в соответствии с переданным обновлением метки.

6.7.4.22. mpo_check_socket_relabel

int mpo_check_socket_relabel(struct ucred *cred, struct socket *socket,
    struct label *socketlabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

socket

Объект; сокет

socketlabel

Метка существующей политики для socket

newlabel

Обновление метки для последующего применения к socketlabel

Определить, могут ли учётные данные субъекта перемаркировать переданный сокет в соответствии с переданным обновлением метки.

6.7.4.23. mpo_check_cred_relabel

int mpo_check_cred_relabel(struct ucred *cred, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

newlabel

Обновление метки для последующего применения к cred

Определить, могут ли учетные данные субъекта перемаркировать себя в соответствии с переданным обновлением метки.

6.7.4.24. mpo_check_vnode_relabel

int mpo_check_vnode_relabel(struct ucred *cred, struct vnode *vp,
    struct label *vnodelabel, struct label *newlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Неизменяемый

vp

Объект; vnode

Заблокирован

vnodelabel

Существующая метка политики для vp

newlabel

Обновление метки политики для последующего применения к vp

Определить, могут ли учётные данные субъекта изменить метку переданного vnode на переданную обновлённую метку.

6.7.4.25. mpo_check_mount_stat

int mpo_check_mount_stat(struct ucred *cred, struct mount *mp,
    struct label *mountlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

mp

Объект; точка монтирования файловой системы

mountlabel

Метка политики для mp

Определить, могут ли учетные данные субъекта видеть результаты выполнения statfs для файловой системы. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии меток или EPERM при отсутствии привилегий. Этот вызов может выполняться в различных ситуациях, включая вызовы statfs(2) и связанных функций, а также для определения, какие файловые системы исключать из списка, например, при вызове getfsstat(2).

6.7.4.26. mpo_check_proc_debug

int mpo_check_proc_debug(struct ucred *cred, struct proc *proc);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Неизменяемый

proc

Объект; процесс

Определить, могут ли учётные данные субъекта отлаживать переданный процесс. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки, EPERM при недостатке прав или ESRCH для скрытия видимости цели. Этот вызов может использоваться в различных ситуациях, включая использование API ptrace(2) и ktrace(2), а также для некоторых операций с procfs.

6.7.4.27. mpo_check_vnode_access

int mpo_check_vnode_access(struct ucred *cred, struct vnode *vp,
    struct label *label, int flags);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

flags

флаги access(2)

Определить, как должны возвращаться вызовы access(2) и связанные вызовы для субъекта с указанными учетными данными при выполнении на переданном vnode с использованием переданных флагов доступа. Обычно это должно быть реализовано с использованием той же семантики, что и в mpo_check_vnode_open. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии меток или EPERM при отсутствии привилегий.

6.7.4.28. mpo_check_vnode_chdir

int mpo_check_vnode_chdir(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

Объект; vnode, в который делается chdir(2)

dlabel

Метка политики для dvp

Определить, могут ли учётные данные субъекта изменить рабочий каталог процесса на переданный vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.29. mpo_check_vnode_chroot

int mpo_check_vnode_chroot(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

vnode каталога

dlabel

Метка политики, связанная с dvp

Определить, следует ли разрешить субъекту выполнять chroot(2) в указанный каталог (dvp).

6.7.4.30. mpo_check_vnode_create

int mpo_check_vnode_create(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel, struct componentname *cnp, struct vattr *vap);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

Объект; vnode

dlabel

Метка политики для dvp

cnp

Название компонента для dvp

vap

атрибуты vnode для vap

Определить, могут ли учетные данные субъекта создать vnode с указанной родительской директорией, информацией о имени и атрибутами. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий. Этот вызов может выполняться в различных ситуациях, включая вызовы open(2) с O_CREAT, mkfifo(2) и другие.

6.7.4.31. mpo_check_vnode_delete

int mpo_check_vnode_delete(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel, struct vnode *vp, void *label,
    struct componentname *cnp);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

Родительский каталог vnode

dlabel

Метка политики для dvp

vp

Объект; vnode для удаления

label

Метка политики для vp

cnp

Название компонента для vp

Определить, может ли субъект с данными учетными данными удалить vnode из переданного родительского каталога и переданной информации о имени. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий. Этот вызов может быть выполнен в различных ситуациях, включая вызовы unlink(2) и rmdir(2). Политики, реализующие эту точку входа, также должны реализовывать mpo_check_rename_to для авторизации удаления объектов в результате их переименования.

6.7.4.32. mpo_check_vnode_deleteacl

int mpo_check_vnode_deleteacl(struct ucred *cred, struct vnode *vp,
    struct label *label, acl_type_t type);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Неизменяемый

vp

Объект; vnode

Заблокирован

label

Метка политики для vp

type

Тип ACL

Определить, могут ли учетные данные субъекта удалить ACL указанного типа из переданного vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.33. mpo_check_vnode_exec

int mpo_check_vnode_exec(struct ucred *cred, struct vnode *vp,
    struct label *label);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode для выполнения

label

Метка политики для vp

Определить, могут ли учётные данные субъекта выполнить переданный vnode. Проверка права на выполнение осуществляется отдельно от решений о любом переходном событии. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии прав.

6.7.4.34. mpo_check_vnode_getacl

int mpo_check_vnode_getacl(struct ucred *cred, struct vnode *vp,
    struct label *label, acl_type_t type);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

type

Тип ACL

Определить, может ли учётное данное субъекта получить ACL указанного типа из переданного vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.35. mpo_check_vnode_getextattr

int mpo_check_vnode_getextattr(struct ucred *cred, struct vnode *vp,
    struct label *label, int attrnamespace, const char *name, struct uio *uio);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

attrnamespace

Пространство имен расширенных атрибутов

name

Имя расширенного атрибута

uio

Указатель структуры ввода-вывода; см. uio(9)

Определить, может ли субъект с указанными учетными данными получить расширенный атрибут с заданным пространством имен и именем из указанного vnode. Политики, реализующие маркировку с использованием расширенных атрибутов, могут требовать особой обработки операций с этими атрибутами. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

int mpo_check_vnode_link(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel, struct vnode *vp, struct label *label,
    struct componentname *cnp);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

vnode каталога

dlabel

Метка политики, связанная с dvp

vp

vnode целевого линка

label

Метка политики, связанная с vp

cnp

Имя компонента для создаваемой ссылки

Определить, следует ли разрешить субъекту создавать ссылку на vnode vp с именем, указанным в cnp.

6.7.4.37. mpo_check_vnode_mmap

int mpo_check_vnode_mmap(struct ucred *cred, struct vnode *vp,
    struct label *label, int prot);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

vnode для mmap

label

Метка политики, связанная с vp

prot

Защита mmap (см. mmap(2))

Определить, следует ли разрешить субъекту отображать vnode vp с указанными в prot правами доступа.

6.7.4.38. mpo_check_vnode_mmap_downgrade

void mpo_check_vnode_mmap_downgrade(struct ucred *cred, struct vnode *vp,
    struct label *label, int *prot);
ПараметрОписаниеБлокировка

cred

См. mpo_check_vnode_mmap.

vp

label

prot

Защита mmap для понижения уровня

Понизить уровень защиты mmap на основе меток субъекта и объекта.

6.7.4.39. mpo_check_vnode_mprotect

int mpo_check_vnode_mprotect(struct ucred *cred, struct vnode *vp,
    struct label *label, int prot);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Отображенный vnode

prot

Защита памяти

Определить, следует ли разрешить субъекту устанавливать указанные защиты памяти для памяти, отображенной из vnode vp.

6.7.4.40. mpo_check_vnode_poll

int mpo_check_vnode_poll(struct ucred *active_cred, struct ucred *file_cred,
    struct vnode *vp, struct label *label);
ПараметрОписаниеБлокировка

active_cred

Учетные данные субъекта

file_cred

Учетные данные, связанные со структурой file

vp

vnode, на котором вызывается poll

label

Метка политики, связанная с vp

Определить, следует ли разрешить субъекту вызывать poll на vnode vp.

6.7.4.41. mpo_check_vnode_rename_from

int mpo_vnode_rename_from(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel, struct vnode *vp, struct label *label,
    struct componentname *cnp);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

vnode каталога

dlabel

Метка политики, связанная с dvp

vp

vnode для переименования

label

Метка политики, связанная с vp

cnp

Название компонента для vp

Определить, следует ли разрешить субъекту переименовать vnode vp во что-то другое.

6.7.4.42. mpo_check_vnode_rename_to

int mpo_check_vnode_rename_to(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel, struct vnode *vp, struct label *label, int samedir,
    struct componentname *cnp);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

vnode каталога

dlabel

Метка политики, связанная с dvp

vp

vnode, который будет перезаписан

label

Метка политики, связанная с vp

samedir

Логическое значение; 1, если исходный и целевой каталоги совпадают

cnp

Имя компонента назначения

Определить, следует ли разрешить субъекту переименование vnode vp в директорию dvp или в имя, представленное cnp. Если не существует файла для перезаписи, vp и label будут NULL.

6.7.4.43. mpo_check_socket_listen

int mpo_check_socket_listen(struct ucred *cred, struct socket *socket,
    struct label *socketlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

socket

Объект; сокет

socketlabel

Метка политики для socket

Определить, могут ли учётные данные субъекта прослушивать переданный сокет (вызывать listen). Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.44. mpo_check_vnode_lookup

int mpo_check_vnode_lookup(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel, struct componentname *cnp);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

Объект; vnode

dlabel

Метка политики для dvp

cnp

Имя компонента, который ищется

Определить, могут ли учётные данные субъекта выполнить поиск указанного имени в каталог с переданном vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.45. mpo_check_vnode_open

int mpo_check_vnode_open(struct ucred *cred, struct vnode *vp,
    struct label *label, int acc_mode);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

acc_mode

режим доступа от open(2)

Определить, могут ли учетные данные субъекта выполнить операцию открытия переданного vnode с указанным режимом доступа. Возвращает 0 в случае успеха или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.46. mpo_check_vnode_readdir

int mpo_check_vnode_readdir(struct ucred *cred, struct vnode *dvp,
    struct label *dlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

dvp

Объект; vnode каталога

dlabel

Метка политики для dvp

Определить, могут ли учетные данные субъекта выполнить операцию readdir для переданного vnode каталога. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

int mpo_check_vnode_readlink(struct ucred *cred, struct vnode *vp,
    struct label *label);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

Определить, могут ли учетные данные субъекта выполнить операцию readlink для переданного символьного vnode. Возвращает 0 в случае успеха или значение errno в случае ошибки. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий. Этот вызов может быть выполнен в различных ситуациях, включая явный вызов readlink пользовательским процессом или неявный readlink во время поиска имени процессом.

6.7.4.48. mpo_check_vnode_revoke

int mpo_check_vnode_revoke(struct ucred *cred, struct vnode *vp,
    struct label *label);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

Определить, могут ли учётные данные субъекта отозвать доступ к переданному vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.49. mpo_check_vnode_setacl

int mpo_check_vnode_setacl(struct ucred *cred, struct vnode *vp,
    struct label *label, acl_type_t type, struct acl *acl);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

type

Тип ACL

acl

ACL

Определить, могут ли учётные данные субъекта установить переданный ACL указанного типа для переданного vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.50. mpo_check_vnode_setextattr

int mpo_check_vnode_setextattr(struct ucred *cred, struct vnode *vp,
    struct label *label, int attrnamespace, const char *name, struct uio *uio);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

attrnamespace

Пространство имен расширенных атрибутов

name

Имя расширенного атрибута

uio

Указатель структуры ввода-вывода; см. uio(9)

Определить, могут ли учетные данные субъекта установить расширенный атрибут с переданным именем и пространством имен на переданном vnode. Политики, реализующие метки безопасности, основанные на расширенных атрибутах, могут предусматривать дополнительные защиты для этих атрибутов. Кроме того, политикам следует избегать принятия решений на основе данных, на которые ссылается uio, так как существует потенциальное состояние гонки между этой проверкой и фактической операцией. uio также может быть NULL, если выполняется операция удаления. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.51. mpo_check_vnode_setflags

int mpo_check_vnode_setflags(struct ucred *cred, struct vnode *vp,
    struct label *label, u_long flags);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

flags

Флаги файла; см. chflags(2)

Определить, могут ли учётные данные субъекта установить переданные флаги на переданном vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.52. mpo_check_vnode_setmode

int mpo_check_vnode_setmode(struct ucred *cred, struct vnode *vp,
    struct label *label, mode_t mode);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

mode

Режим файла; см. chmod(2)

Определить, могут ли учётные данные субъекта установить переданный режим для переданного vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при недостатке привилегий.

6.7.4.53. mpo_check_vnode_setowner

int mpo_check_vnode_setowner(struct ucred *cred, struct vnode *vp,
    struct label *label, uid_t uid, gid_t gid);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

uid

User ID

gid

Идентификатор группы

Определить, могут ли учетные данные субъекта установить переданный uid и переданный gid в качестве uid файла и gid файла для переданного vnode. Идентификаторы могут быть установлены в (-1) для запроса отсутствия обновления. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.54. mpo_check_vnode_setutimes

int mpo_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
    struct label *label, struct timespec atime, struct timespec mtime);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vp

label

Метка политики для vp

atime

Время доступа; см. utimes(2)

mtime

Время изменения; см. utimes(2)

Определить, могут ли учётные данные субъекта установить переданные времена доступа на переданном vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.55. mpo_check_proc_sched

int mpo_check_proc_sched(struct ucred *ucred, struct proc *proc);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

proc

Объект; процесс

Определить, могут ли учетные данные субъекта изменить параметры планирования переданного процесса. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки, EPERM при отсутствии привилегий или ESRCH для ограничения видимости.

См. setpriority(2) для получения дополнительной информации.

6.7.4.56. mpo_check_proc_signal

int mpo_check_proc_signal(struct ucred *cred, struct proc *proc, int signal);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

proc

Объект; процесс

signal

Сигнал; см. kill(2)

Определить, могут ли учётные данные субъекта доставить указанный сигнал указанному процессу. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые коды ошибок: EACCES при несоответствии метки, EPERM при недостатке прав или ESRCH для ограничения видимости.

6.7.4.57. mpo_check_vnode_stat

int mpo_check_vnode_stat(struct ucred *cred, struct vnode *vp,
    struct label *label);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Объект; vnode

label

Метка политики для vp

Определить, могут ли учетные данные субъекта выполнять stat для переданного vnode. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

См. stat(2) для получения дополнительной информации.

6.7.4.58. mpo_check_ifnet_transmit

int mpo_check_ifnet_transmit(struct ucred *cred, struct ifnet *ifnet,
    struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

ifnet

Сетевой интерфейс

ifnetlabel

Метка политики для ifnet

mbuf

Объект; mbuf для отправки

mbuflabel

Метка политики для mbuf

Определить, может ли сетевой интерфейс передать mbuf, переданный в качестве параметра. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.59. mpo_check_socket_deliver

int mpo_check_socket_deliver(struct ucred *cred, struct ifnet *ifnet,
    struct label *ifnetlabel, struct mbuf *mbuf, struct label *mbuflabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

ifnet

Сетевой интерфейс

ifnetlabel

Метка политики для ifnet

mbuf

Объект; mbuf для доставки

mbuflabel

Метка политики для mbuf

Определить, может ли сокет принять датаграмму, хранящуюся в переданном заголовке mbuf. Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии метки или EPERM при отсутствии привилегий.

6.7.4.60. mpo_check_socket_visible

int mpo_check_socket_visible(struct ucred *cred, struct socket *so,
    struct label *socketlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Неизменяемый

so

Объект; сокет

socketlabel

Метка политики для so

Определить, могут ли учетные данные субъекта cred "видеть" переданный сокет (socket), используя функции системного мониторинга, такие как те, что применяются в netstat(8) и sockstat(1). Возвращает 0 при успехе или значение errno при ошибке. Рекомендуемые ошибки: EACCES при несоответствии меток, EPERM при отсутствии привилегий или ESRCH для скрытия видимости.

6.7.4.61. mpo_check_system_acct

int mpo_check_system_acct(struct ucred *ucred, struct vnode *vp,
    struct label *vlabel);
ПараметрОписаниеБлокировка

ucred

Учетные данные субъекта

vp

Файл учёта; acct(5)

vlabel

Метка, связанная с vp

Определить, следует ли разрешить субъекту включение учёта, основываясь на его метке и метке файла журнала учёта.

6.7.4.62. mpo_check_system_nfsd

int mpo_check_system_nfsd(struct ucred *cred);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Определить, следует ли разрешить субъекту вызывать nfssvc(2).

6.7.4.63. mpo_check_system_reboot

int mpo_check_system_reboot(struct ucred *cred, int howto);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

howto

Параметр howto из reboot(2)

Определить, следует ли разрешить субъекту перезагружать систему указанным способом.

6.7.4.64. mpo_check_system_settime

int mpo_check_system_settime(struct ucred *cred);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

Определить, разрешено ли пользователю устанавливать системные часы.

6.7.4.65. mpo_check_system_swapon

int mpo_check_system_swapon(struct ucred *cred, struct vnode *vp,
    struct label *vlabel);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

vp

Устройство подкачки

vlabel

Метка, связанная с vp

Определить, следует ли разрешить субъекту добавлять vp как устройство подкачки.

6.7.4.66. mpo_check_system_sysctl

int mpo_check_system_sysctl(struct ucred *cred, int *name, u_int *namelen,
    void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen);
ПараметрОписаниеБлокировка

cred

Учетные данные субъекта

name

См. sysctl(3)

namelen

old

oldlenp

inkernel

Логический; 1, если вызвано из ядра

new

См. sysctl(3)

newlen

Определить, следует ли разрешить субъекту выполнять указанную транзакцию sysctl(3).

6.7.5. Вызовы при управления метками

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

6.8. Пользовательская архитектура

В фреймворк TrustedBSD MAC входит ряд элементов, не зависящих от политик, включая интерфейсы MAC-библиотеки для абстрактного управления метками, изменения в управлении системными учетными данными и библиотеках входа в систему для поддержки назначения MAC-меток пользователям, а также набор инструментов для мониторинга и изменения меток процессов, файлов и сетевых интерфейсов. Более подробная информация о пользовательской архитектуре будет добавлена в этот раздел в ближайшее время.

6.8.1. API для управления метками, не зависящими от политики

Фреймворк TrustedBSD MAC предоставляет ряд библиотечных и системных вызовов, позволяющих приложениям управлять метками MAC на объектах с использованием политико-независимого интерфейса. Это позволяет приложениям манипулировать метками для различных политик без необходимости поддержки конкретных политик. Эти интерфейсы используются универсальными инструментами, такими как ifconfig(8), ls(1) и ps(1), для просмотра меток на сетевых интерфейсах, файлах и процессах. API также поддерживают инструменты управления MAC, включая getfmac(8), getpmac(8), setfmac(8), setfsmac(8) и setpmac(8). API MAC документированы в mac(3).

Приложения обрабатывают метки MAC в двух формах: внутренней форме, используемой для возврата и установки меток для процессов и объектов (mac_t), и внешней форме, основанной на строках C, подходящих для хранения в конфигурационных файлах, отображения пользователю или ввода от пользователя. Каждая метка MAC содержит ряд элементов, каждый из которых состоит из пары имя-значение. Модули политик в ядре привязываются к определённым именам и интерпретируют значения специфичным для политики образом. Во внешней строковой форме метки представляются списком пар имя-значение, разделённых запятыми и символом /. Метки могут быть напрямую преобразованы в текст и обратно с использованием предоставленных API; при извлечении меток из ядра внутреннее хранилище меток должно быть сначала подготовлено для желаемого набора элементов метки. Обычно это делается одним из двух способов: с использованием mac_prepare(3) и произвольного списка желаемых элементов метки, или одной из вариаций вызова, который загружает набор элементов по умолчанию из конфигурационного файла mac.conf(5). Значения по умолчанию для каждого объекта позволяют разработчикам приложений удобно отображать метки, связанные с объектами, без необходимости знать о присутствующих в системе политиках.

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

6.8.2. Привязка меток к пользователям

Стандартный интерфейс управления контекстом пользователя, setusercontext(3), был изменён для получения меток MAC, связанных с классом пользователя, из login.conf(5). Эти метки устанавливаются вместе с остальным контекстом пользователя, когда указан LOGIN_SETALL или явно указан LOGIN_SETMAC.

Ожидается, что в будущей версии FreeBSD база данных меток MAC будет отделена от абстракции классов пользователей login.conf и будет поддерживаться в отдельной базе данных. Однако API setusercontext(3) должно остаться неизменным после такого изменения.

6.9. Заключение

Фреймворк TrustedBSD MAC позволяет модулям ядра расширять политику безопасности системы высокоинтегрированным способом. Они могут делать это на основе существующих свойств объектов или данных меток, которые поддерживаются с помощью фреймворка MAC. Фреймворк достаточно гибкий для реализации различных типов политик, включая политики безопасности информационных потоков, такие как MLS и Biba, а также политики, основанные на существующих учетных данных BSD или защите файлов. Авторам политик может быть полезно ознакомиться с этой документацией, а также с существующими модулями безопасности при реализации новой службы безопасности.


Изменено: 14 октября 2025 г. by Vladlen Popolitov