1 /* 2 * linux/kernel/capability.c 3 * 4 * Copyright (C) 1997 Andrew Main <zefram@fysh.org> 5 * 6 * Integrated into 2.1.97+, Andrew G. Morgan <morgan@transmeta.com> 7 * 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net> 8 */ 9 10 #include <linux/mm.h> 11 #include <linux/module.h> 12 #include <linux/security.h> 13 #include <linux/syscalls.h> 14 #include <asm/uaccess.h> 15 16 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ 17 kernel_cap_t cap_bset = CAP_INIT_EFF_SET; 18 19 EXPORT_SYMBOL(securebits); 20 EXPORT_SYMBOL(cap_bset); 21 22 /* 23 * This lock protects task->cap_* for all tasks including current. 24 * Locking rule: acquire this prior to tasklist_lock. 25 */ 26 static DEFINE_SPINLOCK(task_capability_lock); 27 28 /* 29 * For sys_getproccap() and sys_setproccap(), any of the three 30 * capability set pointers may be NULL -- indicating that that set is 31 * uninteresting and/or not to be changed. 32 */ 33 34 /** 35 * sys_capget - get the capabilities of a given process. 36 * @header: pointer to struct that contains capability version and 37 * target pid data 38 * @dataptr: pointer to struct that contains the effective, permitted, 39 * and inheritable capabilities that are returned 40 * 41 * Returns 0 on success and < 0 on error. 42 */ 43 asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) 44 { 45 int ret = 0; 46 pid_t pid; 47 __u32 version; 48 task_t *target; 49 struct __user_cap_data_struct data; 50 51 if (get_user(version, &header->version)) 52 return -EFAULT; 53 54 if (version != _LINUX_CAPABILITY_VERSION) { 55 if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) 56 return -EFAULT; 57 return -EINVAL; 58 } 59 60 if (get_user(pid, &header->pid)) 61 return -EFAULT; 62 63 if (pid < 0) 64 return -EINVAL; 65 66 spin_lock(&task_capability_lock); 67 read_lock(&tasklist_lock); 68 69 if (pid && pid != current->pid) { 70 target = find_task_by_pid(pid); 71 if (!target) { 72 ret = -ESRCH; 73 goto out; 74 } 75 } else 76 target = current; 77 78 ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted); 79 80 out: 81 read_unlock(&tasklist_lock); 82 spin_unlock(&task_capability_lock); 83 84 if (!ret && copy_to_user(dataptr, &data, sizeof data)) 85 return -EFAULT; 86 87 return ret; 88 } 89 90 /* 91 * cap_set_pg - set capabilities for all processes in a given process 92 * group. We call this holding task_capability_lock and tasklist_lock. 93 */ 94 static inline int cap_set_pg(int pgrp, kernel_cap_t *effective, 95 kernel_cap_t *inheritable, 96 kernel_cap_t *permitted) 97 { 98 task_t *g, *target; 99 int ret = -EPERM; 100 int found = 0; 101 102 do_each_task_pid(pgrp, PIDTYPE_PGID, g) { 103 target = g; 104 while_each_thread(g, target) { 105 if (!security_capset_check(target, effective, 106 inheritable, 107 permitted)) { 108 security_capset_set(target, effective, 109 inheritable, 110 permitted); 111 ret = 0; 112 } 113 found = 1; 114 } 115 } while_each_task_pid(pgrp, PIDTYPE_PGID, g); 116 117 if (!found) 118 ret = 0; 119 return ret; 120 } 121 122 /* 123 * cap_set_all - set capabilities for all processes other than init 124 * and self. We call this holding task_capability_lock and tasklist_lock. 125 */ 126 static inline int cap_set_all(kernel_cap_t *effective, 127 kernel_cap_t *inheritable, 128 kernel_cap_t *permitted) 129 { 130 task_t *g, *target; 131 int ret = -EPERM; 132 int found = 0; 133 134 do_each_thread(g, target) { 135 if (target == current || target->pid == 1) 136 continue; 137 found = 1; 138 if (security_capset_check(target, effective, inheritable, 139 permitted)) 140 continue; 141 ret = 0; 142 security_capset_set(target, effective, inheritable, permitted); 143 } while_each_thread(g, target); 144 145 if (!found) 146 ret = 0; 147 return ret; 148 } 149 150 /** 151 * sys_capset - set capabilities for a process or a group of processes 152 * @header: pointer to struct that contains capability version and 153 * target pid data 154 * @data: pointer to struct that contains the effective, permitted, 155 * and inheritable capabilities 156 * 157 * Set capabilities for a given process, all processes, or all 158 * processes in a given process group. 159 * 160 * The restrictions on setting capabilities are specified as: 161 * 162 * [pid is for the 'target' task. 'current' is the calling task.] 163 * 164 * I: any raised capabilities must be a subset of the (old current) permitted 165 * P: any raised capabilities must be a subset of the (old current) permitted 166 * E: must be set to a subset of (new target) permitted 167 * 168 * Returns 0 on success and < 0 on error. 169 */ 170 asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) 171 { 172 kernel_cap_t inheritable, permitted, effective; 173 __u32 version; 174 task_t *target; 175 int ret; 176 pid_t pid; 177 178 if (get_user(version, &header->version)) 179 return -EFAULT; 180 181 if (version != _LINUX_CAPABILITY_VERSION) { 182 if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) 183 return -EFAULT; 184 return -EINVAL; 185 } 186 187 if (get_user(pid, &header->pid)) 188 return -EFAULT; 189 190 if (pid && pid != current->pid && !capable(CAP_SETPCAP)) 191 return -EPERM; 192 193 if (copy_from_user(&effective, &data->effective, sizeof(effective)) || 194 copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) || 195 copy_from_user(&permitted, &data->permitted, sizeof(permitted))) 196 return -EFAULT; 197 198 spin_lock(&task_capability_lock); 199 read_lock(&tasklist_lock); 200 201 if (pid > 0 && pid != current->pid) { 202 target = find_task_by_pid(pid); 203 if (!target) { 204 ret = -ESRCH; 205 goto out; 206 } 207 } else 208 target = current; 209 210 ret = 0; 211 212 /* having verified that the proposed changes are legal, 213 we now put them into effect. */ 214 if (pid < 0) { 215 if (pid == -1) /* all procs other than current and init */ 216 ret = cap_set_all(&effective, &inheritable, &permitted); 217 218 else /* all procs in process group */ 219 ret = cap_set_pg(-pid, &effective, &inheritable, 220 &permitted); 221 } else { 222 ret = security_capset_check(target, &effective, &inheritable, 223 &permitted); 224 if (!ret) 225 security_capset_set(target, &effective, &inheritable, 226 &permitted); 227 } 228 229 out: 230 read_unlock(&tasklist_lock); 231 spin_unlock(&task_capability_lock); 232 233 return ret; 234 } 235