0001
0002 #include "cap_helpers.h"
0003
0004
0005
0006
0007 int capget(cap_user_header_t header, cap_user_data_t data);
0008 int capset(cap_user_header_t header, const cap_user_data_t data);
0009
0010 int cap_enable_effective(__u64 caps, __u64 *old_caps)
0011 {
0012 struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
0013 struct __user_cap_header_struct hdr = {
0014 .version = _LINUX_CAPABILITY_VERSION_3,
0015 };
0016 __u32 cap0 = caps;
0017 __u32 cap1 = caps >> 32;
0018 int err;
0019
0020 err = capget(&hdr, data);
0021 if (err)
0022 return err;
0023
0024 if (old_caps)
0025 *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;
0026
0027 if ((data[0].effective & cap0) == cap0 &&
0028 (data[1].effective & cap1) == cap1)
0029 return 0;
0030
0031 data[0].effective |= cap0;
0032 data[1].effective |= cap1;
0033 err = capset(&hdr, data);
0034 if (err)
0035 return err;
0036
0037 return 0;
0038 }
0039
0040 int cap_disable_effective(__u64 caps, __u64 *old_caps)
0041 {
0042 struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
0043 struct __user_cap_header_struct hdr = {
0044 .version = _LINUX_CAPABILITY_VERSION_3,
0045 };
0046 __u32 cap0 = caps;
0047 __u32 cap1 = caps >> 32;
0048 int err;
0049
0050 err = capget(&hdr, data);
0051 if (err)
0052 return err;
0053
0054 if (old_caps)
0055 *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective;
0056
0057 if (!(data[0].effective & cap0) && !(data[1].effective & cap1))
0058 return 0;
0059
0060 data[0].effective &= ~cap0;
0061 data[1].effective &= ~cap1;
0062 err = capset(&hdr, data);
0063 if (err)
0064 return err;
0065
0066 return 0;
0067 }