SELinux Userspace
repository·main·Indexed 23 days ago
https://github.com/selinuxproject/selinuxUtilities and system libraries for configuring and managing Mandatory Access Control (MAC) on Linux systems. Includes Python and Ruby bindings for libselinux, core components like libsepol, and a comprehensive reference for the Common Intermediate Language (CIL) used for policy representation.
What's inside selinux
- CIL (Common Intermediate Language) is the intermediate language used by SELinux for policy representation. It provides a structured way to define security policies, including access vector rules, type enforcement, and various labeling statements. The language is designed with specific goals regarding design philosophy, scalability, and ease of manipulation by tools.
What is SELinux Common Intermediate Language (CIL)?
mainThe SELinux Common Intermediate Language (CIL) is an intermediate language designed to sit between high-level policy languages (like the current module language) and the low-level kernel policy representation.
CIL serves as a bridge that enables:
- Cross-language interaction: Multiple high-level languages can consume and produce language constructs (like interfaces) that have more features than the raw kernel policy.
- Domain-specific policy languages: It simplifies the creation of specialized languages such as CDS Framework, Lobster, and Shrimp.
- Unified policy analysis: It provides a semantically rich representation that allows a single set of analysis tools to process the output of various high-level languages without losing high-level information.
CIL Namespaces and the Global Namespace
mainCIL supports namespaces using containers like the
blockstatement. When a block is resolved, a dot.is used to represent the parent/child relationship.Namespace Resolution
- Namespaced Access: A type
processinsideblock example_nsresolves toexample_ns.process. - Global Namespace: Any symbol declared outside a container is in the global namespace.
- Referencing Global Symbols: To explicitly reference a symbol in the global namespace from within a block, prefix it with a dot
.(e.g.,.tmpfs). - Implicit Resolution: If a symbol is not prefixed, CIL searches the current namespace first. If not found, it searches the global namespace.
; This type is the global tmpfs: (type tmpfs) (block file ; file namespace tmpfs (type tmpfs) (class file (open read write getattr)) ; This rule will reference the local namespace for src and global for tgt: (allow tmpfs .tmpfs (file (read))) ; This rule will reference the global namespace for src and tgt: (allow .tmpfs .tmpfs (file (write))) )- Namespaced Access: A type
Define MLS levels and sensitivity categories
mainTo define a complete MLS
level, you must first associate sensitivities with categories usingsensitivitycategory.Associate categories with sensitivity:
(sensitivitycategory <sensitivity_id> <categoryset_id>)This statement is required before alevelcan be declared.Declare a level:
(level <level_id> (<sensitivity_id> [<categoryset_id>]))A level combines a sensitivity and zero or more categories (via acategorysetor a list of identifiers).Declare a level range:
(levelrange <levelrange_id> (<low_level_id> <high_level_id>))Defines a range between two previously declaredlevelidentifiers.
Use common identifiers to share permissions across classes
mainTo avoid redundancy, you can define a
commonidentifier containing a set of permissions and then associate it with one or more classes usingclasscommon.- Define common permissions: Use
(common common_id (permission_id ...)). - Associate with a class: Use
(classcommon class_id common_id). - Add additional permissions: Use a
classstatement for the sameclass_idto add more permissions. The final set for the class will be the union of the common permissions and the class-specific permissions.
Example:
(common file (ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton)) (classcommon dir file) (class dir (add_name remove_name reparent search rmdir open audit_access execmod))This results in the
dirclass having all permissions from thefilecommon set plus its own specific permissions.(common file (ioctl read write create getattr setattr lock relabelfrom relabelto append unlink link rename execute swapon quotaon mounton)) (classcommon dir file) (class dir (add_name remove_name reparent search rmdir open audit_access execmod))- Define common permissions: Use
Key features enabled by CIL
mainCIL enables several advanced SELinux policy capabilities that are difficult to achieve with traditional policy languages:
- Policy customization without breaking updates: Allows administrators to modify access (e.g., removing unwanted access) without directly modifying shipped vendor policy files, ensuring future updates can still be applied.
- First-class interfaces: Transforms interfaces from pre-processor constructs into first-class language features. This allows compilers and analysis tools to understand them, removing the need to recompile all modules when an interface changes.
- Rich policy relationships: Provides language features to create new types or modules based on existing ones with varying degrees of change, supporting ad-hoc creation of policy modules.
- Policy management support: Enables management tools (like
semanage) to generate and consume CIL to perform policy modifications, rather than directly manipulating private data stores and binary formats.
Core design principles of CIL
mainCIL is designed with several key principles to ensure it remains a robust intermediate layer:
- Intermediate focus: It provides rich semantics for cross-language interaction but avoids adding features purely for convenience if they can be handled by a high-level language.
- Machine-first syntax: The syntax is designed to be easy for compilers, analysis tools, and policy generation tools to parse and generate. Machine processing is prioritized over human readability.
- Faithful kernel representation: CIL aims to fully and faithfully represent the kernel policy without obscuring or hiding the essence of kernel enforcement. It acts like "portable assembler" rather than a pure functional language.
- Source-oriented workflow: CIL assumes a source-policy-oriented world. Binary formats should only be used for communication with the kernel.
- Declarative and order-independent: Like existing SELinux policies, CIL maintains a declarative, order-independent style.
- Elimination of M4: CIL is intended to eliminate the need for M4 and other pre-processors to avoid side-effect issues.
- Single compilation unit: The language is processed as a single compilation unit rather than module-by-module to simplify processing and improve error reporting.
CIL Expressions and Prefix Notation
mainCIL expressions use prefix (Polish) notation, which may be nested. This differs from the kernel policy language, which uses infix notation.
Expression Syntax
expr_set = (name ... | expr ...)expr = (expr_key expr_set ...)
Supported Keys by Statement Type
expr_key classpermissionset / roleattributeset / typeattributeset categoryset booleanif / tunableif constrain / mlsconstrain / validatetrans / mlsvalidatetrans domX dombyX incompX eqX X neX X andX X X X orX X X X notX X X X xorX X X allX X X rangeX Usage Examples
Type Attributes with Logic
(typeattributeset all_fs_type_except_usermodehelper_and_proc_security (and (and fs_type (not file.usermodehelper) ) (not file.proc_security) ) )Boolean Conditionals
(booleanif (and (not disableAudio) (not disableAudioCapture)) (true (allow process device.audio_capture_device (chr_file_set (rw_file_perms))) ) )Constraints (MLS/Transition)
; Process read operations: No read up unless trusted. (mlsconstrain (process (getsched getsession getpgid getcap getattr ptrace share)) (or (dom l1 l2) (eq t1 mlstrustedsubject)))Map multiple classes and permissions using classmap
mainA
classmapallows you to group multipleclassmappingidentifiers. This is useful for rules that support a list of classes (liketypetransition,typechange, etc.) or for linking multipleclasspermissionsets to a single rule.- Define the map:
(classmap classmap_id (classmapping_id ...)) - Define mappings:
(classmapping classmap_id classmapping_id classpermissionset_id)
Example:
(classmap android_classes (set_1 set_2)) (classmapping android_classes set_1 (binder (all))) (classmapping android_classes set_1 (property_service (set))) (allow type_1 self (android_classes (set_1)))This
allowrule will resolve into multiple AV rules, one for each mapping inset_1.(classmap android_classes (set_1 set_2)) (classmapping android_classes set_1 (binder (all))) (classmapping android_classes set_1 (property_service (set)))- Define the map:
CIL Declarations and Definitions
mainCIL uses declarations to create objects and definitions to build upon them.
Declarations
Declarations can be named or anonymous:
- Named Declarations: Create new objects with an identifier. Examples include
(type process),(typeattribute domain), and(class file (read write)). - Explicit Anonymous Declarations: Currently restricted to IP addresses (e.g.,
(127.0.0.1)or(::1)). - Anonymous Declarations: Reference objects that have already been declared.
Definitions
Definitions build on existing objects. They can be repeated multiple times; duplicates are resolved to a single definition during compilation.
- Example:
(typeattributeset domain (process))adds the typeprocessto the attributedomain. - Example:
(allow domain process (file (read write))))adds an access rule.
- Named Declarations: Create new objects with an identifier. Examples include
Understand the CIL syntax and structure
mainCIL's design focuses on simplicity and regularity through the following characteristics:
- S-expression based: The syntax is extremely regular and easy to parse because it is based on s-expressions.
- Minimalist statements: Statements are reduced to the bare minimum, with exactly one way to express any given syntax.
- Unambiguous: Statements are unambiguous and have well-defined overlaps, avoiding the context-dependent declarations found in older policy languages.
- Declarative: The language is declarative and removes ordering constraints.
Note on Semantics: CIL preserves the current kernel policy almost unchanged (using different syntax) and layers on features from the module language and reference policy. While it introduces new constructs for managing namespaces, existing concepts like
typesretain their current semantics.Understand Access Vector (AV) Rules in CIL
mainAccess Vector rules define the relationship between a source type, a target type, and specific class permissions or extended permissions.
Rule Structure:
(av_flavor source_id target_id|self|notself|other classpermission_id|permissionx_id)Key Components:
av_flavor: The type of rule (e.g.,allow,deny,neverallow).source_id: A previously definedtype,typealias, ortypeattribute.target_id: Atype,typealias, ortypeattribute. Special keywords include:self: The source and target are the same. If the source is an attribute, each type in the attribute is paired with itself.notself: The target is all types except those in the source.other: A shorthand for a rule where each type in the source is paired with all other types in the source as the target.
classpermission_id: Aclasspermissionsetor a set ofclassmap/classmappingidentifiers (used for standard rules).permissionx_id: Apermissionxidentifier (used for extended permission rules).