Decoded: runcon (coreutils)

[Back to Project Main Page]

Note: This page explores the design of command-line utilities. It is not a user guide.
[GNU Manual] [No POSIX requirement] [Linux man] [No FreeBSD support]

Logical flow of runcon command (coreutils)

Summary

runcon - Run a command in specified SELinux context

[Source] [Code Walkthrough]

Lines of code: 265
Principal syscall: execvp()
Support syscalls: None
Options: 12 (5 short, 7 long, does not include perm digits)

Added to Coreutils in March 2007 [First version]
Number of revisions: 42 [Code Evolution]

Following the runcon implementation requires basic knowledge of the SELinux API (libselinux), specifically:

  • context_new() - Return a new context initialized to a context string.
  • context_range_set() - Set the range component. Returns nonzero if unsuccessful.
  • context_role_set() - Set the role component. Returns nonzero if unsuccessful.
  • context_type_set() - Set the type component. Returns nonzero if unsuccessful.
  • freecon() - Free the memory allocated for a context by any of the get* calls.
  • getcon() - Get current context, and set *con to refer to it. Caller must free via freecon().
  • getfilecon() - Get file context, and set *con to refer to it. Caller must free via freecon().
  • security_check_context() - Check the validity of a security context.
  • security_compute_create() - Compute a labeling decision and set *newcon to refer to it. Caller must free via freecon().
  • setexeccon() - Set exec security context for the next execve()

Setup

The setup for runcon declares local variables for context information in main():

  • compute_trans - Flag to compute the process transition context
  • context - The string containing the desired security context
  • cur_context - The string holding the current security context
  • file_context - The string holding the file context of the command to execute
  • new_context - The new context after computing transition
  • range - The range (level) component of the security context
  • role - The role component of the security context
  • type - The type component of the security context
  • user - The user component of the security context

Parsing begins with the short options passed as a string literal:
"+r:t:u:l:c"


Parsing

Parsing looks for a target security context, a command to run it in, options for both runcon and the target command, passed as it. What we need to know to know for runcon is:

  • What role, type, user, and range contexts do we need?
  • Should be compute a transition context?

Parsing failures

These failure cases are explicitly checked:

  • Not specifying a target context or a target command
  • Specifying a context component more than once

User specified parsing failures result in a short error message followed by the usage instructions. Access related parsing errors die with an error message.


Execution

runcon execution is straightforward with little branching. The idea is:

  • Verify SELinux is enabled
  • If using a transition context, compute it between target file and desired context
  • Apply any user-specified context modifications
  • Verify the resulting context
  • Prepare the new context for the next execution
  • Invoke the target command
  • Since execvp() doesn't return, further execution of runcon indicates error

The runcon utility may fail in several ways. An EXIT_FAILURE status indicates a failure of runcon, while EXIT_ENOENT or EXIT_CANNOT_INVOKE points to a problem with the target command.

Failure cases:

  • SELinux isn't enabled
  • Unable to find the current security context
  • The desired context is invalid
  • Unable to create the security context
  • Unable to compute the transition context
  • The target command didn't execute properly

All failures at this stage output an error message to STDERR and return without displaying usage help


[Back to Project Main Page]