2,497 bytes added
, 12:29, 6 August 2014
Due to restrictions imposed by several kernel APIs CRIU uses, the tools can only work with run with root privileges. However, if the node administrator sets the +suid bit on the criu binary, or runs criu as an [[RPC]] service, criu will be able to work on behalf of regular user.
In the latter case, the following security restrictions would apply:
<pre>
Legend:
cr_* -- ids of the calling user;
others -- ids of process that we're trying to dump/restore;
</pre>
* criu will refuse to '''dump/restore''' process if [se]?uid is not equal to cr_uid
* criu will refuse to '''dump/restore''' process if [se]?gid is not equal to cr_gid or cr_groups do not contain it
* criu will refuse to '''restore''' process if cr_groups don't contain groups
* criu will refuse to '''dump/restore''' any bits set in any capability set
== Code example ==
Here is a simplified version of code from security.c.
<source lang="c" style="font-size: 120%;">
bool check_uids()
{
if (cr_uid == 0)
return true;
if (cr_uid == ruid && cr_uid == suid && cr_uid == eid)
return true;
return false;
}
bool check_gids()
{
if (cr_gid == 0)
return true;
if ((contains(cr_groups, rgid) || cr_gid == rgid) &&
(contains(cr_groups, egid) || cr_gid == egid) &&
(contains(cr_groups, sgid) || cr_gid == sgid))
return true;
return false;
}
/*
* There is no need to check groups on dump, because if uids and gids match
* then groups will match too. Btw, getting groups on dump is problematic.
* We can't parse proc, as it contains only first 32 groups. And we can't use
* getgrouplist, as it reads /etc/group which depends on the namespace.
*
* On restore we're getting groups from imgs and can check if user didn't add
* wrong groups by modifying images.
*/
bool check_groups()
{
if (cr_gid == 0)
return true;
for (i = 0; i < ngroups; ++i) {
if (!contains(cr_groups, groups[i]))
return false;
}
return true;
}
bool check_caps()
{
/*
* Impose the most strict requirements for now.
* "Real" root user can use any caps, other users may
* use none. Later we will implement more sophisticated
* security model.
*/
if (cr_uid == 0 && cr_gid == 0)
return true;
for (i = 0; i < CR_CAP_SIZE; i++) {
if (inh[i] != 0 || eff[i] != 0 || prm[i] != 0)
return false;
}
return true;
}
bool may_dump()
{
return check_uids() &&
check_gids() &&
check_caps();
}
bool may_restore()
{
return check_uids() &&
check_gids() &&
check_groups() &&
check_caps();
}
</source>