selabel_file(5)

πŸ’– NAME πŸ’–

okay bestie, so this is selabel_file β€” it's a section 5 manual page (iykyk, that means config file format vibes ✨) all about the userspace SELinux labeling interface and configuration file format for the file contexts backend. She's the blueprint, the main character of "what context does this file get" πŸŽ€


🌸 SYNOPSIS 🌸

#include <selinux/label.h>

int selabel_lookup(struct selabel_handle *hnd,
                   char **context,
                   const char *path, int mode);

int selabel_lookup_raw(struct selabel_handle *hnd,
                   char **context,
                   const char *path, int mode);

✨ DESCRIPTION ✨

So the file contexts backend is literally the matchmaker πŸ’… β€” it maps from pathname/mode combinations into security contexts. When you're relabeling a file system, this is what finds the right context for each and every file. And bestie, heads up: the context it hands back must be freed using freecon(3) β€” don't just leave it hanging, that's rude 🫢

selabel_lookup(3) is where you'll find the full story on the function, its return values and its error codes β€” but there's one errno that gets extra clarification specifically for this file contexts backend:

  • ENOENT β€” no context corresponding to the path and mode was found. And plot twist 🫣 this one also shows up when the file contexts series of files has a context of <<none>> sitting against the path (peep the FILE FORMAT section for that one).

The path argument? Set it to the full pathname of the file whose assigned context you're checking. The mode argument? That's the mode bits of the file, as determined by lstat(2). Now, mode may be zero, but like… don't expect full matching to happen if you do that. It's giving half-effort energy, no cap πŸ™ˆ

Any messages that selabel_lookup(3) generates get sent to stderr by default, though you can change that with selinux_set_callback(3).

selabel_lookup_raw(3) is the twin sister of selabel_lookup(3) β€” behaves identically, except she does not perform context translation. Same girl, no translation, periodt.

And the FILES section below? That's the whole rundown of the configuration files used to determine a file context. Let's go πŸ’«


πŸ’… OPTIONS πŸ’…

On top of all the global options described over in selabel_open(3), this backend also recognizes these:

  • SELABEL_OPT_PATH β€” give this a non-null value and it specifies a path to a file that will be opened in lieu of the standard file contexts file. This value also gets used as the base name when figuring out the names of local customization files. Two jobs, one icon πŸ‘‘
  • SELABEL_OPT_BASEONLY β€” a non-null value here indicates that any local customizations to the file contexts mapping should just be ignored. Not today, customizations πŸ’€
  • SELABEL_OPT_SUBSET β€” a non-null value is interpreted as a path prefix, for example "/etc". Only file context specifications whose first component prefix-matches the given prefix get loaded. This may increase lookup performance, but lowkey any attempt to look up a path that doesn't start with that prefix may fail 😭. Also: this optimization is no longer required thanks to file_contexts.bin files, and it is deprecated. Old news, bestie.

πŸŽ€ FILES πŸŽ€

Which file context files get used to retrieve the default context depends on the SELABEL_OPT_PATH parameter you passed to selabel_open(3). If it's NULL, then the SELABEL_OPT_PATH value defaults to the active policy file contexts location (as returned by selinux_file_context_path(3)). Otherwise, the actual SELABEL_OPT_PATH value you specified is the one that gets used. Simple as that πŸ’–

If SELABEL_OPT_BASEONLY is set πŸ¦‹

Then these files get processed, in this order:

  1. The mandatory file contexts file β€” that's either the fully qualified file name from SELABEL_OPT_PATH.value, or if that's NULL, the path returned by selinux_file_context_path(3).
  2. The optional local and distribution substitution files that perform path aliasing on the 'in memory' version of the file contexts file. These files have the same name as the mandatory file contexts file, with the extensions .subs and .subs_dist added. πŸ’«

If SELABEL_OPT_BASEONLY is NOT set 🌈

Then these files get processed:

  1. The mandatory file contexts file β€” either the fully qualified file name from SELABEL_OPT_PATH.value, or if NULL, the path returned by selinux_file_context_path(3).
  2. The optional local customizations file, which has the same name as the mandatory file contexts file with the extension .local added. selinux_file_context_local_path(3) will return the default path to this file.
  3. The optional user home directory customizations file, which has the same name as the mandatory file contexts file with the extension .homedirs added. selinux_file_context_homedir_path(3) will return the default path to this file.
  4. The optional local and distribution substitution files, which perform any path aliasing on the 'in memory' version of the file contexts file (and the .local and/or .homedirs if present). These files have the same name as the mandatory file contexts file with the extensions .subs and .subs_dist added. selinux_file_context_subs_path(3) and selinux_file_context_subs_dist_path(3) will return the default paths to these files.

The default file context series of files πŸ‘‘

/etc/selinux/{SELINUXTYPE}/contexts/files/file_contexts
/etc/selinux/{SELINUXTYPE}/contexts/files/file_contexts.local
/etc/selinux/{SELINUXTYPE}/contexts/files/file_contexts.homedirs
/etc/selinux/{SELINUXTYPE}/contexts/files/file_contexts.subs
/etc/selinux/{SELINUXTYPE}/contexts/files/file_contexts.subs_dist

Where {SELINUXTYPE} is the entry from the selinux configuration file config (see selinux_config(5)).

And the vibe check: only the file_contexts file is mandatory β€” the rest are optional, they're just there if you want them 🫢

The entries inside the file contexts series of files are all shown in the FILE FORMAT section below, so keep reading bestie ⭐


πŸ¦‹ FILE FORMAT πŸ¦‹

File Contexts Format

Every single line inside the file_contexts file and the two customization files (.local and .homedirs) looks like this:

pathname [file_type] context

Where:

  • pathname β€” an entry that defines the path to be labeled. It may contain either a fully qualified path, or a Perl compatible regular expression (PCRE), describing fully qualified path(s). The only PCRE flag in use is PCRE2_DOTALL, which causes a wildcard . to match anything, including a new line. Strings representing paths are processed as bytes (as opposed to Unicode), meaning that non-ASCII characters are not matched by a single wildcard. okay noted πŸ“
  • file_type β€” an optional file type consisting of:
    • -b β€” Block Device
    • -c β€” Character Device
    • -d β€” Directory
    • -p β€” Named Pipe
    • -l β€” Symbolic Link
    • -s β€” Socket
    • -- β€” Ordinary file
  • context β€” this entry can be either:
    1. The security context that will be assigned to the file (i.e. returned as context).
    2. A value of <<none>>, which can be used to indicate that the matching files should not be re-labeled β€” and this causes selabel_lookup(3) to return -1 with errno set to ENOENT.

Example:

# ./contexts/files/file_contexts
# pathname file_type  context
/.*                   system_u:object_r:default_t:s0
/[^/]+        --      system_u:object_r:etc_runtime_t:s0
/tmp/.*               <<none>>

Substitution File Format

Each line within the substitution files (.subs and .subs_dist) has the form:

subs_pathname pathname

Where:

  • pathname β€” a path that matches an entry in one or more of the file contexts policy configuration file.
  • subs_pathname β€” the path that will be aliased (considered equivalent) with pathname by the look up process. ✨

Example:

# ./contexts/files/file_contexts.subs
# pathname  subs_pathname
/myweb      /var/www
/myspool    /var/spool/mail

Using the above example, when selabel_lookup(3) is passed a path of /myweb/index.html the function will substitute the /myweb component with /var/www, therefore the path used is:

/var/www/index.html

🌸 NOTES 🌸

  1. If contexts are to be validated, then the global option SELABEL_OPT_VALIDATE must be set before calling selabel_open(3). If this is not set, then it is possible for an invalid context to be returned. Do not skip this step bestie, it's giving risky πŸ’€
  2. If the size of file contexts series of files contain many entries, then selabel_open(3) may have a delay as it reads in the files, and if requested validates the entries. She's thorough, she takes her time 🧚
  3. Depending on the version of SELinux it is possible that a file_contexts.template file may also be present, however this is now deprecated. The template file has the same format as the file_contexts file and may also contain the keywords HOME_ROOT, HOME_DIR, ROLE and USER. This functionality has now been moved to the policy store and is managed by semodule(8) and genhomedircon(8).

⭐ SEE ALSO ⭐

selinux(8), selabel_open(3), selabel_lookup(3), selabel_stats(3), selabel_close(3), selinux_set_callback(3), selinux_file_context_path(3), freecon(3), selinux_config(5), lstat(2), selinux_file_context_subs_path(3), selinux_file_context_subs_dist_path(3), selinux_file_context_homedir_path(3), selinux_file_context_local_path(3), semodule(8), genhomedircon(8)


and that's the whole page, bestie πŸ’– that was Security Enhanced Linux, dated 01 Dec 2011 β€” she's been iconic since day one, slay, go label some files πŸŽ€βœ¨