2013-09-28 06:16:17 +04:00
|
|
|
#include <unistd.h>
|
|
|
|
#include "crtools.h"
|
2013-09-28 15:48:44 +04:00
|
|
|
#include "proc_parse.h"
|
2013-09-28 06:16:17 +04:00
|
|
|
#include "log.h"
|
|
|
|
|
2013-11-05 12:32:56 +04:00
|
|
|
#include "protobuf/creds.pb-c.h"
|
|
|
|
|
2013-09-28 15:51:09 +04:00
|
|
|
/*
|
|
|
|
* UID and GID of user requesting for C/R
|
|
|
|
*/
|
|
|
|
static unsigned int cr_uid, cr_gid;
|
2013-09-28 06:16:17 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup what user is requesting for dump (via rpc or using
|
|
|
|
* suid bit on crtools). Later we would deny to dump/restore
|
|
|
|
* a task, to which the original user doesn't have the direct
|
|
|
|
* access to. (Or implement some trickier security policy).
|
|
|
|
*/
|
|
|
|
|
2013-09-28 15:51:09 +04:00
|
|
|
void restrict_uid(unsigned int uid, unsigned int gid)
|
2013-09-28 06:16:17 +04:00
|
|
|
{
|
2013-09-28 15:51:09 +04:00
|
|
|
pr_info("Restrict C/R with %u:%u uid\n", uid, gid);
|
2013-10-02 17:11:17 +04:00
|
|
|
cr_uid = uid;
|
2013-09-28 15:51:09 +04:00
|
|
|
cr_gid = gid;
|
2013-10-02 17:11:17 +04:00
|
|
|
}
|
|
|
|
|
2013-09-28 16:43:25 +04:00
|
|
|
static bool check_ids(unsigned int crid, unsigned int rid, unsigned int eid, unsigned int sid)
|
2013-10-02 17:11:17 +04:00
|
|
|
{
|
2013-09-28 16:43:25 +04:00
|
|
|
if (crid == 0)
|
2013-10-02 17:11:17 +04:00
|
|
|
return true;
|
2013-09-28 16:43:25 +04:00
|
|
|
if (crid == rid && crid == eid && crid == sid)
|
2013-10-02 17:11:17 +04:00
|
|
|
return true;
|
|
|
|
|
2013-09-28 16:43:25 +04:00
|
|
|
pr_err("UID/GID mismatch %u != (%u,%u,%u)\n", crid, rid, eid, sid);
|
2013-10-02 17:11:17 +04:00
|
|
|
return false;
|
2013-09-28 06:16:17 +04:00
|
|
|
}
|
|
|
|
|
2013-10-17 14:27:00 +04:00
|
|
|
static bool check_caps(uint32_t *inh, uint32_t *eff, uint32_t *prm)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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) {
|
|
|
|
pr_err("CAPs not allowed for non-root user\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-09-28 15:48:44 +04:00
|
|
|
bool may_dump(struct proc_status_creds *creds)
|
2013-09-28 06:16:17 +04:00
|
|
|
{
|
2013-09-28 16:43:25 +04:00
|
|
|
return check_ids(cr_uid, creds->uids[0], creds->uids[1], creds->uids[2]) &&
|
2013-10-17 14:27:00 +04:00
|
|
|
check_ids(cr_gid, creds->gids[0], creds->gids[1], creds->gids[2]) &&
|
|
|
|
check_caps(creds->cap_inh, creds->cap_eff, creds->cap_prm);
|
2013-10-02 17:11:17 +04:00
|
|
|
}
|
|
|
|
|
2013-09-28 15:48:44 +04:00
|
|
|
bool may_restore(CredsEntry *creds)
|
2013-10-02 17:11:17 +04:00
|
|
|
{
|
2013-09-28 16:43:25 +04:00
|
|
|
return check_ids(cr_uid, creds->uid, creds->euid, creds->suid) &&
|
2013-10-17 14:27:00 +04:00
|
|
|
check_ids(cr_gid, creds->gid, creds->egid, creds->sgid) &&
|
|
|
|
check_caps(creds->cap_inh, creds->cap_eff, creds->cap_prm);
|
2013-09-28 06:16:17 +04:00
|
|
|
}
|