Control a process's ability to perform certain operations
Synopsis:
#include <sys/procmgr.h>
int procmgr_ability( pid_t pid,
unsigned ability, ... );
Arguments:
- pid
- The process ID of the process whose abilities you want to control,
or 0 to control those of the calling process.
Note:
In order to change a different process's abilities, your process needs the
PROCMGR_AID_XPROCESS_ABLE ability enabled.
- ability
- A list of the abilities. Each ability in the list is composed of three separate components that
are ORed together:
- An identifier (PROCMGR_AID_*, or a custom ability found with procmgr_ability_lookup()) that
tells procnto which particular ability you're modifying. See Abilities in the Security Policy Guide for the table detailing the abilities
and their names.
- One or more operations (PROCMGR_AOP_*) that identify the operation you're
performing on the ability.
- One or more domains (PROCMGR_ADN_*) that indicate whether you're modifying what
you can do with the ability while running as root or
non-root.
Note:
Terminate the list with the special ability
identifier
PROCMGR_AID_EOL.
You can OR the domain flags and any of
PROCMGR_AOP_DENY, PROCMGR_AOP_ALLOW, and
PROCMGR_AOP_LOCK into the PROCMGR_AID_EOL macro that ends the list. If
you do this, the operations are performed on all the unlocked abilities that you didn't
specify in the list.
- uint64_t lower, uint64_t upper
- If the ability is for a subrange (see below), follow it by two
uint64_t arguments that specify the lower and upper limits
on the range.
Library:
libc
Use the -l c option to
qcc
to link against this library.
This library is usually included automatically.
Description:
The procmgr_ability() function takes a list of ability operations to control
what the identified process is allowed to do. This function lets a process start running as
root, set the abilities it needs, and then change its group and user IDs. This
can make your system more secure by reducing the number of potentially vulnerable processes running
as root.
Note:
- Using a security policy is more secure and less error-prone
than calling procmgr_ability().
- If you want to set more than one ability, you must specify a separate
identifier-operation-domain argument (with any subranges) for each. The identifiers are an
enumeration; don't try to OR them together.
You must OR in at least one of the following operations:
- PROCMGR_AOP_DENY
- Disallow the performance of the operation in the specified domain(s).
- PROCMGR_AOP_ALLOW
- Allow the performance of the operation in the specified domain(s).
You must have the PROCMGR_AID_ABLE_PRIV ability enabled to do this for privileged abilities.
- PROCMGR_AOP_SUBRANGE
- Restrict the feature to set its parameter to a certain subrange
in the specified domain(s).
The meaning of the parameter depends on on the ability, as described above.
Follow the ability entry in the function's parameter list
with two uint64_t arguments that give the lower and upper
bounds of the subrange.
You must have the PROCMGR_AID_ABLE_PRIV ability enabled to do this for privileged abilities.
Note the following:
- You must still have the PROCMGR_AOP_ALLOW flag
set for the ability in the domain in order to successfully use the feature.
- If you don't specify a subrange on an ability, and the ability is allowed, then it's allowed for
the entire range.
- If you specify a subrange on an ability, and the ability is allowed, it's allowed for just
the subranges specified.
- If you specify a subrange on an ability, and the ability is denied, the set subranges are ignored;
the ability is denied regardless of the requested range.
- If you specify the PROCMGR_AOP_SUBRANGE and PROCMGR_AOP_DENY flags together,
the ability is denied, but the allowed subranges list (should the ability be enabled in the future)
is modified to add the new range listed.
- You can have multiple subrange entries in the list; they OR
together to let you form a discontiguous set.
To do this, specify the identifier-operation-domain argument again,
followed by another pair of range arguments.
For access checks that span a range, the entire range must be covered by a single subrange.
For example, the PROCMGR_AID_MEM_PHYS ability with the enabled subranges 100–200
and 190–300 would not allow a request for the subrange 150–250.
- Subranges can never be deleted once added to an ability.
A PROCMGR_AOP_DENY doesn't delete any subranges associated with the ability being dropped.
Any request to set a subrange adds to the list of allowed subranges.
- PROCMGR_AOP_LOCK
- Lock the current ability so that no further changes to it can be made.
- PROCMGR_AOP_INHERIT_YES
- The changes to the ability are inherited across a spawn
or exec.
- PROCMGR_AOP_INHERIT_NO
- The changes to the ability aren't inherited across a
spawn or exec.
This is the default.
Note:
For a
fork(),
the parent's ability configuration is copied to the child verbatim,
regardless of the INHERIT status of each of the abilities.
You must OR in at least one of the following for the domain portion:
- PROCMGR_ADN_ROOT
- Modify the ability of the process when it has an effective user ID of 0.
- PROCMGR_ADN_NONROOT
- Modify the ability of the process when it has an effective user ID other than 0.
Returns:
- EOK
- The abilities were successfully modified.
- E2BIG
- The list of abilities is too large.
You might not have terminated the list with PROCMGR_AID_EOL.
- EINVAL
- There's something wrong with the parameters to the function.
- ENXIO
- (QNX Neutrino 7.0 or later) The process indicated by pid is no longer valid.
It's going away, has core dumped, or become a zombie.
- EPERM
- One of the following:
- A process that does not have PROCMGR_AID_ABLE_PRIV tried to give itself a
privileged ability.
- A process that does not have PROCMGR_AID_XPROCESS_ABLE tried to
change the abilities of another process.
- A process tried to change a locked ability and procnto was not
run with the -bl option.
- One of the specified abilities has a temporary ID (i.e., has PROCMGR_AID_UNCREATED
ORed into it).
Examples:
Remove the ability for a root process to set the
user ID when spawning a process:
procmgr_ability(0,
PROCMGR_ADN_ROOT|PROCMGR_AOP_DENY|PROCMGR_AID_SPAWN_SETUID,
PROCMGR_AID_EOL);
Regain the ability for a root process to set the
user ID:
procmgr_ability(0,
PROCMGR_ADN_ROOT|PROCMGR_AOP_ALLOW|PROCMGR_AID_SPAWN_SETUID,
PROCMGR_AID_EOL);
Drop all abilities while running as root and lock
out any further changes:
procmgr_ability(0,
PROCMGR_ADN_ROOT|PROCMGR_AOP_DENY|PROCMGR_AOP_LOCK|PROCMGR_AID_EOL);
Allow a non-root process to set the user ID while
spawning, but restrict the number to 10000 or higher and lock out any further changes.
Remove all other abilities while running as root,
and lock any further changes to them as well:
procmgr_ability(0,
PROCMGR_ADN_NONROOT|PROCMGR_AOP_ALLOW|PROCMGR_AID_SPAWN_SETUID,
PROCMGR_ADN_NONROOT|PROCMGR_AOP_SUBRANGE|PROCMGR_AOP_LOCK|PROCMGR_AID_SPAWN_SETUID,
(uint64_t)10000, ~(uint64_t)0,
PROCMGR_ADN_ROOT|PROCMGR_AOP_DENY|PROCMGR_AOP_LOCK|PROCMGR_AID_EOL);
Do the same as the above, but specify a discontiguous set of user IDs by using
a second PROCMGR_AID_SPAWN_SETUID ability:
procmgr_ability(0,
PROCMGR_ADN_NONROOT|PROCMGR_AOP_ALLOW|PROCMGR_AID_SPAWN_SETUID,
PROCMGR_ADN_NONROOT|PROCMGR_AOP_SUBRANGE|PROCMGR_AID_SPAWN_SETUID,
(uint64_t)1000, (uint64_t)1050,
PROCMGR_ADN_NONROOT|PROCMGR_AOP_SUBRANGE|PROCMGR_AOP_LOCK|PROCMGR_AID_SPAWN_SETUID,
(uint64_t)2000, (uint64_t)2013,
PROCMGR_ADN_ROOT|PROCMGR_AOP_DENY|PROCMGR_AOP_LOCK|PROCMGR_AID_EOL);
Classification:
QNX Neutrino
Safety: |
|
Cancellation point |
No |
Interrupt handler |
No |
Signal handler |
No |
Thread |
Yes |