Skip to content

Commit

Permalink
cr: Task CapAmb support
Browse files Browse the repository at this point in the history
Signed-off-by: Liu Chao <[email protected]>
  • Loading branch information
liuchao173 committed Dec 20, 2024
1 parent 32d5a76 commit f1520e3
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 1 deletion.
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 @@ static int restore_creds(struct thread_creds_args *args, int procfd, int lsm_typ
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
9 changes: 8 additions & 1 deletion criu/proc_parse.c
Original file line number Diff line number Diff line change
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;
}

0 comments on commit f1520e3

Please sign in to comment.