KasperskyOS Community Edition 1.0

Isolation and interaction between entities

A cyber immune system consists of isolated parts (security domains in MILS terms) that can interact with one another only through a separation kernel, i.e. in a controlled manner. In KasperskyOS, security domains are implemented as entities.

In this section

Entities

Communication of entities (IPC)

Describing entities' interfaces (EDL, CDL, IDL)

IPC transport

Page top
[Topic overview_isolation_and_ipc]

Entities

In KasperskyOS, each process is a subject in a solution security policy. When a process starts, the KasperskyOS kernel associates with it the context necessary for its execution, and with the Kaspersky Security Module – the security context necessary to control its interactions with other processes.

To emphasize each process's link with the security policy, processes in KasperskyOS are called entities.

From the perspective of the KasperskyOS kernel, an entity is a process that has a separate address space and one or more threads of execution. The kernel guarantees isolation of the address spaces of entities. An entity can implement interfaces, and other entities can call the methods of these interfaces through the kernel.

From the perspective of the Kaspersky Security Module, an entity is a subject that other subjects (entities) can interact with. The types of interactions that are possible are specified by a description of the entity's interfaces that must match the implementation. Interface descriptions let the security module check each interaction for compliance with the solution security policy.

Additional information regarding entities

For the Kaspersky Security Module, the kernel is a subject just like an entity. Entities can call kernel methods, and these interactions are controlled like calls to methods of other entities. Accordingly, we will subsequently say that the kernel is a separate entity from the perspective of the Kaspersky Security Module.

Page top
[Topic overview_entities]

Communication of entities (IPC)

KasperskyOS has only one way for entities to interact – through synchronous exchange of IPC messages: via a request and a response. In each interaction, there are two separate roles: client (the entity that initiates the interaction) and server (the entity that handles the request). Additionally, an entity that acts as a client in one interaction can act as a server in another.

The client and server use three system calls: Call(), Recv() and Reply():

  1. The client sends a request to the server. To do this, one of the client's threads calls Call() and blocks until a response is received from the server or kernel (in the event of an error, for example).
  2. A server thread calls Recv() and waits for messages. When a request is received, this thread unblocks, handles the request, and sends a response by calling Reply().
  3. When a response is received (or an error occurs), the client thread unblocks and continues execution.

Thus, in terms of the MILS model, the KasperskyOS kernel is a separation kernel, because all entity interactions happen through it.

Exchanging messages as method calls

An entity's IPC request to a server is a call to one of the interfaces implemented by the server. The IPC request contains input arguments for the called method, the ID of the interface implementation (RIID), and the ID of the called method (MID). Upon receiving a request, the server entity uses these identifiers to find the method's implementation. The server calls the method's implementation, passing in the input arguments from the IPC request. After handling the request, the server entity sends the client a response that contains the method's output arguments.

The Kaspersky Security Module can analyze all components of an IPC message in order to decide whether the message complies with the system's security policy.

IPC channels

To enable two entities to exchange messages, an IPC channel, also referred to as a "channel" or "connection", must be established between them. The channel specifies the entities' roles, i.e. "client" and "server". Additionally, an entity can have several channels in which it is the client, and several channels in which it is the server.

KasperskyOS has two mechanisms for creating IPC channels:

  1. The static mechanism involves creating a channel when the entity is started (when the solution is started). Channels are created statically by the initializing Einit entity.
  2. The dynamic mechanism allows started entities to establish a channel between one another.
Page top
[Topic overview_ipc]

Describing entities' interfaces (EDL, CDL, IDL)

To control interactions between entities, the structure of the sent IPC messages must be transparent to the security module. In KasperskyOS, this is achieved using a static declaration of entities' interfaces. Special languages are used for this: Entity Definition Language (EDL), Component Definition Language (CDL) and Interface Definition Language (IDL). If an IPC message does not match an interface description, it will be rejected by the security module.

An entity's interface description defines the allowed IPC message structures. This creates a clear link between the implementation of each method and how that method is represented for the security module. Nearly every build tool uses entities' interface descriptions either explicitly or implicitly.

Types of static descriptions

A description of entities' interfaces is built using an "entity-component-interface" model:

  • An IDL description declares an interface, as well as user types and constants (optional). Taken together, all of the IDL descriptions in a solution encompass all the interfaces implemented in the solution.
  • A CDL description lists the interfaces implemented by a component. Components make it possible to group interface implementations. Components can include other components.
  • An entity's EDL description declare instances of the components included in the entity. An entity may include no components.

Example

Below are static declarations of a solution consisting of a Client entity that does not implement a single interface, and a Server entity that implements the FileOps interface.

Client.edl

// The static description consists of only the entity's name

entity Client

Server.edl

// The Server entity contains an instance of the Operations component

entity Server

components {

OpsComp: Operations

}

Operations.cdl

// The Operations component implements the FileOps interface

component Operations

interfaces {

FileOpsImpl: FileOps

}

FileOps.idl

package FileOps

// Declaration of the String user type

typedef array <UInt8, 256> String;

// The FileOps interface contains a single Open method with a 'name' input argument and 'h' output argument

interface {

Open(in String name, out UInt32 h);

}

For more details, refer to Syntax of static declarations.

Page top
[Topic overview_idl_cdl_edl]

IPC transport

To implement entity interactions, we need transport code, which is responsible for properly creating, packing, sending, unpacking, and dispatching IPC messages. Developing solutions for KasperskyOS does not require writing your own transport code. Instead, you can use special tools and libraries included in KasperskyOS Community Edition.

Transport code for developed components

Someone developing new components for KasperskyOS can generate transport code based on static definitions of the components. To achieve this, KasperskyOS Community Edition includes the NK compiler. The NK compiler lets you generate transport methods and types for use by both clients and servers.

Transport code for included components

The functionality of most components included in KasperskyOS Community Edition may be used in a solution both locally (through static linking with the developed code) and via IPC.

The following transport libraries are used to separate a component into a server entity and use it via IPC:

  • The component's client library converts local calls into IPC requests to the driver entity.
  • The component's server library receives IPC requests to the driver entity and converts them into local calls.

To use a component via IPC, it's enough to link its implementation to the server library, and to link the client entity to the client library.

The client library interface does not differ from the interface of the component itself. This means that it is unnecessary to change the code of the client entity in order to switch to using a component via IPC (instead of static linking).

For more details, refer to IPC and transport.

Page top
[Topic overview_ipc_transport]