/*
 * linux/kernel/capability.c
 *
 * Copyright (C) 1997  Andrew Main <zefram@fysh.org>
 *
 * Integrated into 2.1.97+,  Andrew G. Morgan <morgan@transmeta.com>
 * 30 May 2002:	Cleanup, Robert M. Love <rml@tech9.net>
 */ 

#include <linux/mm.h>
#include <linux/module.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <asm/uaccess.h>

unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
kernel_cap_t cap_bset = CAP_INIT_EFF_SET;

EXPORT_SYMBOL(securebits);
EXPORT_SYMBOL(cap_bset);

/*
 * This lock protects task->cap_* for all tasks including current.
 * Locking rule: acquire this prior to tasklist_lock.
 */
static DEFINE_SPINLOCK(task_capability_lock);

/*
 * For sys_getproccap() and sys_setproccap(), any of the three
 * capability set pointers may be NULL -- indicating that that set is
 * uninteresting and/or not to be changed.
 */

/*
 * sys_capget - get the capabilities of a given process.
 */
asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
{
     int ret = 0;
     pid_t pid;
     __u32 version;
     task_t *target;
     struct __user_cap_data_struct data;

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

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

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

     if (pid < 0) 
             return -EINVAL;

     spin_lock(&task_capability_lock);
     read_lock(&tasklist_lock); 

     if (pid && pid != current->pid) {
	     target = find_task_by_pid(pid);
	     if (!target) {
	          ret = -ESRCH;
	          goto out;
	     }
     } else
	     target = current;

     ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted);

out:
     read_unlock(&tasklist_lock); 
     spin_unlock(&task_capability_lock);

     if (!ret && copy_to_user(dataptr, &data, sizeof data))
          return -EFAULT; 

     return ret;
}

/*
 * cap_set_pg - set capabilities for all processes in a given process
 * group.  We call this holding task_capability_lock and tasklist_lock.
 */
static inline int cap_set_pg(int pgrp, kernel_cap_t *effective,
			      kernel_cap_t *inheritable,
			      kernel_cap_t *permitted)
{
	task_t *g, *target;
	int ret = -EPERM;
	int found = 0;

	do_each_task_pid(pgrp, PIDTYPE_PGID, g) {
		target = g;
		while_each_thread(g, target) {
			if (!security_capset_check(target, effective,
							inheritable,
							permitted)) {
				security_capset_set(target, effective,
							inheritable,
							permitted);
				ret = 0;
			}
			found = 1;
		}
	} while_each_task_pid(pgrp, PIDTYPE_PGID, g);

	if (!found)
	     ret = 0;
	return ret;
}

/*
 * cap_set_all - set capabilities for all processes other than init
 * and self.  We call this holding task_capability_lock and tasklist_lock.
 */
static inline int cap_set_all(kernel_cap_t *effective,
			       kernel_cap_t *inheritable,
			       kernel_cap_t *permitted)
{
     task_t *g, *target;
     int ret = -EPERM;
     int found = 0;

     do_each_thread(g, target) {
             if (target == current || target->pid == 1)
                     continue;
             found = 1;
	     if (security_capset_check(target, effective, inheritable,
						permitted))
		     continue;
	     ret = 0;
	     security_capset_set(target, effective, inheritable, permitted);
     } while_each_thread(g, target);

     if (!found)
	     ret = 0;
     return ret;
}

/*
 * sys_capset - set capabilities for a given process, all processes, or all
 * processes in a given process group.
 *
 * The restrictions on setting capabilities are specified as:
 *
 * [pid is for the 'target' task.  'current' is the calling task.]
 *
 * I: any raised capabilities must be a subset of the (old current) permitted
 * P: any raised capabilities must be a subset of the (old current) permitted
 * E: must be set to a subset of (new target) permitted
 */
asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
{
     kernel_cap_t inheritable, permitted, effective;
     __u32 version;
     task_t *target;
     int ret;
     pid_t pid;

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

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

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

     if (pid && pid != current->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; 

     spin_lock(&task_capability_lock);
     read_lock(&tasklist_lock);

     if (pid > 0 && pid != current->pid) {
          target = find_task_by_pid(pid);
          if (!target) {
               ret = -ESRCH;
               goto out;
          }
     } else
               target = current;

     ret = 0;

     /* having verified that the proposed changes are legal,
           we now put them into effect. */
     if (pid < 0) {
             if (pid == -1)  /* all procs other than current and init */
                     ret = cap_set_all(&effective, &inheritable, &permitted);

             else            /* all procs in process group */
                     ret = cap_set_pg(-pid, &effective, &inheritable,
		     					&permitted);
     } else {
	     ret = security_capset_check(target, &effective, &inheritable,
	     						&permitted);
	     if (!ret)
		     security_capset_set(target, &effective, &inheritable,
		     					&permitted);
     }

out:
     read_unlock(&tasklist_lock);
     spin_unlock(&task_capability_lock);

     return ret;
}
