Создание и выполнение тестов политики безопасности решения на базе KasperskyOS

21 мая 2024

ID ssp_descr_psl_syntax_testing

Тестирование политики безопасности решения выполняется, чтобы проверить, разрешает ли политика то, что должна разрешать, и запрещает ли она то, что должна запрещать.

Чтобы создать набор тестов политики безопасности решения, нужно использовать декларацию:

assert ["название набора тестов"] {

// Конструкции на языке PAL (Policy Assertion Language)

[setup {<начальная часть тестов>}]

sequence ["название теста"] {<основная часть теста>}

[...]

[finally {<конечная часть тестов>}]

}

Можно создать несколько наборов тестов, используя несколько таких деклараций.

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

После выполнения каждого теста все изменения в модуле безопасности Kaspersky Security Module, связанные с выполнением этого теста, "откатываются".

Каждый тест включает один или несколько тестовых примеров.

Тестовые примеры

Тестовый пример ассоциирует описание события безопасности и значения параметров интерфейсного метода с ожидаемым решением модуля безопасности Kaspersky Security Module. Если фактическое решение модуля безопасности совпадает с ожидаемым, тестовый пример проходит, иначе не проходит.

Когда выполняется тест, тестовые примеры выполняются в той последовательности, в которой они описаны. То есть осуществляется проверка, как модуль безопасности обрабатывает последовательность событий безопасности.

Если все тестовые примеры в тесте проходят, тест проходит. Если хотя бы один тестовый пример в тесте не проходит, тест не проходит. Выполнение теста завершается на первом тестовом примере, который не проходит. Каждый тест из набора выполняется независимо от того, прошел или не прошел предыдущий тест.

Описание тестового примера на языке PAL представляет собой следующую конструкцию:

[<ожидаемое решение модуля безопасности> ["название тестового примера"]] <вид события безопасности> <селекторы события безопасности> [{значения параметров интерфейсного метода}]

В качестве ожидаемого решения модуля безопасности можно указать значение grant ("разрешено"), deny ("запрещено") или any ("любое решение"). Можно не указывать ожидаемое решение модуля безопасности. По умолчанию ожидается решение "разрешено". Если указано значение any, решение модуля безопасности не влияет на то, проходит тестовый пример или нет. В этом случае тестовый пример может не пройти из-за ошибок обработки IPC-сообщения модулем безопасности (например, при некорректной структуре IPC-сообщения).

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

О видах и селекторах событий безопасности, а также об ограничениях использования селекторов см. "Привязка методов моделей безопасности к событиям безопасности". Селекторы должны обеспечивать, чтобы описанию события безопасности соответствовали IPC-сообщения одного типа. (В привязках методов моделей безопасности к событиям безопасности селекторы могут этого не обеспечивать.)

В описаниях событий безопасности вместо имени класса процессов (и ядра KasperskyOS) нужно указывать SID. Исключение составляют события вида execute, при наступлении которых SID запускаемого процесса (или ядра) неизвестен. Чтобы сохранить SID процесса или ядра в переменную, нужно использовать оператор <- в описании тестового примера вида:

<имя переменной> <- execute dst=<имя класса процессов/ядро> ...

Переменной будет присвоено значение SID, даже если запуск процесса заданного класса (или ядра) запрещен тестируемой политикой, но решение "запрещено" является ожидаемым.

В языке PAL поддерживаются сокращенные формы описаний событий безопасности:

  • security: <SID процесса> ! <квалифицированное имя метода интерфейса безопасности> соответствует security src=<SID процесса> method=<квалифицированное имя метода интерфейса безопасности>.
  • request: <SID клиента> ~> <SID сервера/ядра> : <квалифицированное имя службы.имя метода> соответствует request src=<SID клиента> dst=<SID сервера/ядра> endpoint=<квалифицированное имя службы> method=<имя метода>.
  • response: <SID клиента> <~ <SID сервера/ядра> : <квалифицированное имя службы.имя метода> соответствует response src=<SID сервера/ядра> dst=<SID клиента> endpoint=<квалифицированное имя службы> method=<имя метода>.

Значения параметров интерфейсного метода должны быть заданы для всех видов событий безопасности, кроме execute. Если у интерфейсного метода нет параметров, нужно указать {}. Для событий безопасности вида execute нельзя указывать {}.

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

<имя параметра> : <значение>

Имена и типы параметров должны соответствовать IDL-описанию. Порядок следования параметров не важен.

Пример задания значений параметров:

{ param1 : 23, param2 : "bar", param3 : { collection : [5,7,12], filehandle : 15 }, param4 : { name : ["foo", "baz" } }

В этом примере через параметр param1 передается число. Через параметр param2 передается строковый буфер. Через параметр param3 передается структура, состоящая из двух полей. Поле collection содержит массив или последовательность из трех числовых элементов. Поле filehandle содержит SID. Через параметр param4 передается объединение или структура с одни полем. Поле name содержит массив или последовательность из двух строковых буферов.

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

Значения параметров (элементов параметров) можно не указывать. В этом случае автоматически применяются значения по умолчанию, соответствующие IDL-типам параметров (элементов параметров):

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

Пример применения значения по умолчанию для параметра и элемента параметра:

/* Параметр указан. */

request src=x dst=y endpoint=e method=m { name : { firstname: "a", lastname: "b" } }

/* Параметр не указан. В качестве значения параметра name будет применена структура,

* состоящая из двух строковых буферов нулевого размера.*/

request src=x dst=y endpoint=e method=m {}

/* Элемент параметра не указан. В качестве значения элемента параметра lastname будет

* применен строковый буфер нулевого размера.*/

request src=x dst=y endpoint=e method=m { name : { firstname: "a"} }

Примеры тестов

См. "Примеры тестов политик безопасности решений на базе KasperskyOS".

Тестовая процедура

Тестовая процедура включает следующие шаги:

  1. Сохранить тесты в одном или нескольких PSL-файлах (*.psl или *.psl.in).
  2. Добавить CMake-команду add_kss_pal_qemu_tests() в один из файлов CMakeLists.txt проекта.

    Через параметр PSL_FILES нужно задать пути к PSL-файлам с тестами. Через параметр DEPENDS нужно задать CMake-цели, в результате выполнения которых IDL-, CDL-, EDL-файлы, от которых зависят PSL-файлы, будут помещены в те директории, где компилятор nk-psl-gen-c сможет их найти. Если используются файлы *.psl.in, через параметр ENTITIES нужно задать имена классов процессов системных программ. (Эти системные программы входят в состав решения на базе KasperskyOS, для которого нужно выполнить тестирование политики безопасности.)

    Пример использования CMake-команды add_kss_pal_qemu_tests() в файле einit/CMakeLists.txt:

    add_kss_pal_qemu_tests (

    PSL_FILES src/security.psl.in

    DEPENDS kos-qemu-image

    ENTITIES ${ENTITIES})

  3. Собрать и выполнить тесты.

    Нужно запустить Bash-скрипт сборки cross-build.sh с параметром --target pal-test<N>, где N – индекс PSL-файла в списке PSL-файлов, заданных через параметр PSL_FILES CMake-команды add_kss_pal_qemu_tests() на шаге 2. Например, если указать --target pal-test0, будет создан и запущен на QEMU образ решения на базе KasperskyOS, который соответствует первому PSL-файлу, заданному через параметр PSL_FILES CMake-команды add_kss_pal_qemu_tests(). (Вместо прикладных и системных программ это решение будет содержать программу, выполняющую тесты.)

    Пример:

    ./cross-build.sh --target pal-test0

Пример результатов тестирования:

[==========] Running 4 tests from 1 test suite.

[----------] Global test environment set-up.

[----------] 4 tests from KSS

[ RUN ] KSS.KssUnitTest_flow_normal

[ OK ] KSS.KssUnitTest_flow_normal (6 ms)

[ RUN ] KSS.KssUnitTest_flow_ping_must_be_first

/home/work/build/stat/build/install/examples/ping/build/einit/

pal-test/gen_security.psl.test.c:9742: Failure

Expected equality of these values:

rc

Which is: -1

NK_EOK

Which is: 0

gen_security.psl:116: expect grant

[ FAILED ] KSS.KssUnitTest_flow_ping_must_be_first (8 ms)

[ RUN ] KSS.KssUnitTest_flow_ping_ping_is_deny

[ OK ] KSS.KssUnitTest_flow_ping_ping_is_deny (4 ms)

[ RUN ] KSS.KssUnitTest_flow_test_deny

[ OK ] KSS.KssUnitTest_flow_test_deny (1 ms)

[----------] 4 tests from KSS (29 ms total)

[----------] Global test environment tear-down

[==========] 4 tests from 1 test suite ran. (42 ms total)

[ PASSED ] 3 tests.

[ FAILED ] KSS.KssUnitTest_flow_ping_must_be_first (8 ms)

Результаты тестирования содержат сведения о том, прошел или не прошел каждый тест. Если тест не прошел, то указываются сведения о размещении описания непрошедшего тестового примера в PSL-файле.

Вам помогла эта статья?
Что нам нужно улучшить?
Спасибо за ваш отзыв, вы помогаете нам становиться лучше!
Спасибо за ваш отзыв, вы помогаете нам становиться лучше!