| 27 | }; |
| 28 | |
| 29 | static Capabilities getCapabilities() |
| 30 | { |
| 31 | /// See man getcap. |
| 32 | __user_cap_header_struct request{}; |
| 33 | request.version = _LINUX_CAPABILITY_VERSION_3; |
| 34 | request.pid = getpid(); |
| 35 | |
| 36 | Capabilities ret{}; |
| 37 | __user_cap_data_struct response[2] = {}; |
| 38 | |
| 39 | /// Avoid dependency on 'libcap'. |
| 40 | if (0 == syscall(SYS_capget, &request, response)) |
| 41 | { |
| 42 | ret.effective = static_cast<UInt64>(response[1].effective) << 32 | response[0].effective; |
| 43 | ret.permitted = static_cast<UInt64>(response[1].permitted) << 32 | response[0].permitted; |
| 44 | ret.inheritable = static_cast<UInt64>(response[1].inheritable) << 32 | response[0].inheritable; |
| 45 | return ret; |
| 46 | } |
| 47 | |
| 48 | /// Does not supports V3, fallback to V1. |
| 49 | /// It's enough to check just single CAP_NET_ADMIN capability we are interested. |
| 50 | if (errno == EINVAL && 0 == syscall(SYS_capget, &request, response)) |
| 51 | { |
| 52 | ret.effective = response[0].effective; |
| 53 | ret.permitted = response[0].permitted; |
| 54 | ret.inheritable = response[0].inheritable; |
| 55 | return ret; |
| 56 | } |
| 57 | |
| 58 | throw ErrnoException(ErrorCodes::NETLINK_ERROR, "Cannot do 'capget' syscall"); |
| 59 | } |
| 60 | |
| 61 | bool hasLinuxCapability(int cap) |
| 62 | { |
no test coverage detected