Confused on SCP Inheritance? We Demystify SELinux Context Transitions
When files or processes inherit the wrong security context, the whole system can break. Learn how SELinux type transitions truly work — from default rules to manual overrides.
The Inheritance Puzzle
You create a file in a directory. You expect it to inherit the folder’s SELinux context — and most of the time it does. Then suddenly a process writes a file and the label is all wrong. Permissions break, applications stall, and the audit log lights up. The confusion around security context (SC) inheritance is real, but it’s not magic.
SELinux inheritance is built on precise policy rules, not guesswork. Once you understand the difference between file-inheritance and process-execution transitions, debugging becomes straightforward.
File Inheritance: The Context of the Parent Directory
When a file or directory is created, the kernel consults the SELinux policy for a type transition rule matching the combination of:
The parent directory’s type
The creating process’s domain (the type of the running process)
The class of the object being created (file, dir, etc.)
If no explicit rule exists, the new object simply inherits the type of its parent directory. This is why most files “get it right” – the default is copy‑the‑parent. But a transition rule can override this: for example, a rule might say “when the `httpd_t` process creates a file in a directory labeled `httpd_sys_content_t`, label the new file as `httpd_sys_rw_content_t`.”
> “By default, a file created in a directory inherits the SELinux type of its parent directory. Type transition rules in the policy can change this behavior.”
> — Red Hat Enterprise Linux 9: Using SELinux, Chapter 3.1
If you ever see a freshly written file with a type that doesn’t match the parent, it’s almost certainly a type transition firing. Tools like `matchpathcon` (part of libselinux) can show what the policy expects:
$ matchpathcon /var/www/html/new-file.html
/var/www/html/new-file.html system_u:object_r:httpd_sys_content_t:s0And if the file is mislabeled, a quick `restorecon -v` will fix it according to the file‑contexts database.
Process Inheritance: The Tale of Two Contexts
Processes don’t just spawn and keep the parent’s label. They follow an entirely different logic. A process always starts with the context of its parent — but the moment it executes a file (via `execve()`), a **domain transition** can occur if all of these are true:
The file being executed has its own type (the “entrypoint” type).
The parent process’s domain is allowed to transition via a `type_transition` rule.
The new domain is permitted by the policy (`allow` rules).
The entrypoint type is marked as an entry point for the target domain.
This is the most common source of SCP inheritance confusion. You might label a binary as `myapp_exec_t` expecting it to run in `myapp_t`, but if the transition isn’t fully wired in policy, the process stays in the parent domain. No error, no obvious log entry — just silent denial of the permissions you assumed were there.
Real‑World Example
Suppose you have a custom daemon `/opt/mydaemon/svc`. You label it `mydaemon_exec_t`. You define a domain `mydaemon_t` and add:
type_transition init_t mydaemon_exec_t:process mydaemon_t;This tells the system: when `init_t` executes a file of type `mydaemon_exec_t`, the resulting process should run as `mydaemon_t`. If you forget the corresponding `allow` rule, or the `mydaemon_exec_t` is not declared as an entry point (`typeattribute mydaemon_t daemon;` alone isn’t enough), the transition silently fails and the process remains `init_t`.
To debug, use `seinfo` and `sesearch` from `setools-console` to check the policy:
$ sesearch -T -s init_t -t mydaemon_exec_t -c process -p transitionOr inspect the entrypoint attribute of the target domain:
$ seinfo -tmydaemon_t -xRestoring Sanity with Sapior
At Sapior we build developer tools that visualize and interrogate SELinux policy state. Instead of grepping through monolithic `.te` files, you can see instant answers about why a context didn’t inherit, what transitions are active, and where the gaps are. Whether you’re managing containers, securing a web server, or locking down an IoT edge device, understanding context inheritance is the difference between a hardened system and a bricked one.
We hope this clears the fog. Next time a mislabeled file appears, you’ll know exactly which rule to check — and you’ll never look at a directory’s context the same way again.