Provided by: xchpst_0.6.2-1_amd64 bug

NAME

       xchpst — eXtended CHange Process STate

SYNOPSIS

       xchpst --help
       xchpst --version
       xchpst --exit[=retcode]
       xchpst [OPTIONS] [--] command ...

DESCRIPTION

       The  xchpst  utility  changes  process state according to the supplied options and then calls exec() on a
       named executable with the positional arguments.

       xchpst is a backwards-compatible extension to the chpst(8) tool which is  supplied  with  runit.   xchpst
       enables  runit  service  scripts  to take advantage of hardening capabilities available with recent Linux
       kernels such as namespaces and capabilities.  xchpst can set up shadow  subtrees  within  the  filesystem
       hierarchy  to  isolate  long-running  services  from  parts  of the system to which they ought to need no
       access, e.g. with private /tmp areas and read-only /usr.

   Extended xchpst options
       The extra options provided by xchpst are as follows:

       --help      Show help text and usage.

       --file file
                   Read options from file.  See “Options file” for the file format.

       --exit[=retcode]
                   Exit immediately with exit  status  0  if  the  given  options  are  supported.   retcode  if
                   specified.

       --mount-ns  Create new mount namespace.  Various other options also implicitly enable mount namespaces as
                   this  is  important  to  their  operation;  this  option  is rarely likely to be needed to be
                   specified explicitly.

       --net-ns    Create new network namespace.  This will more or less isolate the process from the networking
                   subsystem.

       --uts-ns    Create new UTS namespace.

       --pid-ns    Create a PID namespace.  This implies --fork-join because a new process is needed to  act  as
                   PID 1 and in order to be able to mount a new procfs for the namespace.

       --fork-join
                   Fork  a  new  process  and wait for it to finish, passing on to the child process any signals
                   received by the  xchpst  process.   This  option  is  necessary  to  take  advantage  of  PID
                   namespaces.  The exit status is that of the child process.

       --user-ns   Create a user namespace.

       --adopt-net path
                   Adopt  the  network namespace bound to path.  The binding will be deleted from the filesystem
                   meaning that the namespace will disappear when the  process  exits,  if  there  is  no  other
                   reference  to  it. This allows the calling script to set up a suitable networking environment
                   for the process and hand it over.

       --new-root  Create a new root filesystem (will implicitly enable the creation of a new mount  namespace).
                   The  new  root  filesystem  is  created  as  a tmpfs and all the top-level directories in the
                   original root filesystem are bind mounted and any symlinks are replicated.

       --private-run
                   Mount an isolated /run directory for the process.  Unless --new-root is also  specified,  the
                   old shared /run directory will still be accessible if the stacked mount is removed.

       --private-tmp
                   Mount  an  isolated /tmp directory for the process.  Unless --new-root is also specified, the
                   old shared /tmp directory will still be accessible if the stacked mount is removed.

       --protect-home
                   Mount isolated /home, /root and /run/user directories for the process.  Unless --new-root  is
                   also  specified,  the  old  shared  host  directories will still be accessible if the stacked
                   mounts are removed.

       --ro-sys    Convert /usr and /boot into read-only mounts.  Note that if  the  hardened  process  has  the
                   rights  to  unmount  filesystems,  it  can  reveal  the  original  writable filesystems.  The
                   --new-root option is designed to prevent this.  Alternatively, use  --cap-bs-drop  to  remove
                   the ‘CAP_SYS_ADMIN’ capability, preventing the bind mount from being unmounted.

       --ro-home   Convert  /home,  /root  and  and  /run/usr  into  read-only mounts.  This option has the same
                   limitations as --ro-sys.

       --ro-etc    Convert /etc into a read-only mount.  This option has the same limitations as --ro-sys.

       --caps-bs-keep capability[,capability...]
                   Keeps only the listed capabilities in the bounding set.

       --caps-bs-drop capability[,capability...]
                   Drops the listed capabilities from the bounding  set.   Use  only  one  of  the  two  options
                   governing the bounding set.

       --caps-keep capability[,capability...]
                   Retain the listed capabilities when dropping to a non-root user.

       --caps-drop capability[,capability...]
                   Drop the listed capabilities when dropping to a non-root user, but retain all others.

       --no-new-privs
                   Prevent    the    target    application    from    obtaining   any   new   privileges.    See
                   PR_SET_NO_NEW_PRIVS(2const).

       --cpu-scheduler other|batch|idle
                   Set the scheduler policy, as per sched_setscheduler(2).

       --io-scheduler rt|best-effort|idle[:priority]
                   Set the I/O scheduler policy and priority, as per ionice(1).

       --cpus start[-end[:stride]][,...]
                   Set CPU affinity in the same format as taskset(1).

       --umask mode
                   Set umask to the octal value mode.

       --app name  Override program name used for pre-creating system directories.

       --run-dir   Create a directory for the program under /run, owned by the appropriate user.

       --state-dir
                   Create a directory for the program under /var/lib, owned by the appropriate user.

       --log-dir   Create a directory for the program under /var/log, owned by the appropriate user.

       --cache-dir
                   Create a directory for the program under /var/cache, owned by the appropriate user.

       --login     Create a login environment, using the user specified by -u, -U or the current user, in  order
                   of  preference.  If this option is specified and no command is specified to be executed, then
                   the shell defined for the given user is launched, instead of an error being returned.

       --oom adjustment
                   Set the out-of-memory (OOM) score adjustment to adjustment.

       -s bytes    Set soft limit for stack segment size.

       -a bytes    Set soft limit for address space size.

       --limit-memlock bytes
                   Set soft limit for amount of locked memory.

       --limit-msgqueue bytes
                   Set soft limit for message queue space for this user.

       --limit-nice niceness
                   Set 20 minus the minimum niceness possible for this process.

       --limit-rtptio prio
                   Set soft limit for real time priority of the process.

       --limit-rttime ms
                   Set soft limit for amount of real time processing between blocking system calls.

       --limit-sigpending number
                   Set soft limit for the number of pending signals permitted for the process.

       --limit-locks number
                   Set soft limit for the number of file locks that this process may hold.

       --hardlimit
                   Also set the hard limit for any soft limit option that follows.

       -@          Switch to chpst-compatible option handling only for the remaining options. This is to support
                   scripts that can convert an xchpst invocation into a command line for chpst if xchpst is  not
                   present on the system.

   chpst-compatible options
       The options compatible with classic chpst are as follows:

       -u user[:group]...
                 Set  uid,  gid and supplementary groups. Prepend the argument with a colon for numerical inputs
                 rather than names to be looked up. If no group is specified then the specified user's group  is
                 used. There is no space within the argument.

       -U user[:group]
                 Like  -u  but  the  environment  variables  UID  and  GID are set instead of changing the user.
                 Supplementary groups are ignored.

       -b argv0  Set argv[0] to argv0 instead of the target executable path when launching the program.

       -e dir    Populate environment.  For every file  within  dir,  the  filename  represents  an  environment
                 variable  that  will be set or unset.  The first line of the corresponding files is the content
                 to be set, with NUL characters replaced by LF and trailing whitespace removed.  If the file  is
                 0  bytes  long  then  the  variable  is  unset.   (So a file with just a newline results in the
                 variable being set with an empty value.)

       -/ dir    Run in a chroot.  Change to the dir directory and make it the new root.

       -C dir    Change directory.  Change to the dir directory (after any chroot setting is applied).

       -n inc    Increase niceness by inc, which can be negative, resulting  in  the  process  taking  a  higher
                 priority.

       -l file   Wait for lock. Take a lock out on file and wait to obtain it before proceeding to exec().

       -L file   Try to obtain lock; bail out if it can't be obtained.

       -m bytes  Set soft limit for data and stack segments and virtual memory size and locked memory.

       -d bytes  Set soft limit for data segment size.

       -o files  Set soft limit for the number of open files.

       -p procs  Set soft limit for the number of processes for this user.

       -f bytes  Set soft limit for the size of file that this process may create.

       -c bytes  Set soft limit for the size of core this process may dump.

       -t seconds
                 Set soft limit for the amount of CPU time this process may consume.

       -v        Be verbose. This option may be repeated for increased verbosity to support debugging.

       -V        Show xchpst version number.

       -P        Make this process the process group leader, allocating a new session idea.

       -0        Close stdin.

       -1        Close stout.

       -2        Close stderr.

   Resource limit options
       The resource limit options above take a parameter in one of the following forms:

       soft       Set  only  the  soft  limit,  in  the  style  of  chpst  and softlimit, unless --hardlimit has
                  previously been specified, in which case both soft and hard limits are defined, in  the  style
                  of prlimit.

       soft:      Set only the soft limit, in the style of prlimit(1).

       soft:hard  Set soft and hard limits.

       :hard      Set only the hard limit.

       +both      Set both soft and hard limits.

       An unlimited limit may be selected by any value of ‘-1’, ‘unlimited’ or ‘infinity’.

   Emulating ancestor tools
       When  invoked  as  chpst,  envdir,  envuidgid,  pgrphack,  setlock,  setuidgid,  or softlimit, the xchpst
       executable emulates the corresponding tools from the “runit” or “daemontools” packages respectively.   As
       an additional feature, all these tools when so invoked, accept the -v option to increase verbosity.

   Options file
       An  options  file  specifies  additional options to apply, one option per line.  Each line begins with an
       option name.  Options that take an argument have horizontal white space and the  option  value  following
       the  option  name.  Comments begin with a ‘#’ character and may only be preceded by whitespace, otherwise
       they will be interpreted as part of an option name or value.

       Example options file:

             # Comment line
             private-tmp
             app my app
             run-dir
             pid-ns

EXIT STATUS

       0       The default exit status when --exit is specified is 0. This can be used for  a  quick  test  that
               xchpst is available on the system in shell scripts and that the given options are supported.

       100     The  return  code when an invalid option or option argument is specified, including if a username
               cannot be resolved, for example.

       111     When the requested process state cannot be changed.

       other   The --exit option takes an optional argument with a return code to use.

       If there is no error and the intended application is exec()'d, the  exit  status  will  be  that  of  the
       application, not xchpst.

   Behaviour on failure to apply
       The  table  below  divides  the  process change options between those that abort on failure to effect the
       requested change (with error code 111) and those that continue execution. Nonsense  configuration  values
       always fail with error code 100.

       ┌──────────────────┬──────────────────────────────────────────┬─────────────────────────────────────────┐
       │ Option groupAbort on errorContinue on error                        │
       ├──────────────────┼──────────────────────────────────────────┼─────────────────────────────────────────┤
       │ chpst            │ u e / C n L l m d s a o p f c r t        │U b 0 1 2                                │
       ├──────────────────┼──────────────────────────────────────────┼─────────────────────────────────────────┤
       │ rlimit           │ limit-memlock limit-msgqueue limit-nice  │                                         │
       │                  │ limit-rtprio     limit-rttime    limit-  │                                         │
       │                  │ sigpending limit-locks                   │                                         │
       ├──────────────────┼──────────────────────────────────────────┼─────────────────────────────────────────┤
       │ namespaces       │ fork-join  new-root   mount-ns   net-ns  │                                         │
       │                  │ user-ns pid-ns uts-ns net-adopt          │                                         │
       ├──────────────────┼──────────────────────────────────────────┼─────────────────────────────────────────┤
       │ capabilities [1] │                                          │cap-bs-keep cap-bs-drop caps-keep caps-  │
       │                  │                                          │drop                                     │
       ├──────────────────┼──────────────────────────────────────────┼─────────────────────────────────────────┤
       │ filesystem       │ private-run   private-tmp  protect-home  │                                         │
       │                  │ ro-sys ro-home ro-etc run-dir state-dir  │                                         │
       │                  │ cache-dir log-dir                        │                                         │
       ├──────────────────┼──────────────────────────────────────────┼─────────────────────────────────────────┤
       │ other            │                                          │cpus cpu-scheduler io-scheduler no-new-  │
       │                  │                                          │privs umask oom login                    │
       └──────────────────┴──────────────────────────────────────────┴─────────────────────────────────────────┘

       [1]  If capabilities are not available in the kernel, errors are ignored.  Otherwise any  failure  causes
            an abort.  See “BUGS”

NOTES

   systemd option mapping
       The  table  below shows how some systemd service directives map onto xchpst options.  See systemd.exec(5)
       This is not an exhaustive list.
       ┌──────────────────────────────┬───────────────┬────────────────────────────────────────────────────────┐
       │ systemdxchpstDifferences                                            │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ ProtectSystem=yes            │ ro-sys        │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ ProtectSystem=full           │ ro-sys ro-etc │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ ProtectHome=read-only        │ ro-home       │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ ProtectHome=tmpfs            │ protect-home  │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ PrivateTmp=yes               │ private-tmp   │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ CapabilityBoundingSet=       │ cap-bs-keep   │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ CapabilityBoundingSet=~      │ cap-bs-drop   │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ AmbientCapabilities=         │ caps-keep     │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ AmbientCapabilities=~        │ caps-drop     │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ NoNewPrivileges=yes          │ no-new-privs  │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ CPUAffinity=                 │ cpus          │ use taskset(1) format                                  │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ CPUSchedulingPolicy=         │ cpu-scheduler │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ IOSchedulingClass=           │ io-scheduler  │                                                        │
       │ IOSchedulingPriority=        │               │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ UMask=                       │ umask         │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ RuntimeDirectory=            │ run-dir       │ Leaf name governed by target command or ‘app’ option   │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ StateDirectory=              │ state-dir     │ Leaf name governed by target command or ‘app’ option   │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ CacheDirectory=              │ cache-dir     │ Leaf name governed by target command or ‘app’ option   │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ LogsDirectory=               │ log-dir       │ Leaf name governed by target command or ‘app’ option   │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ OOMScoreAdjust=              │ oom           │                                                        │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ User=                        │ u             │ Check  syntax. In particular, numeric ids begin with a │
       │ Group=                       │               │ colon.                                                 │
       ├──────────────────────────────┼───────────────┼────────────────────────────────────────────────────────┤
       │ User=  with  ExecStart=+  or │ U             │ In these  modes,  systemd  does  not  drop  the  user, │
       │ ExecStart=!                  │               │ expecting the application to do that, but instead uses │
       │                              │               │ the  specified  username  for  other options.  In this │
       │                              │               │ case the environment variable setting by xchpst is not │
       │                              │               │ useful but other options like ‘run-dir’ will  use  the │
       │                              │               │ right user.                                            │
       └──────────────────────────────┴───────────────┴────────────────────────────────────────────────────────┘

   Resource limit option mapping
       The table below shows how xchpst resource limit options correspond to those of other tools.
       ┌──────────────────┬───────┬───────────┬─────────┬─────────┬──────────────────┐
       │ xchpstchpstsoftlimitprlimitulimitsystemd          │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ d                │ d     │ d         │ d       │ d       │ LimitDATA=       │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ o                │ o     │ o         │ n       │ n       │ LimitNOFILE=     │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ p                │ p     │ p         │ u       │ u       │ LimitNPROC=      │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ f                │ f     │ f         │ f       │ f       │ LimitFSIZE=      │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ c                │ c     │ c         │ c       │ c       │ LimitCORE=       │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ t                │ t     │ t         │ t       │ t       │ LimitCPU=        │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ r                │       │ r         │ m       │ m       │ LimitRSS=        │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ s                │       │ s         │ s       │ s       │ LimitSTACK=      │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ a                │       │ a         │ v       │ v       │ LimitAS=         │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ m                │ m     │ m         │ d s l v │ d s l v │ LimitDATA=       │
       │                  │       │           │         │         │ LimitSTACK=      │
       │                  │       │           │         │         │ LimitAS=         │
       │                  │       │           │         │         │ LimitMEMLOCK=    │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ limit-memlock    │       │ l         │ l       │ l       │ LimitMEMLOCK=    │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ limit-msgqueue   │       │           │ q       │ q       │ LimitMSGQUEUE=   │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ limit-nice       │       │           │ e       │ e       │ LimitNICE=       │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ limit-rtprio     │       │           │ r       │ r       │ LimitRTPRIO=     │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ limit-rttime     │       │           │ y       │ R       │ LimitRTTIME=     │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ limit-sigpending │       │           │ i       │ i       │ LimitSIGPENDING= │
       ├──────────────────┼───────┼───────────┼─────────┼─────────┼──────────────────┤
       │ limit-locks      │       │           │ x       │ x       │ LimitLOCKS=      │
       └──────────────────┴───────┴───────────┴─────────┴─────────┴──────────────────┘
       The following options from the bash ulimit command are not available: b k p P T.

BUGS

       The --cpu-scheduler option should accept more scheduling policies and should accept additional parameters
       to  qualify  those  policies.  Currently unknown policy names are treated as the default Linux scheduling
       policy.

       When the kernel supports capabilities but not specific  capabilities  that  have  been  requested  to  be
       dropped or kept, xchpst should continue rather than aborting.

EXAMPLES

       Testing the emulation of ‘envdir’:
             xchpst -b envdir -- xchpst

       Launch with read-only filesystem if xchpst is available, else use chpst:
             xchpst   --exit   &&   exec  xchpst  --ro-sys  -l  /var/lock/ntpsec-ntpdate  ntpd;  exec  chpst  -l
             /var/log/ntpsec-ntpdate ntpd

       Drop a capability from the bounding set:
             xchpst --cap-bs-drop CAP_SYS_ADMIN -- acmed

       Drop user while retaining some capabilities:
             xchpst -u :500:500 --caps-keep CAP_DAC_OVERRIDE fakeroot /usr/sbin/gpm  -D  -m  /dev/input/mice  -t
             exps2

   Diagnostics
       To  see  what is going on, including options enabled implicitly due to other options, add the ‘--verbose’
       option.

       Use ‘--login’ without a command name to explore the hardened environment from a shell.

       You can enter the created namespaces (but not other aspects of hardening), including any synthesised root
       filesystem, by identifying the process id of the hardened application and running:
             nsenter -a -t PID

SEE ALSO

       chpst(8), runit(8),  unshare(1),  capsh(1),  taskset(1),  chrt(1),  choom(1),  proc_pid_oom_score_adj(5),
       prlimit(1), prlimit(2), namespaces(7), capabilities(7)

AUTHORS

       Andrew Bower <andrew@bower.uk>

Debian                                           March 21, 2025                                        xchpst(8)