diff --git a/pkgs/additional/bunpen/rt/ext/capabilities.ha b/pkgs/additional/bunpen/rt/ext/capabilities.ha index 19f7995e0..1aea046c3 100644 --- a/pkgs/additional/bunpen/rt/ext/capabilities.ha +++ b/pkgs/additional/bunpen/rt/ext/capabilities.ha @@ -292,6 +292,9 @@ export fn no_new_privs() (void | rt::errno) = { rt::prctl(rt::PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)?; }; +// set the Effective, Permitted, and Inheritable capability vectors. +// this does NOT effect the Ambient or Bounding capability sets; +// see PR_CAP_AMBIENT and PR_CAPBSET_DROP for that. export fn capset(eff: caps, prm: caps, inh: caps) (void | rt::errno) = { let hdr = user_cap_header { version = _LINUX_CAPABILITY_VERSION_3, @@ -320,3 +323,22 @@ export fn capset(eff: caps, prm: caps, inh: caps) (void | rt::errno) = { ]; syscall(rt::SYS_capset, &hdr: uintptr, &data: uintptr)?; }; + +// add the provided capability to the ambient set. +// the capability must already be in the permitted and inheritable sets (see `capset`). +// will fail if PR_CAP_AMBIENT_LOWER secure bit has been set. +export fn cap_ambient_raise(c: cap) (void | rt::errno) = { + rt::prctl(rt::PR_CAP_AMBIENT, rt::PR_CAP_AMBIENT_RAISE, c: u64, 0, 0)?; +}; + +// remove the provided capability from the ambient set. +export fn cap_ambient_lower(c: cap) (void | rt::errno) = { + rt::prctl(rt::PR_CAP_AMBIENT, rt::PR_CAP_AMBIENT_LOWER, c: u64, 0, 0)?; +}; + +// drop the provided capability from the capability bounding set. +// the effect is to make it so this thread generally can't acquire that capability +// (combine that with NO_NEW_PRIVS to be certain). +export fn capbset_drop(c: cap) (void | rt::errno) = { + rt::prctl(rt::PR_CAPBSET_DROP, c: u64, 0, 0, 0)?; +};