capabilities: Ensure required capabilities are actually held by the process/user
This commit is contained in:
@@ -142,7 +142,12 @@ static bool nm_backend_init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* bypass file permissions to read from users ssh-agent */
|
/* bypass file permissions to read from users ssh-agent */
|
||||||
charon->caps->keep(charon->caps, CAP_DAC_OVERRIDE);
|
if (!charon->caps->keep(charon->caps, CAP_DAC_OVERRIDE))
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "NM backend requires CAP_DAC_OVERRIDE capability");
|
||||||
|
nm_backend_deinit();
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
lib->processor->queue_job(lib->processor,
|
lib->processor->queue_job(lib->processor,
|
||||||
(job_t*)callback_job_create_with_prio((callback_job_cb_t)run, this,
|
(job_t*)callback_job_create_with_prio((callback_job_cb_t)run, this,
|
||||||
|
|||||||
@@ -591,8 +591,6 @@ private_daemon_t *daemon_create(const char *name)
|
|||||||
this->public.shunts = shunt_manager_create();
|
this->public.shunts = shunt_manager_create();
|
||||||
this->kernel_handler = kernel_handler_create();
|
this->kernel_handler = kernel_handler_create();
|
||||||
|
|
||||||
this->public.caps->keep(this->public.caps, CAP_NET_ADMIN);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,6 +626,12 @@ bool libcharon_init(const char *name)
|
|||||||
|
|
||||||
this = daemon_create(name);
|
this = daemon_create(name);
|
||||||
|
|
||||||
|
if (!this->public.caps->keep(this->public.caps, CAP_NET_ADMIN))
|
||||||
|
{
|
||||||
|
dbg(DBG_DMN, 1, "libcharon requires CAP_NET_ADMIN capability");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* for uncritical pseudo random numbers */
|
/* for uncritical pseudo random numbers */
|
||||||
srandom(time(NULL) + getpid());
|
srandom(time(NULL) + getpid());
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,13 @@ plugin_t *xauth_pam_plugin_create()
|
|||||||
{
|
{
|
||||||
xauth_pam_plugin_t *this;
|
xauth_pam_plugin_t *this;
|
||||||
|
|
||||||
|
/* required for PAM authentication */
|
||||||
|
if (!charon->caps->keep(charon->caps, CAP_AUDIT_WRITE))
|
||||||
|
{
|
||||||
|
DBG1(DBG_DMN, "xauth-pam plugin requires CAP_AUDIT_WRITE capability");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.plugin = {
|
.plugin = {
|
||||||
.get_name = _get_name,
|
.get_name = _get_name,
|
||||||
@@ -60,8 +67,5 @@ plugin_t *xauth_pam_plugin_create()
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/* required for PAM authentication */
|
|
||||||
charon->caps->keep(charon->caps, CAP_AUDIT_WRITE);
|
|
||||||
|
|
||||||
return &this->plugin;
|
return &this->plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 Tobias Brunner
|
* Copyright (C) 2012-2013 Tobias Brunner
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
* Copyright (C) 2012 Martin Willi
|
* Copyright (C) 2012 Martin Willi
|
||||||
* Copyright (C) 2012 revosec AG
|
* Copyright (C) 2012 revosec AG
|
||||||
@@ -76,9 +76,57 @@ struct private_capabilities_t {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(capabilities_t, keep, void,
|
static bool has_capability(u_int cap)
|
||||||
|
{
|
||||||
|
#ifndef CAPABILITIES
|
||||||
|
/* if we can't check the actual capabilities assume only root has it */
|
||||||
|
return getuid() == 0;
|
||||||
|
#endif /* !CAPABILITIES */
|
||||||
|
#ifdef CAPABILITIES_LIBCAP
|
||||||
|
cap_flag_value_t val;
|
||||||
|
cap_t caps;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
caps = cap_get_proc();
|
||||||
|
if (!caps)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ok = cap_get_flag(caps, cap, CAP_PERMITTED, &val) == 0 && val == CAP_SET;
|
||||||
|
cap_free(caps);
|
||||||
|
return ok;
|
||||||
|
#endif /* CAPABILITIES_LIBCAP */
|
||||||
|
#ifdef CAPABILITIES_NATIVE
|
||||||
|
struct __user_cap_header_struct header = {
|
||||||
|
#if defined(_LINUX_CAPABILITY_VERSION_3)
|
||||||
|
.version = _LINUX_CAPABILITY_VERSION_3,
|
||||||
|
#elif defined(_LINUX_CAPABILITY_VERSION_2)
|
||||||
|
.version = _LINUX_CAPABILITY_VERSION_2,
|
||||||
|
#elif defined(_LINUX_CAPABILITY_VERSION_1)
|
||||||
|
.version = _LINUX_CAPABILITY_VERSION_1,
|
||||||
|
#else
|
||||||
|
.version = _LINUX_CAPABILITY_VERSION,
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
struct __user_cap_data_struct caps[2];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if (cap >= 32)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
cap -= 32;
|
||||||
|
}
|
||||||
|
return capget(&header, caps) == 0 && caps[i].permitted & (1 << cap);
|
||||||
|
#endif /* CAPABILITIES_NATIVE */
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(capabilities_t, keep, bool,
|
||||||
private_capabilities_t *this, u_int cap)
|
private_capabilities_t *this, u_int cap)
|
||||||
{
|
{
|
||||||
|
if (!has_capability(cap))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
#ifdef CAPABILITIES_LIBCAP
|
#ifdef CAPABILITIES_LIBCAP
|
||||||
cap_set_flag(this->caps, CAP_EFFECTIVE, 1, &cap, CAP_SET);
|
cap_set_flag(this->caps, CAP_EFFECTIVE, 1, &cap, CAP_SET);
|
||||||
cap_set_flag(this->caps, CAP_INHERITABLE, 1, &cap, CAP_SET);
|
cap_set_flag(this->caps, CAP_INHERITABLE, 1, &cap, CAP_SET);
|
||||||
@@ -96,6 +144,7 @@ METHOD(capabilities_t, keep, void,
|
|||||||
this->caps[i].permitted |= 1 << cap;
|
this->caps[i].permitted |= 1 << cap;
|
||||||
this->caps[i].inheritable |= 1 << cap;
|
this->caps[i].inheritable |= 1 << cap;
|
||||||
#endif /* CAPABILITIES_NATIVE */
|
#endif /* CAPABILITIES_NATIVE */
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(capabilities_t, get_uid, uid_t,
|
METHOD(capabilities_t, get_uid, uid_t,
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2013 Tobias Brunner
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
* Copyright (C) 2012 Martin Willi
|
* Copyright (C) 2012 Martin Willi
|
||||||
* Copyright (C) 2012 revosec AG
|
* Copyright (C) 2012 revosec AG
|
||||||
*
|
*
|
||||||
@@ -36,11 +38,14 @@ typedef struct capabilities_t capabilities_t;
|
|||||||
struct capabilities_t {
|
struct capabilities_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a capability to keep while calling drop().
|
* Register a capability to keep while calling drop(). Verifies that the
|
||||||
|
* capability is currently held.
|
||||||
*
|
*
|
||||||
* @param cap capability to keep
|
* @param cap capability to keep
|
||||||
|
* @return FALSE if the capability is currently not held
|
||||||
*/
|
*/
|
||||||
void (*keep)(capabilities_t *this, u_int cap);
|
bool (*keep)(capabilities_t *this,
|
||||||
|
u_int cap) __attribute__((warn_unused_result));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the user ID set through set_uid/resolve_uid.
|
* Get the user ID set through set_uid/resolve_uid.
|
||||||
|
|||||||
Reference in New Issue
Block a user