1 // SPDX-License-Identifier: GPL-2.0 2 #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 */ 7 int capget(cap_user_header_t header, cap_user_data_t data); 8 int capset(cap_user_header_t header, const cap_user_data_t data); 9 10 int 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 40 int 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