forked from checkpoint-restore/criu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsecurity.c
74 lines (61 loc) · 1.81 KB
/
security.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <unistd.h>
#include "crtools.h"
#include "proc_parse.h"
#include "log.h"
#include "protobuf/creds.pb-c.h"
/*
* UID and GID of user requesting for C/R
*/
static unsigned int cr_uid, cr_gid;
/*
* 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).
*/
void restrict_uid(unsigned int uid, unsigned int gid)
{
pr_info("Restrict C/R with %u:%u uid\n", uid, gid);
cr_uid = uid;
cr_gid = gid;
}
static bool check_ids(unsigned int crid, unsigned int rid, unsigned int eid, unsigned int sid)
{
if (crid == 0)
return true;
if (crid == rid && crid == eid && crid == sid)
return true;
pr_err("UID/GID mismatch %u != (%u,%u,%u)\n", crid, rid, eid, sid);
return false;
}
static bool check_caps(u32 *inh, u32 *eff, u32 *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;
}
bool may_dump(struct proc_status_creds *creds)
{
return check_ids(cr_uid, creds->uids[0], creds->uids[1], creds->uids[2]) &&
check_ids(cr_gid, creds->gids[0], creds->gids[1], creds->gids[2]) &&
check_caps(creds->cap_inh, creds->cap_eff, creds->cap_prm);
}
bool may_restore(CredsEntry *creds)
{
return check_ids(cr_uid, creds->uid, creds->euid, creds->suid) &&
check_ids(cr_gid, creds->gid, creds->egid, creds->sgid) &&
check_caps(creds->cap_inh, creds->cap_eff, creds->cap_prm);
}