CAP_LAUNCH(3)
π CAP_LAUNCH(3) π
okay bestie, welcome to the libcap launch functionality page π this is the <linux programmer's manual> corner of the world, and we're about to get so into it.
β¨ NAME β¨
cap_new_launcher, cap_func_launcher, cap_launcher_callback, cap_launcher_set_mode, cap_launcher_set_iab, cap_launcher_set_chroot, cap_launch, cap_launcher_setuid, cap_launcher_setgroups β the whole little squad that makes up libcap launch functionality π
πΈ SYNOPSYS πΈ
(yes bestie the manual literally spells it like that, we respect the typo, it's iconic)
#include <sys/capability.h>
cap_launch_t cap_new_launcher(const char *arg0, const char *const *argv,
const char *const *envp);
cap_launch_t cap_func_launcher(int (callback_fn)(void *detail));
int cap_launcher_callback(cap_launch_t attr,
int (callback_fn)(void *detail));
int cap_launcher_set_mode(cap_launch_t attr, cap_mode_t flavor);
cap_iab_t cap_launcher_set_iab(cap_launch_t attr, cap_iab_t iab);
int cap_launcher_set_chroot(cap_launch_t attr, const char *chroot);
#include <sys/types.h>
pid_t cap_launch(cap_launch_t attr, void *detail);
int cap_launcher_setuid(cap_launch_t attr, uid_t uid);
int cap_launcher_setgroups(cap_launch_t attr, gid_t gid,
int ngroups, const gid_t *groups);
and like, link it with -lcap, obviously π
π¦ DESCRIPTION π¦
so a launcher is literally just a little mechanism that lets your code run a callback function and/or a program executable in an environment with a modified security context. that's the whole vibe. it's basically giving a program the power to fork(2) a fresh new context off of the main program, mess with capability and other privileged state inside that fork(2)ed process, and then (optionally) execve(2) a whole new program into it. main character energy fr fr π₯
and listen β when your application links to -lpsx, you actually need this support to robustly execute the launched code without modifying the privilege of the whole (POSIX semantics honoring) main application. it's not optional, it's the move.
A launcher gets defined by one of these two functions: cap_new_launcher() or cap_func_launcher(). the return value is the opaque type cap_launch_t, and if you get back NULL, that means an error has occurred π
Once it's defined, a cap_launch_t value can be handed to cap_launch() to actually execute that launcher. and in those cases a non-negative return value means success, so:
- zero means success without a program being invoked
- non-zero means it's equal to the process ID (
pid_t) of the newly launched program π«Ά
A cap_launch_t occupies allocated memory and should be freed with cap_free(3). Before being cap_free(3)d a cap_value_t value may be reused for multiple independent launches. (yes, reusing it is allowed, we love an efficient queen β¨)
The detail argument to cap_launch(), together with the launcher's callback function, can be used to customize the invocation of the launch. but β οΈ care must be taken to leverage custom shared memory (see mmap(2)) or some other IPC to return values to the main program via detail, because the callback and any subsequent program execution will occur outside the main process of the calling application. an example of this would be to allocate detail like so:
const char *args[] = { "echo", "hello", NULL };
cap_launch_t cmd = cap_new_launcher("/usr/bin/echo", args, NULL);
int *detail = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
cap_launcher_callback(cmd, &answer_detail_fn);
*detail = 41;
pid_t pid = cap_launch(cmd, detail);
printf("launcher callback set detail to %d\n", *detail);
munmap(detail, sizeof(int));
Unless it's modified by the callback function, the launched code will execute with the capability and other security context of the application.
If the callback function returns anything other than zero, a cap_launch() will be aborted π. If the detail of the failure is important to the caller, it should be communicated via the detail argument.
The following functions can be used to instruct the launcher to modify the security state of the invoked program without altering the state of the calling program. Such modifications must be performed prior to calling cap_launch() if they are to have the desired effect. Further, they are only invoked after any installed callback has completed. For example, one can drop or modify capabilities, just for executing a file. slay.
The following functions instruct the launcher to do some common tasks of this sort β and ngl, some of them require permitted capability bits to succeed, so keep that in mind:
cap_launcher_callback()β can be used to install or replace the currently installed callback function of the launcher.cap_launcher_set_mode()β can be used to ensure that the libcap-mode of the launched program is the desired one.cap_launcher_set_iab()β this function returns thecap_iab_tpreviously associated with the launcher. Calling this function with an IAB value ofNULLwill configure the launcher to not set an IAB value (that's the default). Seecap_iab(3)for details on the IAB set. Note: the launcher is associated directly with the supplied iab value, and does not make a copy of it. This iab value is locked to the laucher and cannot be modified while associated with the launcher. Set withNULLto regain control over the memory associated with that IAB value, otherwise the IAB value will becap_free()'d when the launcher is.cap_launcher_set_chroot()β this function causes the launched program executable to be invoked inside a chroot root directory.cap_launcher_setuid()β this function causes the launched program executable to be invoked with the specified user identifier (uid_t).cap_launcher_setgroups()β this function causes the launched program executable to be invoked with the specified primary and supplementary group IDs.
β οΈ heads up bestie: if any of the launcher enhancements made by the above functions should fail to take effect (typically for a lack of sufficient privilege), the launch will fail and return -1. no cap, that's real.
π ERRORS π
A return of NULL for a cap_launch_t should be considered an error.
cap_launch() returns -1 in the case of an error.
In all such cases a return value of 0 implies success. In other cases, consult errno(3) for further details. (iykyk, go read the errno page, it's got the lore π)
π HISTORY π
The cap_launch() family of functions were introduced in libcap 2.33. It primarily addresses a complexity with -lpsx linked pthreads(7) applications that use capabilities but also honor POSIX semantics.
π¨ okay this one matters: using-lcapand-lpthreadtogether without the POSIX semantics support from-lpsxintroduces a subtle class of exposure to privilege escalation. (Seehttps://sites.google.com/site/fullycapable/who-ordered-libpsxfor an explanation.)
π«Ά SEE ALSO π«Ά
libpsx(3), psx_syscall(3), libcap(3), cap_mode(3), cap_iab(3), capabilities(7), errno(3), fork(2), mmap(2), chroot(2), and munmap(2).
and that's the whole page, bestie π
this one's stamped 2021-08-01 and comes straight from the CAP_LAUNCH(3) corner of the Linux Programmer's Manual β go forth and launch responsibly, mwah πβ¨π¦
π¦ where this page comes from
- alpine 3.22: libcap-doc 2.78-r0 Β· BSD-3-Clause OR GPL-2.0-only
- alpine 3.23: libcap-doc 2.78-r0 Β· BSD-3-Clause OR GPL-2.0-only
- alpine 3.24: libcap-doc 2.78-r0 Β· BSD-3-Clause OR GPL-2.0-only
- arch rolling: libcap 2.78-1 Β· BSD-3-Clause OR GPL-2.0-only
- centos-stream 10: libcap-devel 2.69-7.el10 Β· BSD-3-Clause OR GPL-2.0-only
- debian trixie: libcap-dev 1:2.75-10+deb13u1+b3 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 43: libcap-devel 2.76-3.fc43 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 43: libcap-devel 2.76-3.fc43 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 43: libcap-devel 2.76-4.fc43 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 43: libcap-devel 2.76-4.fc43 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 44: libcap-devel 2.77-2.fc44 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 44: libcap-devel 2.77-2.fc44 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 44: libcap-devel 2.78-1.fc44 Β· BSD-3-Clause OR GPL-2.0-only
- fedora 44: libcap-devel 2.78-1.fc44 Β· BSD-3-Clause OR GPL-2.0-only
- nixpkgs unstable: libcap 2.78
- opensuse-leap 16.0: libcap-devel 2.73-160000.3.1 Β· BSD-3-Clause OR GPL-2.0-only
- opensuse-leap 16.0: libcap-devel 2.73-160000.3.1 Β· BSD-3-Clause OR GPL-2.0-only
- opensuse-leap 16.0: libcap-devel 2.73-160000.3.1 Β· BSD-3-Clause OR GPL-2.0-only
- opensuse-leap 16.0: libcap-devel 2.73-160000.3.1 Β· BSD-3-Clause OR GPL-2.0-only
- ubuntu questing: libcap-dev 1:2.75-7ubuntu2
- ubuntu questing: libcap-dev 1:2.75-7ubuntu2.2
- ubuntu resolute: libcap-dev 1:2.75-10ubuntu2 Β· BSD-3-Clause OR GPL-2.0-only
- ubuntu stonking: libcap-dev 1:2.78-1ubuntu1 Β· BSD-3-Clause OR GPL-2.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms