void krg_cap_finish_exec(struct linux_binprm *bprm) { /* The model needs changes with filesystem support ... */ #if 0 kernel_krg_cap_t *caps = ¤t->krg_caps; kernel_cap_t new_krg_permitted, new_krg_effective; /* added by David Margery (c) Inria 2004 */ /* Updated by Pascal Gallard (c) Inria 2005 */ task_lock(current); new_krg_permitted = cap_intersect(caps->inheritable_permitted, bprm->krg_cap_permitted); new_krg_permitted = cap_combine(new_krg_permitted, bprm->krg_cap_forced); new_krg_effective = cap_intersect(bprm->krg_cap_effective, new_krg_permitted); new_krg_effective = cap_intersect(caps->inheritable_effective, new_krg_effective); caps->permitted = new_krg_permitted; caps->effective = new_krg_effective; task_unlock(current); #endif /* 0 */ }
void krg_cap_fork(struct task_struct *task, unsigned long clone_flags) { kernel_krg_cap_t *caps = ¤t->krg_caps; kernel_krg_cap_t *new_caps = &task->krg_caps; kernel_cap_t new_krg_effective; int i; #ifdef CONFIG_KRG_EPM if (krg_current && !in_krg_do_fork()) /* Migration/restart: do not recompute krg caps */ return; #endif /* * Compute the new capabilities and reset the private * krg_cap_unavailable array */ new_krg_effective = cap_intersect(caps->inheritable_effective, caps->inheritable_permitted); new_caps->permitted = caps->inheritable_permitted; new_caps->effective = new_krg_effective; for (i = 0; i < CAP_SIZE; i++) atomic_set(&task->krg_cap_unavailable_private[i], 0); /* The other fields have been inherited by copy. */ }
void cap_bprm_compute_creds (struct linux_binprm *bprm) { /* Derived from fs/exec.c:compute_creds. */ kernel_cap_t new_permitted, working; int do_unlock = 0; new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); working = cap_intersect (bprm->cap_inheritable, current->cap_inheritable); new_permitted = cap_combine (new_permitted, working); if (!cap_issubset (new_permitted, current->cap_permitted)) { current->mm->dumpable = 0; lock_kernel (); if (must_not_trace_exec (current) || atomic_read (¤t->fs->count) > 1 || atomic_read (¤t->files->count) > 1 || atomic_read (¤t->sig->count) > 1) { if (!capable (CAP_SETPCAP)) { new_permitted = cap_intersect (new_permitted, current-> cap_permitted); } } do_unlock = 1; } /* For init, we want to retain the capabilities set * in the init_task struct. Thus we skip the usual * capability rules */ if (current->pid != 1) { current->cap_permitted = new_permitted; current->cap_effective = cap_intersect (new_permitted, bprm->cap_effective); } /* AUD: Audit candidate if current->cap_effective is set */ if (do_unlock) unlock_kernel (); current->keep_capabilities = 0; }
void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) { /* Derived from fs/exec.c:compute_creds. */ kernel_cap_t new_permitted, working; new_permitted = cap_intersect (bprm->cap_permitted, cap_bset); working = cap_intersect (bprm->cap_inheritable, current->cap_inheritable); new_permitted = cap_combine (new_permitted, working); if (bprm->e_uid != current->uid || bprm->e_gid != current->gid || !cap_issubset (new_permitted, current->cap_permitted)) { current->mm->dumpable = 0; if (unsafe & ~LSM_UNSAFE_PTRACE_CAP) { if (!capable(CAP_SETUID)) { bprm->e_uid = current->uid; bprm->e_gid = current->gid; } if (!capable (CAP_SETPCAP)) { new_permitted = cap_intersect (new_permitted, current->cap_permitted); } } } current->suid = current->euid = current->fsuid = bprm->e_uid; current->sgid = current->egid = current->fsgid = bprm->e_gid; /* For init, we want to retain the capabilities set * in the init_task struct. Thus we skip the usual * capability rules */ if (current->pid != 1) { current->cap_permitted = new_permitted; current->cap_effective = cap_intersect (new_permitted, bprm->cap_effective); } /* AUD: Audit candidate if current->cap_effective is set */ current->keep_capabilities = 0; }
static int krg_set_cap(struct task_struct *tsk, const kernel_krg_cap_t *requested_cap) { kernel_krg_cap_t *caps = &tsk->krg_caps; kernel_cap_t tmp_cap; struct nsproxy *nsp; int res; int i; res = 0; rcu_read_lock(); nsp = rcu_dereference(tsk->nsproxy); if (!nsp || !nsp->krg_ns) res = -EPERM; rcu_read_unlock(); if (res) goto out; res = -EINVAL; if (!cap_issubset(requested_cap->effective, requested_cap->permitted) || !cap_issubset(requested_cap->inheritable_permitted, requested_cap->permitted) || !cap_issubset(requested_cap->inheritable_effective, requested_cap->inheritable_permitted)) goto out; res = -ENOSYS; tmp_cap = KRG_CAP_SUPPORTED; if (!cap_issubset(requested_cap->permitted, tmp_cap)) goto out; res = -EPERM; if (!permissions_ok(tsk)) goto out; task_lock(tsk); if (!cap_raised(caps->effective, CAP_CHANGE_KERRIGHED_CAP)) goto out_unlock; res = -EBUSY; for (i = 0; i < CAP_SIZE; i++) if (atomic_read(&tsk->krg_cap_used[i]) && !cap_raised(requested_cap->effective, i)) goto out_unlock; tmp_cap = cap_intersect(caps->permitted, requested_cap->permitted); caps->permitted = tmp_cap; tmp_cap = cap_intersect(caps->permitted, requested_cap->effective); caps->effective = tmp_cap; tmp_cap = cap_intersect(caps->permitted, requested_cap->inheritable_effective); caps->inheritable_effective = tmp_cap; tmp_cap = cap_intersect(caps->permitted, requested_cap->inheritable_permitted); caps->inheritable_permitted = tmp_cap; res = 0; out_unlock: task_unlock(tsk); out: return res; }