68 lines · c
1// SPDX-License-Identifier: GPL-2.02#include "cap_helpers.h"3 4/* Avoid including <sys/capability.h> from the libcap-devel package,5 * so directly declare them here and use them from glibc.6 */7int capget(cap_user_header_t header, cap_user_data_t data);8int capset(cap_user_header_t header, const cap_user_data_t data);9 10int cap_enable_effective(__u64 caps, __u64 *old_caps)11{12 struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];13 struct __user_cap_header_struct hdr = {14 .version = _LINUX_CAPABILITY_VERSION_3,15 };16 __u32 cap0 = caps;17 __u32 cap1 = caps >> 32;18 int err;19 20 err = capget(&hdr, data);21 if (err)22 return err;23 24 if (old_caps)25 *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;26 27 if ((data[0].effective & cap0) == cap0 &&28 (data[1].effective & cap1) == cap1)29 return 0;30 31 data[0].effective |= cap0;32 data[1].effective |= cap1;33 err = capset(&hdr, data);34 if (err)35 return err;36 37 return 0;38}39 40int cap_disable_effective(__u64 caps, __u64 *old_caps)41{42 struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];43 struct __user_cap_header_struct hdr = {44 .version = _LINUX_CAPABILITY_VERSION_3,45 };46 __u32 cap0 = caps;47 __u32 cap1 = caps >> 32;48 int err;49 50 err = capget(&hdr, data);51 if (err)52 return err;53 54 if (old_caps)55 *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;56 57 if (!(data[0].effective & cap0) && !(data[1].effective & cap1))58 return 0;59 60 data[0].effective &= ~cap0;61 data[1].effective &= ~cap1;62 err = capset(&hdr, data);63 if (err)64 return err;65 66 return 0;67}68