aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/capability.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/capability.c')
-rw-r--r--kernel/capability.c112
1 files changed, 103 insertions, 9 deletions
diff --git a/kernel/capability.c b/kernel/capability.c
index 2f05303715a5..283c529f8b1c 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -14,6 +14,7 @@
14#include <linux/security.h> 14#include <linux/security.h>
15#include <linux/syscalls.h> 15#include <linux/syscalls.h>
16#include <linux/pid_namespace.h> 16#include <linux/pid_namespace.h>
17#include <linux/user_namespace.h>
17#include <asm/uaccess.h> 18#include <asm/uaccess.h>
18 19
19/* 20/*
@@ -21,12 +22,8 @@
21 */ 22 */
22 23
23const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; 24const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
24const kernel_cap_t __cap_full_set = CAP_FULL_SET;
25const kernel_cap_t __cap_init_eff_set = CAP_INIT_EFF_SET;
26 25
27EXPORT_SYMBOL(__cap_empty_set); 26EXPORT_SYMBOL(__cap_empty_set);
28EXPORT_SYMBOL(__cap_full_set);
29EXPORT_SYMBOL(__cap_init_eff_set);
30 27
31int file_caps_enabled = 1; 28int file_caps_enabled = 1;
32 29
@@ -290,6 +287,60 @@ error:
290} 287}
291 288
292/** 289/**
290 * has_capability - Does a task have a capability in init_user_ns
291 * @t: The task in question
292 * @cap: The capability to be tested for
293 *
294 * Return true if the specified task has the given superior capability
295 * currently in effect to the initial user namespace, false if not.
296 *
297 * Note that this does not set PF_SUPERPRIV on the task.
298 */
299bool has_capability(struct task_struct *t, int cap)
300{
301 int ret = security_real_capable(t, &init_user_ns, cap);
302
303 return (ret == 0);
304}
305
306/**
307 * has_capability - Does a task have a capability in a specific user ns
308 * @t: The task in question
309 * @ns: target user namespace
310 * @cap: The capability to be tested for
311 *
312 * Return true if the specified task has the given superior capability
313 * currently in effect to the specified user namespace, false if not.
314 *
315 * Note that this does not set PF_SUPERPRIV on the task.
316 */
317bool has_ns_capability(struct task_struct *t,
318 struct user_namespace *ns, int cap)
319{
320 int ret = security_real_capable(t, ns, cap);
321
322 return (ret == 0);
323}
324
325/**
326 * has_capability_noaudit - Does a task have a capability (unaudited)
327 * @t: The task in question
328 * @cap: The capability to be tested for
329 *
330 * Return true if the specified task has the given superior capability
331 * currently in effect to init_user_ns, false if not. Don't write an
332 * audit message for the check.
333 *
334 * Note that this does not set PF_SUPERPRIV on the task.
335 */
336bool has_capability_noaudit(struct task_struct *t, int cap)
337{
338 int ret = security_real_capable_noaudit(t, &init_user_ns, cap);
339
340 return (ret == 0);
341}
342
343/**
293 * capable - Determine if the current task has a superior capability in effect 344 * capable - Determine if the current task has a superior capability in effect
294 * @cap: The capability to be tested for 345 * @cap: The capability to be tested for
295 * 346 *
@@ -299,17 +350,60 @@ error:
299 * This sets PF_SUPERPRIV on the task if the capability is available on the 350 * This sets PF_SUPERPRIV on the task if the capability is available on the
300 * assumption that it's about to be used. 351 * assumption that it's about to be used.
301 */ 352 */
302int capable(int cap) 353bool capable(int cap)
354{
355 return ns_capable(&init_user_ns, cap);
356}
357EXPORT_SYMBOL(capable);
358
359/**
360 * ns_capable - Determine if the current task has a superior capability in effect
361 * @ns: The usernamespace we want the capability in
362 * @cap: The capability to be tested for
363 *
364 * Return true if the current task has the given superior capability currently
365 * available for use, false if not.
366 *
367 * This sets PF_SUPERPRIV on the task if the capability is available on the
368 * assumption that it's about to be used.
369 */
370bool ns_capable(struct user_namespace *ns, int cap)
303{ 371{
304 if (unlikely(!cap_valid(cap))) { 372 if (unlikely(!cap_valid(cap))) {
305 printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap); 373 printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap);
306 BUG(); 374 BUG();
307 } 375 }
308 376
309 if (security_capable(cap) == 0) { 377 if (security_capable(ns, current_cred(), cap) == 0) {
310 current->flags |= PF_SUPERPRIV; 378 current->flags |= PF_SUPERPRIV;
311 return 1; 379 return true;
312 } 380 }
313 return 0; 381 return false;
382}
383EXPORT_SYMBOL(ns_capable);
384
385/**
386 * task_ns_capable - Determine whether current task has a superior
387 * capability targeted at a specific task's user namespace.
388 * @t: The task whose user namespace is targeted.
389 * @cap: The capability in question.
390 *
391 * Return true if it does, false otherwise.
392 */
393bool task_ns_capable(struct task_struct *t, int cap)
394{
395 return ns_capable(task_cred_xxx(t, user)->user_ns, cap);
396}
397EXPORT_SYMBOL(task_ns_capable);
398
399/**
400 * nsown_capable - Check superior capability to one's own user_ns
401 * @cap: The capability in question
402 *
403 * Return true if the current task has the given superior capability
404 * targeted at its own user namespace.
405 */
406bool nsown_capable(int cap)
407{
408 return ns_capable(current_user_ns(), cap);
314} 409}
315EXPORT_SYMBOL(capable);