KasperskyOS Community Edition 1.3

Using templates when creating a KasperskyOS-based solution security policy description

When creating a policy description, you can use the Ginger template engine that is integrated into the nk-psl-gen-c compiler. To manage the template engine, you must use the parameters of the nk-psl-gen-c compiler or parameters of the CMake commands build_kos_qemu_image() and build_kos_hw_image().

A Ginger PSL template is a PSL file that contains syntactic constructs of the Ginger template engine in addition to declarations in PSL. Files such as security.psl.in, security.psl, and core.psl are considered to be Ginger PSL templates if they contain syntactic constructs of the Ginger template engine. (A security.psl.in file simultaneously serves as a PSL template in a different context because this file may use macros and variables that are not linked to the Ginger template engine.)

A description of the syntactic constructs of the Ginger template engine is provided in the official documentation for this template engine. For example, you can use macros.

Example of defining a macro:

{% macro VMMSafe(src) %} match method=Allocate { match src={{ src }} { grant () } } {% endmacro %}

Example macro call

{{ VMMSafe(["Einit"]) }}

This call will create the following construct:

match method=Allocate { match src=Einit { grant () } }

Example definition of a macro with loops:

{% macro VMMSafe(srcs) %} {% for method in ["Allocate", "Commit", "Decommit"] %} match method={{ method }} { {% for src in srcs %} match src={{ src }} { grant () } {% endfor %} } {% endfor %} {% endmacro %}

Example construct with a macro call:

match endpoint=vmm.VMM { {{ VMMSafe(["Einit", "client.Client", "consumer.Consumer", "kl.bc.BlobContainer", "kl.core.NameServer", "kl.VfsEntity", "scm.Producer", "execution_manager.ExecMgrEntity", "scm.SecurityConfigMgrEntity", "kl.drivers.ATA", "kl.drivers.PCIE"]) }} }

When the macro is expanded in this construct, the following construct will be created:

match endpoint=vmm.VMM { match method=Allocate { match src = Einit { grant () } match src=client.Client { grant () } match src=consumer.Consumer { grant () } match src=kl.bc.BlobContainer { grant () } match src=kl.core.NameServer { grant () } match src=kl.VfsEntity { grant () } match src=scm.Producer { grant () } match src=execution_manager.ExecMgrEntity { grant () } match src=scm.SecurityConfigMgrEntity { grant () } match src=kl.drivers.ATA { grant () } match src=kl.drivers.PCIE { grant () } } match method=Commit { match src = Einit { grant () } match src=client.Client { grant () } match src=consumer.Consumer { grant () } match src=kl.bc.BlobContainer { grant () } match src=kl.core.NameServer { grant () } match src=kl.VfsEntity { grant () } match src=scm.Producer { grant () } match src=execution_manager.ExecMgrEntity { grant () } match src=scm.SecurityConfigMgrEntity { grant () } match src=kl.drivers.ATA { grant () } match src=kl.drivers.PCIE { grant () } } match method=Decommit { match src = Einit { grant () } match src=client.Client { grant () } match src=consumer.Consumer { grant () } match src=kl.bc.BlobContainer { grant () } match src=kl.core.NameServer { grant () } match src=kl.VfsEntity { grant () } match src=scm.Producer { grant () } match src=execution_manager.ExecMgrEntity { grant () } match src=scm.SecurityConfigMgrEntity { grant () } match src=kl.drivers.ATA { grant () } match src=kl.drivers.PCIE { grant () } } }

Comments can be used in Ginger PSL templates:

{# Comment that will be deleted when the template is expanded. #}

A file inclusion construct can also be used in Ginger PSL templates.

Example of a file inclusion construct:

{% include "defs.ginger" %}

The defs.ginger file may contain definitions of macros used in a Ginger PSL template, for example. This file must be located in the same directory as the Ginger PSL template that contains this construct.