[GNU Manual] [No POSIX requirement] [Linux man] [No FreeBSD support]
Summary
runcon - Run a command in specified SELinux context
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 contextcontext
- The string containing the desired security contextcur_context
- The string holding the current security contextfile_context
- The string holding the file context of the command to executenew_context
- The new context after computing transitionrange
- The range (level) component of the security contextrole
- The role component of the security contexttype
- The type component of the security contextuser
- 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