Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
capability.c
Go to the documentation of this file.
1 /*
2  * linux/kernel/capability.c
3  *
4  * Copyright (C) 1997 Andrew Main <[email protected]>
5  *
6  * Integrated into 2.1.97+, Andrew G. Morgan <[email protected]>
7  * 30 May 2002: Cleanup, Robert M. Love <[email protected]>
8  */
9 
10 #include <linux/audit.h>
11 #include <linux/capability.h>
12 #include <linux/mm.h>
13 #include <linux/export.h>
14 #include <linux/security.h>
15 #include <linux/syscalls.h>
16 #include <linux/pid_namespace.h>
17 #include <linux/user_namespace.h>
18 #include <asm/uaccess.h>
19 
20 /*
21  * Leveraged for setting/resetting capabilities
22  */
23 
24 const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
25 
26 EXPORT_SYMBOL(__cap_empty_set);
27 
29 
30 static int __init file_caps_disable(char *str)
31 {
33  return 1;
34 }
35 __setup("no_file_caps", file_caps_disable);
36 
37 /*
38  * More recent versions of libcap are available from:
39  *
40  * http://www.kernel.org/pub/linux/libs/security/linux-privs/
41  */
42 
43 static void warn_legacy_capability_use(void)
44 {
45  static int warned;
46  if (!warned) {
47  char name[sizeof(current->comm)];
48 
49  printk(KERN_INFO "warning: `%s' uses 32-bit capabilities"
50  " (legacy support in use)\n",
52  warned = 1;
53  }
54 }
55 
56 /*
57  * Version 2 capabilities worked fine, but the linux/capability.h file
58  * that accompanied their introduction encouraged their use without
59  * the necessary user-space source code changes. As such, we have
60  * created a version 3 with equivalent functionality to version 2, but
61  * with a header change to protect legacy source code from using
62  * version 2 when it wanted to use version 1. If your system has code
63  * that trips the following warning, it is using version 2 specific
64  * capabilities and may be doing so insecurely.
65  *
66  * The remedy is to either upgrade your version of libcap (to 2.10+,
67  * if the application is linked against it), or recompile your
68  * application with modern kernel headers and this warning will go
69  * away.
70  */
71 
72 static void warn_deprecated_v2(void)
73 {
74  static int warned;
75 
76  if (!warned) {
77  char name[sizeof(current->comm)];
78 
79  printk(KERN_INFO "warning: `%s' uses deprecated v2"
80  " capabilities in a way that may be insecure.\n",
82  warned = 1;
83  }
84 }
85 
86 /*
87  * Version check. Return the number of u32s in each capability flag
88  * array, or a negative value on error.
89  */
90 static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy)
91 {
92  __u32 version;
93 
94  if (get_user(version, &header->version))
95  return -EFAULT;
96 
97  switch (version) {
99  warn_legacy_capability_use();
100  *tocopy = _LINUX_CAPABILITY_U32S_1;
101  break;
103  warn_deprecated_v2();
104  /*
105  * fall through - v3 is otherwise equivalent to v2.
106  */
108  *tocopy = _LINUX_CAPABILITY_U32S_3;
109  break;
110  default:
112  return -EFAULT;
113  return -EINVAL;
114  }
115 
116  return 0;
117 }
118 
119 /*
120  * The only thing that can change the capabilities of the current
121  * process is the current process. As such, we can't be in this code
122  * at the same time as we are in the process of setting capabilities
123  * in this process. The net result is that we can limit our use of
124  * locks to when we are reading the caps of another process.
125  */
126 static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp,
127  kernel_cap_t *pIp, kernel_cap_t *pPp)
128 {
129  int ret;
130 
131  if (pid && (pid != task_pid_vnr(current))) {
132  struct task_struct *target;
133 
134  rcu_read_lock();
135 
136  target = find_task_by_vpid(pid);
137  if (!target)
138  ret = -ESRCH;
139  else
140  ret = security_capget(target, pEp, pIp, pPp);
141 
142  rcu_read_unlock();
143  } else
144  ret = security_capget(current, pEp, pIp, pPp);
145 
146  return ret;
147 }
148 
159 {
160  int ret = 0;
161  pid_t pid;
162  unsigned tocopy;
163  kernel_cap_t pE, pI, pP;
164 
165  ret = cap_validate_magic(header, &tocopy);
166  if ((dataptr == NULL) || (ret != 0))
167  return ((dataptr == NULL) && (ret == -EINVAL)) ? 0 : ret;
168 
169  if (get_user(pid, &header->pid))
170  return -EFAULT;
171 
172  if (pid < 0)
173  return -EINVAL;
174 
175  ret = cap_get_target_pid(pid, &pE, &pI, &pP);
176  if (!ret) {
177  struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S];
178  unsigned i;
179 
180  for (i = 0; i < tocopy; i++) {
181  kdata[i].effective = pE.cap[i];
182  kdata[i].permitted = pP.cap[i];
183  kdata[i].inheritable = pI.cap[i];
184  }
185 
186  /*
187  * Note, in the case, tocopy < _KERNEL_CAPABILITY_U32S,
188  * we silently drop the upper capabilities here. This
189  * has the effect of making older libcap
190  * implementations implicitly drop upper capability
191  * bits when they perform a: capget/modify/capset
192  * sequence.
193  *
194  * This behavior is considered fail-safe
195  * behavior. Upgrading the application to a newer
196  * version of libcap will enable access to the newer
197  * capabilities.
198  *
199  * An alternative would be to return an error here
200  * (-ERANGE), but that causes legacy applications to
201  * unexpectidly fail; the capget/modify/capset aborts
202  * before modification is attempted and the application
203  * fails.
204  */
205  if (copy_to_user(dataptr, kdata, tocopy
206  * sizeof(struct __user_cap_data_struct))) {
207  return -EFAULT;
208  }
209  }
210 
211  return ret;
212 }
213 
233 {
234  struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S];
235  unsigned i, tocopy, copybytes;
237  struct cred *new;
238  int ret;
239  pid_t pid;
240 
241  ret = cap_validate_magic(header, &tocopy);
242  if (ret != 0)
243  return ret;
244 
245  if (get_user(pid, &header->pid))
246  return -EFAULT;
247 
248  /* may only affect current now */
249  if (pid != 0 && pid != task_pid_vnr(current))
250  return -EPERM;
251 
252  copybytes = tocopy * sizeof(struct __user_cap_data_struct);
253  if (copybytes > sizeof(kdata))
254  return -EFAULT;
255 
256  if (copy_from_user(&kdata, data, copybytes))
257  return -EFAULT;
258 
259  for (i = 0; i < tocopy; i++) {
260  effective.cap[i] = kdata[i].effective;
261  permitted.cap[i] = kdata[i].permitted;
262  inheritable.cap[i] = kdata[i].inheritable;
263  }
264  while (i < _KERNEL_CAPABILITY_U32S) {
265  effective.cap[i] = 0;
266  permitted.cap[i] = 0;
267  inheritable.cap[i] = 0;
268  i++;
269  }
270 
271  new = prepare_creds();
272  if (!new)
273  return -ENOMEM;
274 
275  ret = security_capset(new, current_cred(),
276  &effective, &inheritable, &permitted);
277  if (ret < 0)
278  goto error;
279 
280  audit_log_capset(pid, new, current_cred());
281 
282  return commit_creds(new);
283 
284 error:
285  abort_creds(new);
286  return ret;
287 }
288 
301  struct user_namespace *ns, int cap)
302 {
303  int ret;
304 
305  rcu_read_lock();
306  ret = security_capable(__task_cred(t), ns, cap);
307  rcu_read_unlock();
308 
309  return (ret == 0);
310 }
311 
322 bool has_capability(struct task_struct *t, int cap)
323 {
324  return has_ns_capability(t, &init_user_ns, cap);
325 }
326 
341  struct user_namespace *ns, int cap)
342 {
343  int ret;
344 
345  rcu_read_lock();
346  ret = security_capable_noaudit(__task_cred(t), ns, cap);
347  rcu_read_unlock();
348 
349  return (ret == 0);
350 }
351 
365 {
366  return has_ns_capability_noaudit(t, &init_user_ns, cap);
367 }
368 
380 bool ns_capable(struct user_namespace *ns, int cap)
381 {
382  if (unlikely(!cap_valid(cap))) {
383  printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap);
384  BUG();
385  }
386 
387  if (security_capable(current_cred(), ns, cap) == 0) {
388  current->flags |= PF_SUPERPRIV;
389  return true;
390  }
391  return false;
392 }
394 
405 bool capable(int cap)
406 {
407  return ns_capable(&init_user_ns, cap);
408 }
410 
419 {
420  return ns_capable(current_user_ns(), cap);
421 }
422 
437 bool inode_capable(const struct inode *inode, int cap)
438 {
439  struct user_namespace *ns = current_user_ns();
440 
441  return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
442 }