コード例 #1
0
ファイル: commoncap.c プロジェクト: BackupTheBerlios/tuxap
int cap_capset_check (struct task_struct *target, kernel_cap_t *effective,
		      kernel_cap_t *inheritable, kernel_cap_t *permitted)
{
	/* Derived from kernel/capability.c:sys_capset. */
	/* verify restrictions on target's new Inheritable set */
	if (!cap_issubset (*inheritable,
			   cap_combine (target->cap_inheritable,
					current->cap_permitted))) {
		return -EPERM;
	}

	/* verify restrictions on target's new Permitted set */
	if (!cap_issubset (*permitted,
			   cap_combine (target->cap_permitted,
					current->cap_permitted))) {
		return -EPERM;
	}

	/* verify the _new_Effective_ is a subset of the _new_Permitted_ */
	if (!cap_issubset (*effective, *permitted)) {
		return -EPERM;
	}

	return 0;
}
コード例 #2
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 */
}
コード例 #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
ファイル: commoncap.c プロジェクト: BackupTheBerlios/tuxap
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
 * @inheritable: A pointer to the proposed new inheritable capabilities set
 * @permitted: A pointer to the proposed new permitted capabilities set
 *
 * This function validates and applies a proposed mass change to the current
 * process's capability sets.  The changes are made to the proposed new
 * credentials, and assuming no error, will be committed by the caller of LSM.
 */
int cap_capset(struct cred *new,
	       const struct cred *old,
	       const kernel_cap_t *effective,
	       const kernel_cap_t *inheritable,
	       const kernel_cap_t *permitted)
{
	if (cap_inh_is_capped() &&
	    !cap_issubset(*inheritable,
			  cap_combine(old->cap_inheritable,
				      old->cap_permitted)))
		/* incapable of using this inheritable set */
		return -EPERM;

	if (!cap_issubset(*inheritable,
			  cap_combine(old->cap_inheritable,
				      old->cap_bset)))
		/* no new pI capabilities outside bounding set */
		return -EPERM;

	/* verify restrictions on target's new Permitted set */
	if (!cap_issubset(*permitted, old->cap_permitted))
		return -EPERM;

	/* verify the _new_Effective_ is a subset of the _new_Permitted_ */
	if (!cap_issubset(*effective, *permitted))
コード例 #6
0
asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
{
     kernel_cap_t inheritable, permitted, effective;
     __u32 version;
     struct task_struct *target;
     int error, pid;

     if (get_user(version, &header->version))
	     return -EFAULT; 

     if (version != _LINUX_CAPABILITY_VERSION) {
             version = _LINUX_CAPABILITY_VERSION;
	     if (put_user(version, &header->version))
		     return -EFAULT; 
             return -EINVAL;
     }

     if (get_user(pid, &header->pid))
	     return -EFAULT; 

     if (pid && !capable(CAP_SETPCAP))
             return -EPERM;

     if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
	 copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) ||
	 copy_from_user(&permitted, &data->permitted, sizeof(permitted)))
	     return -EFAULT; 

     error = -EPERM;
     spin_lock(&task_capability_lock);

     if (pid > 0 && pid != current->pid) {
             read_lock(&tasklist_lock);
             target = find_task_by_pid(pid);  /* identify target of query */
             if (!target) {
                     error = -ESRCH;
		     goto out;
	     }
     } else {
             target = current;
     }


     /* verify restrictions on target's new Inheritable set */
     if (!cap_issubset(inheritable,
                       cap_combine(target->cap_inheritable,
                                   current->cap_permitted))) {
             goto out;
     }

     /* verify restrictions on target's new Permitted set */
     if (!cap_issubset(permitted,
                       cap_combine(target->cap_permitted,
                                   current->cap_permitted))) {
             goto out;
     }

     /* verify the _new_Effective_ is a subset of the _new_Permitted_ */
     if (!cap_issubset(effective, permitted)) {
             goto out;
     }

     /* having verified that the proposed changes are legal,
           we now put them into effect. */
     error = 0;

     if (pid < 0) {
             if (pid == -1)  /* all procs other than current and init */
                     cap_set_all(&effective, &inheritable, &permitted);

             else            /* all procs in process group */
                     cap_set_pg(-pid, &effective, &inheritable, &permitted);
             goto spin_out;
     } else {
             /* FIXME: do we need to have a write lock here..? */
             target->cap_effective   = effective;
             target->cap_inheritable = inheritable;
             target->cap_permitted   = permitted;
     }

out:
     if (target != current) {
             read_unlock(&tasklist_lock);
     }
spin_out:
     spin_unlock(&task_capability_lock);
     return error;
}