Locking an ability

An important aspect of procmgr abilities is ability locking, which allows you to force a specific ability to be immutable until the next time the process starts.

This aspect is useful if an ability never needs to be reobtained, especially by a process that is root. This also allows non-inheritable abilities to not be subsequently marked as inheritable, and so on. Keep in mind that if you lock an ability and don't mark it as inheritable, then if and when you spawn a new process, that process will not have the ability locked.

The following example demonstrates how to lock a capability by using the PROCMGR_AOP_LOCK flag, effectively preventing it from being changed during the lifetime of the process. The following example specifically adds additional security to the PROCMGR_AOP_SUBRANGE example:

procmgr_ability(0,
                PROCMGR_ADN_NONROOT           // Non-root domain
                  | PROCMGR_AOP_ALLOW         // Allow the ability
                  | PROCMGR_AOP_LOCK          // Prevent further changes
                  | PROCMGR_AOP_SUBRANGE      // Limit ability to a subrange
                  | PROCMGR_AID_SPAWN_SETUID, // Requested ability
                (uint64_t)800, (uint64_t)899, // Subrange for ability
                PROCMGR_AID_EOL               // End of ability list
);

Once this call is made, the PROCMGR_AID_SPAWN_SETUID ability can't be modified by anyone. We recommend that you immediately lock all abilities expected to be static after set.

Note: Take care when locking an allowed and inheritable ability. A vulnerability can be introduced if an allowed ability is locked and inheritable and the process then forks or spawns a child that doesn't require the ability or wishes to drop it. Locking should generally be reserved for situations where you are denying an ability. Always check the return code of procmgr_ability() and test for an error value of -1 to identify—early in development—these types of problems you may have with dropping abilities.