cr: Task CapAmb support

Signed-off-by: Liu Chao <liuchao173@huawei.com>
This commit is contained in:
Liu Chao 2024-12-19 08:16:36 +00:00 committed by Andrei Vagin
parent 94b9b3c5da
commit 6f8efad304
11 changed files with 60 additions and 2 deletions

View file

@ -2992,6 +2992,7 @@ 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;
@ -2999,6 +3000,7 @@ static struct thread_creds_args *rst_prep_creds_args(CredsEntry *ce, unsigned lo
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;

View file

@ -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];

View file

@ -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
#endif
#ifndef PR_SET_MM
#define PR_SET_MM 35

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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)
@ -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);

View file

@ -347,6 +347,22 @@ skip_xids:
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_err("Unable to raise ambient capability %d: %d\n", i + b * 32, ret);
return -1;
}
}
if (lsm_type != LSMTYPE__SELINUX) {
/*
* SELinux does not support setting the process context for

View file

@ -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;
@ -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;
@ -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)

View file

@ -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.
@ -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);

View file

@ -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;
}