#include <sys/capability.h> cap_iab_t cap_iab_init(void); cap_iab_t cap_iab_dup(cap_iab_t iab); cap_iab_t cap_iab_get_proc(void); cap_iab_t cap_iab_get_pid(pid_t pid); int cap_iab_set_proc(cap_iab_t iab); char *cap_iab_to_text(cap_iab_t iab); cap_iab_t cap_iab_from_text(const char *text); cap_flag_value_t cap_iab_get_vector(cap_iab_t iab, cap_iab_vector_t vec, cap_value_t val); int cap_iab_compare(cap_iab_t a, cap_iab_t b); int cap_iab_set_vector(cap_iab_t iab, cap_iab_vector_t vec, cap_value_t val, cap_flag_value_t enable); int cap_iab_fill(cap_iab_t iab, cap_iab_vector_t vec, cap_t set, cap_flag_t flag); char *cap_proc_root(const char *root);Link with -lcap.
There are some constraints enforced by the kernel with respect to the three components of an IAB tuple and the Permitted process capability flag. They are: the Inh vector is entirely equal to the process Inheritable flag at all times; the Amb vector contains no more capability values than the intersection of the Inh vector and the Permitted flag for the process; and the Bound (or blocked) vector is the twos-complement of the process bounding vector.
In some environments, it is considered desirable to naively inherit capabilities. That is pass capabilities, independent of the status of the executed binary, from parent to child through exec* system calls. The surviving capabilities become the Permitted flag for the post-exec process. This method of inheritance differs significantly from the handshake inheritance between a pre-exec* process and a file-capability bestowed executable of the traditional (POSIX.1e) capability mechanism.
The convolution rules for IAB style inheritance are: I'=I; A'=A&I; P'=A&I&P. Where P etc are the pre-exec values and P' etc are the post-exec values.
With an understanding of these convolution rules, we can explain how libcap (3) support for the IAB tuple is managed: the IAB API.
cap_iab_init () returns an empty IAB value. That is a mostly-harmless tuple. It will not block any Permitted file capabilities through exec, but it won't bestow any either. The returned cap_iab_t should be freed with cap_free (3). cap_iab_dup () returns a copy of the specified IAB value. The returned cap_iab_t should be freed with cap_free (3). cap_iab_get_proc () returns a copy of the IAB value for the current process. The returned cap_iab_t should be freed with cap_free (3). cap_iab_get_pid () returns a copy of the IAB value for the specified process. The returned cap_iab_t should be freed with cap_free (3). This function defaults to searching /proc/ <PID> /status for the IAB information, but that location can be overridden using the cap_proc_root () function. cap_iab_set_proc () can be used to set the IAB value carried by the current process. Such a setting will fail if the process is insufficiently capable. The process requires CAP_SETPCAP raised in the E flag and a superset of P and I values over those in the A vectors. cap_iab_to_text () will convert an IAB tuple to a canonical text representation. The representation is slightly redundant but libcap will try to generate as short a representation as it is able. cap_iab_from_text () generates an IAB tuple from a text string (likely generated by the previous function). The returned IAB tuple should be freed with cap_free (3). The text format accepted by cap_iab_from_text () is a comma separated list of capability values. Each capability is prefixed by nothing (or %) (Inh); ! (Bound, but think Blocked); ^ (Amb). Or, some combination thereof. Since the Amb vector is constrained to be no greater than the Inh vector, ^ is equivalent to %^. Further, unless B is non-zero, % can be omitted. The following are legal text representations: "!%cap_chown" (Bound but Inh), "!cap_chown,^cap_chown" (Bound, Inh+Amb). "cap_setuid,!cap_chown" (Inh, Bound). As noted above, this text representation is the syntax for the pam_cap.so config file. cap_iab_get_vector () can be used to determine the specific capability value of an IAB vector. cap_iab_compare () can be used to compare two cap_iab_t tuples. When the return value is non-zero, the macro CAP_IAB_DIFFERS(status, vector) evaluates to non-zero if the returned status differs in its vector components. cap_iab_set_vector () can be used to set a specific vector value to the enable setting. cap_iab_fill () can be used to wholesale copy a cap_t flag value into the vec vector of the IAB tuple. Copying into Amb in this way may implicitly raise Inh values in the IAB tuple. Similarly copying into the Inh vector may implicitly lower Amb values that are not present in the resulting Inh vector. cap_proc_root () can be used to determine the current location queried by cap_iab_get_pid (). Returned values should be released with cap_free (3). If the argument to cap_proc_root () is not NULL, a copy of it will become the replacement for /proc . Note, this function is not thread safe with respect to concurrent calls to cap_iab_get_pid ().
Unlike the traditional cap_t capability set, the IAB tuple, taken together, is incompatible with filesystem capabilities created via tools like setcap (8). That is, the Amb vector of the IAB tuple is rendered moot when an executable with a file capability is executed.
Further, there are libcap cap_mode (3)s that render the Amb vector and its method of process inheritance disabled.
https://bugzilla.kernel.org/buglist.cgi?component=libcap&list_id=1090757