Пример #1
0
void krg_cap_finish_exec(struct linux_binprm *bprm)
{
	/* The model needs changes with filesystem support ... */
#if 0
	kernel_krg_cap_t *caps = &current->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 */
}
Пример #2
0
void krg_cap_fork(struct task_struct *task, unsigned long clone_flags)
{
	kernel_krg_cap_t *caps = &current->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. */
}
Пример #3
0
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 (&current->fs->count) > 1
		    || atomic_read (&current->files->count) > 1
		    || atomic_read (&current->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;
}
Пример #4
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;
}
Пример #5
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;
}