Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cr: Task CapAmb support #2554

Open
wants to merge 1 commit into
base: criu-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions criu/cr-restore.c
Original file line number Diff line number Diff line change
Expand Up @@ -2992,13 +2992,15 @@ static struct thread_creds_args *rst_prep_creds_args(CredsEntry *ce, unsigned lo
args->creds.cap_eff = NULL;
args->creds.cap_prm = NULL;
args->creds.cap_bnd = NULL;
args->creds.cap_amb = NULL;
args->creds.groups = NULL;
args->creds.lsm_profile = NULL;

copy_caps(args->cap_inh, ce->cap_inh, ce->n_cap_inh);
copy_caps(args->cap_eff, ce->cap_eff, ce->n_cap_eff);
copy_caps(args->cap_prm, ce->cap_prm, ce->n_cap_prm);
copy_caps(args->cap_bnd, ce->cap_bnd, ce->n_cap_bnd);
copy_caps(args->cap_amb, ce->cap_amb, ce->n_cap_amb);

if (ce->n_groups && !groups_match(ce->groups, ce->n_groups)) {
unsigned int *groups;
Expand Down
1 change: 1 addition & 0 deletions criu/include/parasite.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ struct parasite_dump_creds {
u32 cap_prm[CR_CAP_SIZE];
u32 cap_eff[CR_CAP_SIZE];
u32 cap_bnd[CR_CAP_SIZE];
u32 cap_amb[CR_CAP_SIZE];

int uids[4];
int gids[4];
Expand Down
9 changes: 9 additions & 0 deletions criu/include/prctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,15 @@
#ifndef PR_SET_NO_NEW_PRIVS
#define PR_SET_NO_NEW_PRIVS 38
#endif
#ifndef PR_CAP_AMBIENT
#define PR_CAP_AMBIENT 47
#endif
#ifndef PR_CAP_AMBIENT_IS_SET
#define PR_CAP_AMBIENT_IS_SET 1
#endif
#ifndef PR_CAP_AMBIENT_RAISE
# define PR_CAP_AMBIENT_RAISE 2

Check warning on line 46 in criu/include/prctl.h

View workflow job for this annotation

GitHub Actions / build

#endif

#ifndef PR_SET_MM
#define PR_SET_MM 35
Expand Down
1 change: 1 addition & 0 deletions criu/include/proc_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ struct proc_status_creds {
u32 cap_prm[PROC_CAP_SIZE];
u32 cap_eff[PROC_CAP_SIZE];
u32 cap_bnd[PROC_CAP_SIZE];
u32 cap_amb[PROC_CAP_SIZE];
};

#define INVALID_UID ((uid_t)-1)
Expand Down
1 change: 1 addition & 0 deletions criu/include/restorer.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct thread_creds_args {
u32 cap_prm[CR_CAP_SIZE];
u32 cap_eff[CR_CAP_SIZE];
u32 cap_bnd[CR_CAP_SIZE];
u32 cap_amb[CR_CAP_SIZE];

char *lsm_profile;
unsigned int *groups;
Expand Down
3 changes: 3 additions & 0 deletions criu/parasite-syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,19 @@ static int alloc_groups_copy_creds(CredsEntry *ce, struct parasite_dump_creds *c
BUILD_BUG_ON(sizeof(ce->cap_prm[0]) != sizeof(c->cap_prm[0]));
BUILD_BUG_ON(sizeof(ce->cap_eff[0]) != sizeof(c->cap_eff[0]));
BUILD_BUG_ON(sizeof(ce->cap_bnd[0]) != sizeof(c->cap_bnd[0]));
BUILD_BUG_ON(sizeof(ce->cap_amb[0]) != sizeof(c->cap_amb[0]));

BUG_ON(ce->n_cap_inh != CR_CAP_SIZE);
BUG_ON(ce->n_cap_prm != CR_CAP_SIZE);
BUG_ON(ce->n_cap_eff != CR_CAP_SIZE);
BUG_ON(ce->n_cap_bnd != CR_CAP_SIZE);
BUG_ON(ce->n_cap_amb != CR_CAP_SIZE);

memcpy(ce->cap_inh, c->cap_inh, sizeof(c->cap_inh[0]) * CR_CAP_SIZE);
memcpy(ce->cap_prm, c->cap_prm, sizeof(c->cap_prm[0]) * CR_CAP_SIZE);
memcpy(ce->cap_eff, c->cap_eff, sizeof(c->cap_eff[0]) * CR_CAP_SIZE);
memcpy(ce->cap_bnd, c->cap_bnd, sizeof(c->cap_bnd[0]) * CR_CAP_SIZE);
memcpy(ce->cap_amb, c->cap_amb, sizeof(c->cap_amb[0]) * CR_CAP_SIZE);

if (c->no_new_privs > 0) {
ce->no_new_privs = c->no_new_privs;
Expand Down
13 changes: 13 additions & 0 deletions criu/pie/parasite.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ static int dump_creds(struct parasite_dump_creds *args)
args->cap_prm[i] = data[i].prm;
args->cap_inh[i] = data[i].inh;
args->cap_bnd[i] = 0;
args->cap_amb[i] = 0;

for (j = 0; j < 32; j++) {
if (j + i * 32 > args->cap_last_cap)
Expand All @@ -336,6 +337,18 @@ static int dump_creds(struct parasite_dump_creds *args)
if (ret)
args->cap_bnd[i] |= (1 << j);
}

for (j = 0; j < 32; j++) {
if (j + i * 32 > args->cap_last_cap)
break;
ret = sys_prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, j + i * 32, 0, 0);
if (ret < 0) {
pr_err("Unable to read ambient capability %d: %d\n", j + i * 32, ret);
return -1;
}
if (ret)
args->cap_amb[i] |= (1 << j);
}
}

args->no_new_privs = sys_prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);
Expand Down
15 changes: 15 additions & 0 deletions criu/pie/restorer.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,21 @@
return -1;
}

for (b = 0; b < CR_CAP_SIZE; b++) {
for (i = 0; i < 32; i++) {
if (b * 32 + i > args->cap_last_cap)
break;
if ((args->cap_amb[b] & (1 << i)) == 0)
/* don't set */
continue;
ret = sys_prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i + b * 32, 0, 0);
if (!ret)
continue;
pr_warn("Unable to raise ambient capability %d: %d\n", i + b * 32, ret);
}
}


Check warning on line 364 in criu/pie/restorer.c

View workflow job for this annotation

GitHub Actions / build

if (lsm_type != LSMTYPE__SELINUX) {
/*
* SELinux does not support setting the process context for
Expand Down
11 changes: 9 additions & 2 deletions criu/proc_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,7 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss, void *data)
if (bfdopenr(&f))
return -1;

while (done < 13) {
while (done < 14) {
str = breadline(&f);
if (str == NULL)
break;
Expand Down Expand Up @@ -1155,6 +1155,13 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss, void *data)
continue;
}

if (!strncmp(str, "CapAmb:", 7)) {
if (cap_parse(str + 8, cr->cap_amb))
goto err_parse;
done++;
continue;
}

if (!strncmp(str, "Seccomp:", 8)) {
if (sscanf(str + 9, "%d", &cr->s.seccomp_mode) != 1) {
goto err_parse;
Expand Down Expand Up @@ -1198,7 +1205,7 @@ int parse_pid_status(pid_t pid, struct seize_task_status *ss, void *data)
}

/* seccomp and nspids are optional */
expected_done = (parsed_seccomp ? 12 : 11);
expected_done = (parsed_seccomp ? 13 : 12);
if (kdat.has_nspid)
expected_done++;
if (done == expected_done)
Expand Down
3 changes: 3 additions & 0 deletions criu/pstree.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ CoreEntry *core_entry_alloc(int th, int tsk)
sz += CR_CAP_SIZE * sizeof(ce->cap_prm[0]);
sz += CR_CAP_SIZE * sizeof(ce->cap_eff[0]);
sz += CR_CAP_SIZE * sizeof(ce->cap_bnd[0]);
sz += CR_CAP_SIZE * sizeof(ce->cap_amb[0]);
/*
* @groups are dynamic and allocated
* on demand.
Expand Down Expand Up @@ -122,10 +123,12 @@ CoreEntry *core_entry_alloc(int th, int tsk)
ce->n_cap_prm = CR_CAP_SIZE;
ce->n_cap_eff = CR_CAP_SIZE;
ce->n_cap_bnd = CR_CAP_SIZE;
ce->n_cap_amb = CR_CAP_SIZE;
ce->cap_inh = xptr_pull_s(&m, CR_CAP_SIZE * sizeof(ce->cap_inh[0]));
ce->cap_prm = xptr_pull_s(&m, CR_CAP_SIZE * sizeof(ce->cap_prm[0]));
ce->cap_eff = xptr_pull_s(&m, CR_CAP_SIZE * sizeof(ce->cap_eff[0]));
ce->cap_bnd = xptr_pull_s(&m, CR_CAP_SIZE * sizeof(ce->cap_bnd[0]));
ce->cap_amb = xptr_pull_s(&m, CR_CAP_SIZE * sizeof(ce->cap_amb[0]));

if (arch_alloc_thread_info(core)) {
xfree(core);
Expand Down
2 changes: 2 additions & 0 deletions images/creds.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ message creds_entry {
optional string lsm_sockcreate = 16;
optional bytes apparmor_data = 17;
optional uint32 no_new_privs = 18;

repeated uint32 cap_amb = 19;
}
Loading