procmgr_ability()

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: You need to be running as root in order to change a different process's abilities.
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 an custom ability found with procmgr_ability_lookup()) that tells procnto which particular ability you're modifying.
  • 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.

Terminate the list with PROCMGR_AID_EOL.

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.

The table below describes the identifier portion for each ability, indicates whether the operation is normally privileged (e.g. rebooting the system) or not (e.g. spawning and forking), and describes the subrange if applicable. If you want to specify a subrange, include PROCMGR_AOP_SUBRANGE in the operation flags. You can also specify custom abilities that a server has defined by calling procmgr_ability_create().

Note: 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.
Identifier Privileged? Controls the process's ability to: Subrange (optional)
PROCMGR_AID_ABLE_CREATE Yes Allocate permanent identifiers for additional named abilities; for more information, see procmgr_ability_create() and procmgr_ability_lookup()
PROCMGR_AID_ABLE_PRIV Yes Enable a currently denied privileged ability, add subranges to such an ability, or inherit such an ability
PROCMGR_AID_APS_ROOT Yes Execute adaptive partitioning scheduler operations that usually require root permissions; for more information, see SchedCtl()
PROCMGR_AID_CHANNEL_CONNECT Yes Connect to channels belonging to other processes and that have a type ID other than 0. For more information, see Security Policy and Mandatory Access Control chapter of the Security Developer's Guide. Allowable channel type IDs
PROCMGR_AID_CHILD_NEWAPP Yes Create a new application ID for a child process by setting POSIX_SPAWN_NEWAPP for posix_spawn() or posix_spawnp(), or SPAWN_NEWAPP for the spawn*() functions
PROCMGR_AID_CHROOT Yes Change the root directory by calling chroot().
PROCMGR_AID_CLOCKPERIOD Yes Change the clock period, using ClockPeriod() Allowable periods, in nanoseconds
PROCMGR_AID_CLOCKSET Yes Set the clock, using clock_settime(), settimeofday(), ClockAdjust(), or ClockTime() Allowable times, in nanoseconds
PROCMGR_AID_CONFSET Yes Set configuration strings, using confstr() Allowable names (_CS_*)
PROCMGR_AID_CONNECTION Yes
  • Use ConnectFlags() to change the connection flags on a coid for another process with a different user ID
  • Use MsgSendPulse() to send a pulse to a channel that was created by a different process with a different user ID
  • Use SyncMutexEvent() with a SIGEV_PULSE sigevent that's going to a channel that was created by a different process with a different user ID
  • Call timer_create() or TimerCreate() to create a timer that sends a pulse to a process belonging to a different user
PROCMGR_AID_CPUMODE Yes Change the CPU's power management mode Allowable modes
PROCMGR_AID_DEFAULT_TIMER_TOLERANCE Yes Set the default timer tolerance for a process, using procmgr_timer_tolerance()
PROCMGR_AID_EVENT Yes Trigger privileged system-wide events, using procmgr_event_trigger() or procmgr_event_trigger_updateable() Trigger bits
PROCMGR_AID_FORK No Create a new process by calling fork()
PROCMGR_AID_GETID Yes Get the group ID or session ID of a process outside the calling process's session, by using getpgid() or getsid(), respectively
PROCMGR_AID_HIGH_RESOLUTION_TIMER Yes (QNX Neutrino 7.0.1 or later) Set the timer tolerance to a value between 0 and the clock period, by calling timer_settime(), timer_timeout(), TimerSettime(), or TimerTimeout()
PROCMGR_AID_INTERRUPT Yes Attach interrupt handlers by calling InterruptAttach() or InterruptAttachArray(), or events by calling InterruptAttachEvent(). You also need I/O privileges; see PROCMGR_AID_IO, below. Interrupt sources
PROCMGR_AID_INTERRUPTEVENT Yes (QNX Neutrino 7.0.1 or later) Attach interrupt events by calling InterruptAttachEvent(). You also need I/O privileges; see PROCMGR_AID_IO, below. Interrupt sources
PROCMGR_AID_IO Yes Request I/O privileges by calling ThreadCtl() with the _NTO_TCTL_IO or _NTO_TCTL_IO_PRIV command. (QNX Neutrino 7.0.1 or later) Level: 0 for _NTO_TCTL_IO, or 1 for _NTO_TCTL_IO_PRIV
PROCMGR_AID_KEYDATA Yes Pass data through a common client, by calling MsgKeyData(). Resource managers that don't run as root should retain this ability, or else DUP messages will fail.
PROCMGR_AID_MAC_POLICY Yes Change the security policy that procnto enforces; see secpolpush in the Utilities Reference
PROCMGR_AID_MAP_FIXED No Use mmap() with MAP_FIXED to map fixed addresses (including zero) Allowable virtual addresses
PROCMGR_AID_MEM_ADD Yes Add physical memory Allowable physical addresses
PROCMGR_AID_MEM_GLOBAL Yes Mark shared memory as being global across all processes, by calling shm_ctl() or shm_ctl_special(), specifying SHMCTL_GLOBAL
PROCMGR_AID_MEM_LOCK Yes Lock a range of process address space into physical memory, by calling mlock() or mlockall() Allowable virtual addresses
PROCMGR_AID_MEM_PEER Yes Manipulate a peer process's memory Peer process IDs
PROCMGR_AID_MEM_PHYS Yes Allowable physical addresses
PROCMGR_AID_MEM_SPECIAL Yes Call shm_ctl_special()
PROCMGR_AID_PATHSPACE Yes Add items to the procnto pathname prefix space, specifically to create symbolic links by calling pathmgr_symlink(), or to register names in the path space by calling resmgr_attach()
PROCMGR_AID_PATH_TRUST Yes Modify the list of trusted files and filesystems. For more information, see the entry for pathtrust in the Utilities Reference, as well as the description of PROT_EXEC in the entry for mmap().
PROCMGR_AID_PGRP No Set its process group ID, by calling setpgrp() or procmgr_session(). This ability is enabled by default (for POSIX conformance). You can disable it completely or restrict it to specific pid ranges. Process IDs
PROCMGR_AID_POWER Yes Set power-management parameters
PROCMGR_AID_PRIORITY Yes

The maximum unprivileged priority is usually 63, but is governed by the -P option to procnto.

Allowable priorities
PROCMGR_AID_PROT_EXEC No Load code by calling dlopen() or map memory as executable by calling mmap(), mmap_device_memory(), or mprotect() with PROT_EXEC Allowable virtual addresses
PROCMGR_AID_PROT_WRITE_AND_EXEC No Simultaneously map memory as writable and executable by calling mmap(), mmap_device_memory(), or mprotect() with PROT_WRITE | PROT_EXEC Allowable virtual addresses
PROCMGR_AID_PUBLIC_CHANNEL No Create a public channel by calling ChannelCreate() without setting _NTO_CHF_PRIVATE. Resource managers need this ability in order to create a public channel when they call dispatch_create_channel() or resmgr_attach(). Programs that aren't resource managers need it in order to create a public channel when they call name_attach(). You might also need this ability when you call message_attach(), pulse_attach(), or select_attach().
PROCMGR_AID_QNET Yes Used by Qnet when it creates a channel.
PROCMGR_AID_QVM Yes Reserved for the hypervisor
PROCMGR_AID_RCONSTRAINT No Operate without any resource constraints. For more information, see Resource constraint thresholds in the “Processes” chapter of the QNX Neutrino Programmer's Guide.
PROCMGR_AID_REBOOT Yes Cause the system to reboot by calling sysmgr_reboot()
PROCMGR_AID_RLIMIT Yes Use setrlimit() to raise hard limits on system resources Limits (RLIMIT_*) that it can raise
PROCMGR_AID_RLIMIT_PEER Yes Raise hard limits on system resources for other processes. Allowable user IDs
PROCMGR_AID_RSRCDBMGR Yes Use the rsrcdbmgr*() functions to manipulate the resource database manager
PROCMGR_AID_RUNSTATE Yes Use sysmgr_runstate() and sysmgr_runstate_dynamic() to control a CPU's running state Allowable CPU numbers
PROCMGR_AID_RUNSTATE_BURST No Use sysmgr_runstate_burst() to tell the kernel to turn on any offlined CPUs because the system is about to get busy The maximum length of time, in milliseconds, for which the process is allowed to set burst mode
PROCMGR_AID_SANDBOX Yes Create and delete sandboxes, attach a process to a sandbox, and detach a process from a sandbox.
PROCMGR_AID_SCHEDULE Yes Use SchedCtl() with the SCHED_CONFIGURE command, SchedGet(), sched_getparam(), sched_getscheduler(), SchedSet(), sched_setparam(), or sched_setscheduler() to get or set the scheduling policy and parameters for a process whose user ID is different from the calling process's real or effective user ID
PROCMGR_AID_SESSION Yes Use procmgr_session() to change a character terminal's process group or to send a signal to a member of a session group Allowable session IDs
PROCMGR_AID_SETGID Yes Set its real or effective group ID to values other than its real or effective group ID or its saved set-group ID, by calling setgid(), setegid(), setregid(), or change or delete its supplementary group IDs by calling setgroups() Allowable group IDs
PROCMGR_AID_SETTYPEID Yes Specify a type identifier in a call to posix_spawn or to call procmgr_set_type_id. This ability supports subranges that control which type identifiers a process is able to use. A process may not even spawn a process or set its type to its current type if it lacks the ability. For more information, see Security Policy and Mandatory Access Control chapter of the Security Developer's Guide. Allowable type IDs
PROCMGR_AID_SETUID Yes Set its real or effective user ID to values other than its real or effective user ID or its saved set-user ID, by calling seteuid(), setuid(), or setreuid() Allowable user IDs
PROCMGR_AID_SIGNAL Yes Allowable signals
PROCMGR_AID_SPAWN No Spawn new processes by calling exec*(), spawn*, or posix_spawn()
PROCMGR_AID_SPAWN_SETGID Yes Set the group ID of the child process when using posix_spawn() Allowable group IDs
PROCMGR_AID_SPAWN_SETUID Yes Set the user ID of the child process when using posix_spawn() Allowable user IDs
PROCMGR_AID_SRANDOM Yes Use SysSrandom() to install a source of entropy for the kernel's pseudorandom number generator
PROCMGR_AID_SWAP Yes Enable, disable, or configure the memory swapper
PROCMGR_AID_TIMER Yes Get timer information for a process belonging to a different user and reset overruns by calling TimerInfo() Timer IDs
PROCMGR_AID_TRACE Yes Add handlers for trace events or allocate the instrumented kernel's trace buffers by calling TraceEvent()
PROCMGR_AID_UMASK Yes Change the file-mode creation mask for a process with a different effective user ID
PROCMGR_AID_V86 Yes Call _intr_v86()
PROCMGR_AID_WAIT Yes Use wait(), wait3(), wait4(), waitid(), or waitpid() to wait for the status of a terminated child process whose real or saved user ID is different from the calling process's real or effective user ID Child process IDs
PROCMGR_AID_XPROCESS_ABLE Yes Change the abilities of another process.
PROCMGR_AID_XPROCESS_DEBUG Yes Open for writing the /proc/pid/as or /proc/pid/ctl files of another process that's running as a different user ID than the requesting process. Doing this is required to debug a process. User IDs that can be accessed
PROCMGR_AID_XPROCESS_MEM_READ Yes Open for reading the /proc/pid/as file of another process that's running as a different user ID than the requesting process. This ability is required to create core files, for full pidin functionality, and for debugging another process. User IDs that can be accessed
PROCMGR_AID_XPROCESS_QUERY Yes
  • Use clock_gettime(), ClockTime(), ConnectFlags(), or TimerInfo() to request information about another process.
  • Open for reading the /proc/pid/* files (except for the as file) of another process that's running as a different user ID than the requesting process.
Allowable user IDs
PROCMGR_AID_XTHREAD_THREADCTL No Use ThreadCtlExt() or ThreadCtlExt_r() to control a thread other than the calling thread. By default, all processes have this ability for all commands (that is, by default a thread is allowed to invoke a ThreadCtlExt() command on a different thread in the same process). _NTO_TCTL_* commands

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 be root when doing this for privileged abilities.
PROCMGR_AOP_SUBRANGE
Restrict the feature to set its “parameter” to a certain subrange in the specified domain(s). You must still have the PROCMGR_AOP_ALLOW flag set for the ability in the domain to successfully use the feature.

The meaning of the “parameter” varies, 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 be root when doing this for privileged abilities.

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.

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's running as root.
PROCMGR_ADN_NONROOT
Modify the ability of the process when it isn't running as root.

There's also a special ability identifier, PROCMGR_AID_EOL, that indicates the end of the list of abilities passed to this function.

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.

Returns:

EOK
The abilities were successfully modified.
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 non-root process tried to give itself a privileged ability, change a locked ability, or change the abilities for another process.
  • 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 Yes
Thread Yes