# Container Statements

## block

Start a new namespace where any CIL statement is valid.

Statement definition:

    (block block_id
        cil_statement
        ...
    )

Where:

`block` | The `block` keyword.
`block_id` | The namespace identifier.
`cil_statement` | Zero or more valid CIL statements.

Example:

See the `blockinherit` statement for an example.

## blockabstract

Declares the namespace as a 'template' and does not generate code until instantiated by another namespace that has a `blockinherit` statement.

Statement definition:

    (block block_id
        (blockabstract template_id)
        cil_statement
        ...
    )

Where:

`block` | The `block` keyword.
`block_id` | The namespace identifier.
`blockabstract` | The `blockabstract` keyword.
`template_id` | The abstract namespace identifier. This must match the `block_id` entry.
`cil_statement` | Zero or more valid CIL statements forming the abstract block.

Example:

See the `blockinherit` statement for an example.

## blockinherit

Used to add common policy rules to the current namespace via a template that has been defined with the `blockabstract` statement.

Statement definition:

    (block block_id
        (blockinherit template_id)
        cil_statement
        ...
    )

Where:

`block` | The `block` keyword.
`block_id` | The namespace identifier.
`blockinherit` | The `blockinherit` keyword.
`template_id` | The inherited namespace identifier.
`cil_statement` | Zero or more valid CIL statements.

Example:

This example contains a template `client_server` that is instantiated in two blocks (`netserver_app` and `netclient_app`):

    ; This is the template block:
    (block client_server
        (blockabstract client_server)

        ; Log file labeling
        (type log_file)
        (typeattributeset file_type (log_file))
        (typeattributeset data_file_type (log_file))
        (allow process log_file (dir (write search create setattr add_name)))
        (allow process log_file (file (create open append getattr setattr)))
        (roletype object_r log_file)
        (context log_file_context (u object_r log_file low_low))

        ; Process labeling
        (type process)
        (typeattributeset domain (process))
        (call app_domain (process))
        (call net_domain (process))
    )

    ; This is a policy block that will inherit the abstract block above:
    (block netclient_app
        ; Add common policy rules to namespace:
        (blockinherit client_server)
        ; Label the log files
        (filecon "/data/data/com.se4android.netclient/.*" file log_file_context)
    )

    ; This is another policy block that will inherit the abstract block above:
    (block netserver_app
       ; Add common policy rules to namespace:
        (blockinherit client_server)

        ; Label the log files
        (filecon "/data/data/com.se4android.netserver/.*" file log_file_context)
    )

## optional

Declare an `optional` namespace. All CIL statements in the optional block must be satisfied before instantiation in the binary policy. `tunableif` and `macro` statements are not allowed in optional containers. The same restrictions apply to CIL policy statements within `optional`'s that apply to kernel policy statements, i.e. only the policy statements shown in the following table are valid:

`allow` | `auditallow` | `booleanif` | `dontaudit`
`typepermissive` | `rangetransition` | `role` | `roleallow`
`roleattribute` | `roletransition` | `type` | `typealias`
`typeattribute` | `typechange` | `typemember` | `typetransition`

Statement definition:

    (optional optional_id
        cil_statement
        ...
    )

Where:

`optional` | The `optional` keyword.
`optional_id` | The `optional` namespace identifier.
`cil_statement` | Zero or more valid CIL statements.

Example:

This example will instantiate the optional block `ext_gateway.move_file` into policy providing all optional CIL statements can be resolved:

    (block ext_gateway
        ......
        (optional move_file
            (typetransition process msg_filter.move_file.in_queue file msg_filter.move_file.in_file)
            (allow process msg_filter.move_file.in_queue (dir (read getattr write search add_name)))
            (allow process msg_filter.move_file.in_file (file (write create getattr)))
            (allow msg_filter.move_file.in_file unconfined.object (filesystem (associate)))
            (typetransition msg_filter.int_gateway.process msg_filter.move_file.out_queue file
                msg_filter.move_file.out_file)
            (allow msg_filter.int_gateway.process msg_filter.move_file.out_queue (dir (read write search)))
            (allow msg_filter.int_gateway.process msg_filter.move_file.out_file (file (read getattr unlink)))
        ) ; End optional block

        .....
    ) ; End block

## in

Allows the insertion of CIL statements into a named container (`block`, `optional` or `macro`). This statement is not allowed in `booleanif` or `tunableif` statements.

Statement definition:

    (in container_id
        cil_statement
        ...
    )

Where:

`in` | The `in` keyword.
`container_id` | A valid `block`, `optional` or `macro` namespace identifier.
`cil_statement` | Zero or more valid CIL statements.

Example:

This will add rules to the container named `system_server`:

    (in system_server
        (dontaudit process secmark_demo.dns_packet (packet (send recv)))
        (allow process secmark_demo.dns_packet (packet (send recv)))
    )