Checking for capabilities in more direct way #2482

This commit is contained in:
Alexey Milovidov 2018-08-22 02:52:03 +03:00
parent ea98d79e56
commit e0bf8c757b

View File

@ -6,6 +6,7 @@
#include <linux/genetlink.h>
#include <linux/netlink.h>
#include <linux/taskstats.h>
#include <linux/capability.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -242,17 +243,27 @@ int TaskStatsInfoGetter::getDefaultTID()
return default_tid;
}
static bool tryGetTaskStats()
static bool checkPermissionsImpl()
{
TaskStatsInfoGetter getter;
::taskstats stat;
return getter.tryGetStat(stat);
/// See man getcap.
__user_cap_header_struct request{};
request.version = _LINUX_CAPABILITY_VERSION_1; /// It's enough to check just single CAP_NET_ADMIN capability we are interested.
request.pid = getpid();
__user_cap_data_struct response{};
/// Avoid dependency on 'libcap'.
if (0 != syscall(SYS_capget, &request, &response))
throwFromErrno("Cannot do 'capget' syscall", ErrorCodes::NETLINK_ERROR);
return (1 << CAP_NET_ADMIN) & response.effective;
}
bool TaskStatsInfoGetter::checkPermissions()
{
/// It is thread- and exception- safe since C++11
static bool res = tryGetTaskStats();
static bool res = checkPermissionsImpl();
return res;
}