11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/kernel/capability.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1997 Andrew Main <zefram@fysh.org> 51da177e4SLinus Torvalds * 672c2d582SAndrew Morgan * Integrated into 2.1.97+, Andrew G. Morgan <morgan@kernel.org> 71da177e4SLinus Torvalds * 30 May 2002: Cleanup, Robert M. Love <rml@tech9.net> 81da177e4SLinus Torvalds */ 91da177e4SLinus Torvalds 10e68b75a0SEric Paris #include <linux/audit.h> 11c59ede7bSRandy.Dunlap #include <linux/capability.h> 121da177e4SLinus Torvalds #include <linux/mm.h> 139984de1aSPaul Gortmaker #include <linux/export.h> 141da177e4SLinus Torvalds #include <linux/security.h> 151da177e4SLinus Torvalds #include <linux/syscalls.h> 16b460cbc5SSerge E. Hallyn #include <linux/pid_namespace.h> 173486740aSSerge E. Hallyn #include <linux/user_namespace.h> 181da177e4SLinus Torvalds #include <asm/uaccess.h> 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds /* 21e338d263SAndrew Morgan * Leveraged for setting/resetting capabilities 22e338d263SAndrew Morgan */ 23e338d263SAndrew Morgan 24e338d263SAndrew Morgan const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; 25e338d263SAndrew Morgan 26e338d263SAndrew Morgan EXPORT_SYMBOL(__cap_empty_set); 27e338d263SAndrew Morgan 281f29fae2SSerge E. Hallyn int file_caps_enabled = 1; 291f29fae2SSerge E. Hallyn 301f29fae2SSerge E. Hallyn static int __init file_caps_disable(char *str) 311f29fae2SSerge E. Hallyn { 321f29fae2SSerge E. Hallyn file_caps_enabled = 0; 331f29fae2SSerge E. Hallyn return 1; 341f29fae2SSerge E. Hallyn } 351f29fae2SSerge E. Hallyn __setup("no_file_caps", file_caps_disable); 361f29fae2SSerge E. Hallyn 37e338d263SAndrew Morgan /* 38e338d263SAndrew Morgan * More recent versions of libcap are available from: 39e338d263SAndrew Morgan * 40e338d263SAndrew Morgan * http://www.kernel.org/pub/linux/libs/security/linux-privs/ 41e338d263SAndrew Morgan */ 42e338d263SAndrew Morgan 43e338d263SAndrew Morgan static void warn_legacy_capability_use(void) 44e338d263SAndrew Morgan { 45e338d263SAndrew Morgan static int warned; 46e338d263SAndrew Morgan if (!warned) { 47e338d263SAndrew Morgan char name[sizeof(current->comm)]; 48e338d263SAndrew Morgan 49e338d263SAndrew Morgan printk(KERN_INFO "warning: `%s' uses 32-bit capabilities" 50e338d263SAndrew Morgan " (legacy support in use)\n", 51e338d263SAndrew Morgan get_task_comm(name, current)); 52e338d263SAndrew Morgan warned = 1; 53e338d263SAndrew Morgan } 54e338d263SAndrew Morgan } 55e338d263SAndrew Morgan 56e338d263SAndrew Morgan /* 57ca05a99aSAndrew G. Morgan * Version 2 capabilities worked fine, but the linux/capability.h file 58ca05a99aSAndrew G. Morgan * that accompanied their introduction encouraged their use without 59ca05a99aSAndrew G. Morgan * the necessary user-space source code changes. As such, we have 60ca05a99aSAndrew G. Morgan * created a version 3 with equivalent functionality to version 2, but 61ca05a99aSAndrew G. Morgan * with a header change to protect legacy source code from using 62ca05a99aSAndrew G. Morgan * version 2 when it wanted to use version 1. If your system has code 63ca05a99aSAndrew G. Morgan * that trips the following warning, it is using version 2 specific 64ca05a99aSAndrew G. Morgan * capabilities and may be doing so insecurely. 65ca05a99aSAndrew G. Morgan * 66ca05a99aSAndrew G. Morgan * The remedy is to either upgrade your version of libcap (to 2.10+, 67ca05a99aSAndrew G. Morgan * if the application is linked against it), or recompile your 68ca05a99aSAndrew G. Morgan * application with modern kernel headers and this warning will go 69ca05a99aSAndrew G. Morgan * away. 70ca05a99aSAndrew G. Morgan */ 71ca05a99aSAndrew G. Morgan 72ca05a99aSAndrew G. Morgan static void warn_deprecated_v2(void) 73ca05a99aSAndrew G. Morgan { 74ca05a99aSAndrew G. Morgan static int warned; 75ca05a99aSAndrew G. Morgan 76ca05a99aSAndrew G. Morgan if (!warned) { 77ca05a99aSAndrew G. Morgan char name[sizeof(current->comm)]; 78ca05a99aSAndrew G. Morgan 79ca05a99aSAndrew G. Morgan printk(KERN_INFO "warning: `%s' uses deprecated v2" 80ca05a99aSAndrew G. Morgan " capabilities in a way that may be insecure.\n", 81ca05a99aSAndrew G. Morgan get_task_comm(name, current)); 82ca05a99aSAndrew G. Morgan warned = 1; 83ca05a99aSAndrew G. Morgan } 84ca05a99aSAndrew G. Morgan } 85ca05a99aSAndrew G. Morgan 86ca05a99aSAndrew G. Morgan /* 87ca05a99aSAndrew G. Morgan * Version check. Return the number of u32s in each capability flag 88ca05a99aSAndrew G. Morgan * array, or a negative value on error. 89ca05a99aSAndrew G. Morgan */ 90ca05a99aSAndrew G. Morgan static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy) 91ca05a99aSAndrew G. Morgan { 92ca05a99aSAndrew G. Morgan __u32 version; 93ca05a99aSAndrew G. Morgan 94ca05a99aSAndrew G. Morgan if (get_user(version, &header->version)) 95ca05a99aSAndrew G. Morgan return -EFAULT; 96ca05a99aSAndrew G. Morgan 97ca05a99aSAndrew G. Morgan switch (version) { 98ca05a99aSAndrew G. Morgan case _LINUX_CAPABILITY_VERSION_1: 99ca05a99aSAndrew G. Morgan warn_legacy_capability_use(); 100ca05a99aSAndrew G. Morgan *tocopy = _LINUX_CAPABILITY_U32S_1; 101ca05a99aSAndrew G. Morgan break; 102ca05a99aSAndrew G. Morgan case _LINUX_CAPABILITY_VERSION_2: 103ca05a99aSAndrew G. Morgan warn_deprecated_v2(); 104ca05a99aSAndrew G. Morgan /* 105ca05a99aSAndrew G. Morgan * fall through - v3 is otherwise equivalent to v2. 106ca05a99aSAndrew G. Morgan */ 107ca05a99aSAndrew G. Morgan case _LINUX_CAPABILITY_VERSION_3: 108ca05a99aSAndrew G. Morgan *tocopy = _LINUX_CAPABILITY_U32S_3; 109ca05a99aSAndrew G. Morgan break; 110ca05a99aSAndrew G. Morgan default: 111ca05a99aSAndrew G. Morgan if (put_user((u32)_KERNEL_CAPABILITY_VERSION, &header->version)) 112ca05a99aSAndrew G. Morgan return -EFAULT; 113ca05a99aSAndrew G. Morgan return -EINVAL; 114ca05a99aSAndrew G. Morgan } 115ca05a99aSAndrew G. Morgan 116ca05a99aSAndrew G. Morgan return 0; 117ca05a99aSAndrew G. Morgan } 118ca05a99aSAndrew G. Morgan 119ab763c71SAndrew G. Morgan /* 120d84f4f99SDavid Howells * The only thing that can change the capabilities of the current 121d84f4f99SDavid Howells * process is the current process. As such, we can't be in this code 122d84f4f99SDavid Howells * at the same time as we are in the process of setting capabilities 123d84f4f99SDavid Howells * in this process. The net result is that we can limit our use of 124d84f4f99SDavid Howells * locks to when we are reading the caps of another process. 125ab763c71SAndrew G. Morgan */ 126ab763c71SAndrew G. Morgan static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp, 127ab763c71SAndrew G. Morgan kernel_cap_t *pIp, kernel_cap_t *pPp) 128ab763c71SAndrew G. Morgan { 129ab763c71SAndrew G. Morgan int ret; 130ab763c71SAndrew G. Morgan 131ab763c71SAndrew G. Morgan if (pid && (pid != task_pid_vnr(current))) { 132ab763c71SAndrew G. Morgan struct task_struct *target; 133ab763c71SAndrew G. Morgan 13486fc80f1SThomas Gleixner rcu_read_lock(); 135ab763c71SAndrew G. Morgan 136ab763c71SAndrew G. Morgan target = find_task_by_vpid(pid); 137ab763c71SAndrew G. Morgan if (!target) 138ab763c71SAndrew G. Morgan ret = -ESRCH; 139ab763c71SAndrew G. Morgan else 140ab763c71SAndrew G. Morgan ret = security_capget(target, pEp, pIp, pPp); 141ab763c71SAndrew G. Morgan 14286fc80f1SThomas Gleixner rcu_read_unlock(); 143ab763c71SAndrew G. Morgan } else 144ab763c71SAndrew G. Morgan ret = security_capget(current, pEp, pIp, pPp); 145ab763c71SAndrew G. Morgan 146ab763c71SAndrew G. Morgan return ret; 147ab763c71SAndrew G. Morgan } 148ab763c71SAndrew G. Morgan 149207a7ba8SRandy Dunlap /** 1501da177e4SLinus Torvalds * sys_capget - get the capabilities of a given process. 151207a7ba8SRandy Dunlap * @header: pointer to struct that contains capability version and 152207a7ba8SRandy Dunlap * target pid data 153207a7ba8SRandy Dunlap * @dataptr: pointer to struct that contains the effective, permitted, 154207a7ba8SRandy Dunlap * and inheritable capabilities that are returned 155207a7ba8SRandy Dunlap * 156207a7ba8SRandy Dunlap * Returns 0 on success and < 0 on error. 1571da177e4SLinus Torvalds */ 158b290ebe2SHeiko Carstens SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) 1591da177e4SLinus Torvalds { 1601da177e4SLinus Torvalds int ret = 0; 1611da177e4SLinus Torvalds pid_t pid; 162e338d263SAndrew Morgan unsigned tocopy; 163e338d263SAndrew Morgan kernel_cap_t pE, pI, pP; 1641da177e4SLinus Torvalds 165ca05a99aSAndrew G. Morgan ret = cap_validate_magic(header, &tocopy); 166c4a5af54SAndrew G. Morgan if ((dataptr == NULL) || (ret != 0)) 167c4a5af54SAndrew G. Morgan return ((dataptr == NULL) && (ret == -EINVAL)) ? 0 : ret; 1681da177e4SLinus Torvalds 1691da177e4SLinus Torvalds if (get_user(pid, &header->pid)) 1701da177e4SLinus Torvalds return -EFAULT; 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds if (pid < 0) 1731da177e4SLinus Torvalds return -EINVAL; 1741da177e4SLinus Torvalds 175ab763c71SAndrew G. Morgan ret = cap_get_target_pid(pid, &pE, &pI, &pP); 176e338d263SAndrew Morgan if (!ret) { 177ca05a99aSAndrew G. Morgan struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; 178e338d263SAndrew Morgan unsigned i; 179e338d263SAndrew Morgan 180e338d263SAndrew Morgan for (i = 0; i < tocopy; i++) { 181e338d263SAndrew Morgan kdata[i].effective = pE.cap[i]; 182e338d263SAndrew Morgan kdata[i].permitted = pP.cap[i]; 183e338d263SAndrew Morgan kdata[i].inheritable = pI.cap[i]; 184e338d263SAndrew Morgan } 185e338d263SAndrew Morgan 186e338d263SAndrew Morgan /* 187ca05a99aSAndrew G. Morgan * Note, in the case, tocopy < _KERNEL_CAPABILITY_U32S, 188e338d263SAndrew Morgan * we silently drop the upper capabilities here. This 189e338d263SAndrew Morgan * has the effect of making older libcap 190e338d263SAndrew Morgan * implementations implicitly drop upper capability 191e338d263SAndrew Morgan * bits when they perform a: capget/modify/capset 192e338d263SAndrew Morgan * sequence. 193e338d263SAndrew Morgan * 194e338d263SAndrew Morgan * This behavior is considered fail-safe 195e338d263SAndrew Morgan * behavior. Upgrading the application to a newer 196e338d263SAndrew Morgan * version of libcap will enable access to the newer 197e338d263SAndrew Morgan * capabilities. 198e338d263SAndrew Morgan * 199e338d263SAndrew Morgan * An alternative would be to return an error here 200e338d263SAndrew Morgan * (-ERANGE), but that causes legacy applications to 201e338d263SAndrew Morgan * unexpectidly fail; the capget/modify/capset aborts 202e338d263SAndrew Morgan * before modification is attempted and the application 203e338d263SAndrew Morgan * fails. 204e338d263SAndrew Morgan */ 205e338d263SAndrew Morgan if (copy_to_user(dataptr, kdata, tocopy 206e338d263SAndrew Morgan * sizeof(struct __user_cap_data_struct))) { 2071da177e4SLinus Torvalds return -EFAULT; 208e338d263SAndrew Morgan } 209e338d263SAndrew Morgan } 2101da177e4SLinus Torvalds 2111da177e4SLinus Torvalds return ret; 2121da177e4SLinus Torvalds } 2131da177e4SLinus Torvalds 214207a7ba8SRandy Dunlap /** 215ab763c71SAndrew G. Morgan * sys_capset - set capabilities for a process or (*) a group of processes 216207a7ba8SRandy Dunlap * @header: pointer to struct that contains capability version and 217207a7ba8SRandy Dunlap * target pid data 218207a7ba8SRandy Dunlap * @data: pointer to struct that contains the effective, permitted, 219207a7ba8SRandy Dunlap * and inheritable capabilities 220207a7ba8SRandy Dunlap * 2211cdcbec1SDavid Howells * Set capabilities for the current process only. The ability to any other 2221cdcbec1SDavid Howells * process(es) has been deprecated and removed. 2231da177e4SLinus Torvalds * 2241da177e4SLinus Torvalds * The restrictions on setting capabilities are specified as: 2251da177e4SLinus Torvalds * 2261cdcbec1SDavid Howells * I: any raised capabilities must be a subset of the old permitted 2271cdcbec1SDavid Howells * P: any raised capabilities must be a subset of the old permitted 2281cdcbec1SDavid Howells * E: must be set to a subset of new permitted 229207a7ba8SRandy Dunlap * 230207a7ba8SRandy Dunlap * Returns 0 on success and < 0 on error. 2311da177e4SLinus Torvalds */ 232b290ebe2SHeiko Carstens SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) 2331da177e4SLinus Torvalds { 234ca05a99aSAndrew G. Morgan struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; 235825332e4SArjan van de Ven unsigned i, tocopy, copybytes; 2361da177e4SLinus Torvalds kernel_cap_t inheritable, permitted, effective; 237d84f4f99SDavid Howells struct cred *new; 2381da177e4SLinus Torvalds int ret; 2391da177e4SLinus Torvalds pid_t pid; 2401da177e4SLinus Torvalds 241ca05a99aSAndrew G. Morgan ret = cap_validate_magic(header, &tocopy); 242ca05a99aSAndrew G. Morgan if (ret != 0) 243ca05a99aSAndrew G. Morgan return ret; 2441da177e4SLinus Torvalds 2451da177e4SLinus Torvalds if (get_user(pid, &header->pid)) 2461da177e4SLinus Torvalds return -EFAULT; 2471da177e4SLinus Torvalds 2481cdcbec1SDavid Howells /* may only affect current now */ 2491cdcbec1SDavid Howells if (pid != 0 && pid != task_pid_vnr(current)) 2501cdcbec1SDavid Howells return -EPERM; 2511cdcbec1SDavid Howells 252825332e4SArjan van de Ven copybytes = tocopy * sizeof(struct __user_cap_data_struct); 253825332e4SArjan van de Ven if (copybytes > sizeof(kdata)) 254825332e4SArjan van de Ven return -EFAULT; 255825332e4SArjan van de Ven 256825332e4SArjan van de Ven if (copy_from_user(&kdata, data, copybytes)) 2571da177e4SLinus Torvalds return -EFAULT; 258e338d263SAndrew Morgan 259e338d263SAndrew Morgan for (i = 0; i < tocopy; i++) { 260e338d263SAndrew Morgan effective.cap[i] = kdata[i].effective; 261e338d263SAndrew Morgan permitted.cap[i] = kdata[i].permitted; 262e338d263SAndrew Morgan inheritable.cap[i] = kdata[i].inheritable; 263e338d263SAndrew Morgan } 264ca05a99aSAndrew G. Morgan while (i < _KERNEL_CAPABILITY_U32S) { 265e338d263SAndrew Morgan effective.cap[i] = 0; 266e338d263SAndrew Morgan permitted.cap[i] = 0; 267e338d263SAndrew Morgan inheritable.cap[i] = 0; 268e338d263SAndrew Morgan i++; 269e338d263SAndrew Morgan } 2701da177e4SLinus Torvalds 271d84f4f99SDavid Howells new = prepare_creds(); 272d84f4f99SDavid Howells if (!new) 273d84f4f99SDavid Howells return -ENOMEM; 274d84f4f99SDavid Howells 275d84f4f99SDavid Howells ret = security_capset(new, current_cred(), 276d84f4f99SDavid Howells &effective, &inheritable, &permitted); 277d84f4f99SDavid Howells if (ret < 0) 278d84f4f99SDavid Howells goto error; 279d84f4f99SDavid Howells 28057f71a0aSAl Viro audit_log_capset(pid, new, current_cred()); 281e68b75a0SEric Paris 282d84f4f99SDavid Howells return commit_creds(new); 2831da177e4SLinus Torvalds 284d84f4f99SDavid Howells error: 285d84f4f99SDavid Howells abort_creds(new); 2861da177e4SLinus Torvalds return ret; 2871da177e4SLinus Torvalds } 28812b5989bSChris Wright 2895cd9c58fSDavid Howells /** 29025e75703SEric Paris * has_ns_capability - Does a task have a capability in a specific user ns 2913263245dSSerge E. Hallyn * @t: The task in question 2923263245dSSerge E. Hallyn * @ns: target user namespace 2933263245dSSerge E. Hallyn * @cap: The capability to be tested for 2943263245dSSerge E. Hallyn * 2953263245dSSerge E. Hallyn * Return true if the specified task has the given superior capability 2963263245dSSerge E. Hallyn * currently in effect to the specified user namespace, false if not. 2973263245dSSerge E. Hallyn * 2983263245dSSerge E. Hallyn * Note that this does not set PF_SUPERPRIV on the task. 2993263245dSSerge E. Hallyn */ 3003263245dSSerge E. Hallyn bool has_ns_capability(struct task_struct *t, 3013263245dSSerge E. Hallyn struct user_namespace *ns, int cap) 3023263245dSSerge E. Hallyn { 3032920a840SEric Paris int ret; 3042920a840SEric Paris 3052920a840SEric Paris rcu_read_lock(); 3062920a840SEric Paris ret = security_capable(__task_cred(t), ns, cap); 3072920a840SEric Paris rcu_read_unlock(); 3083263245dSSerge E. Hallyn 3093263245dSSerge E. Hallyn return (ret == 0); 3103263245dSSerge E. Hallyn } 3113263245dSSerge E. Hallyn 3123263245dSSerge E. Hallyn /** 31325e75703SEric Paris * has_capability - Does a task have a capability in init_user_ns 31425e75703SEric Paris * @t: The task in question 31525e75703SEric Paris * @cap: The capability to be tested for 31625e75703SEric Paris * 31725e75703SEric Paris * Return true if the specified task has the given superior capability 31825e75703SEric Paris * currently in effect to the initial user namespace, false if not. 31925e75703SEric Paris * 32025e75703SEric Paris * Note that this does not set PF_SUPERPRIV on the task. 32125e75703SEric Paris */ 32225e75703SEric Paris bool has_capability(struct task_struct *t, int cap) 32325e75703SEric Paris { 32425e75703SEric Paris return has_ns_capability(t, &init_user_ns, cap); 32525e75703SEric Paris } 32625e75703SEric Paris 32725e75703SEric Paris /** 3287b61d648SEric Paris * has_ns_capability_noaudit - Does a task have a capability (unaudited) 3297b61d648SEric Paris * in a specific user ns. 3307b61d648SEric Paris * @t: The task in question 3317b61d648SEric Paris * @ns: target user namespace 3327b61d648SEric Paris * @cap: The capability to be tested for 3337b61d648SEric Paris * 3347b61d648SEric Paris * Return true if the specified task has the given superior capability 3357b61d648SEric Paris * currently in effect to the specified user namespace, false if not. 3367b61d648SEric Paris * Do not write an audit message for the check. 3377b61d648SEric Paris * 3387b61d648SEric Paris * Note that this does not set PF_SUPERPRIV on the task. 3397b61d648SEric Paris */ 3407b61d648SEric Paris bool has_ns_capability_noaudit(struct task_struct *t, 3417b61d648SEric Paris struct user_namespace *ns, int cap) 3427b61d648SEric Paris { 3437b61d648SEric Paris int ret; 3447b61d648SEric Paris 3457b61d648SEric Paris rcu_read_lock(); 3467b61d648SEric Paris ret = security_capable_noaudit(__task_cred(t), ns, cap); 3477b61d648SEric Paris rcu_read_unlock(); 3487b61d648SEric Paris 3497b61d648SEric Paris return (ret == 0); 3507b61d648SEric Paris } 3517b61d648SEric Paris 3527b61d648SEric Paris /** 3537b61d648SEric Paris * has_capability_noaudit - Does a task have a capability (unaudited) in the 3547b61d648SEric Paris * initial user ns 3553263245dSSerge E. Hallyn * @t: The task in question 3563263245dSSerge E. Hallyn * @cap: The capability to be tested for 3573263245dSSerge E. Hallyn * 3583263245dSSerge E. Hallyn * Return true if the specified task has the given superior capability 3593263245dSSerge E. Hallyn * currently in effect to init_user_ns, false if not. Don't write an 3603263245dSSerge E. Hallyn * audit message for the check. 3613263245dSSerge E. Hallyn * 3623263245dSSerge E. Hallyn * Note that this does not set PF_SUPERPRIV on the task. 3633263245dSSerge E. Hallyn */ 3643263245dSSerge E. Hallyn bool has_capability_noaudit(struct task_struct *t, int cap) 3653263245dSSerge E. Hallyn { 3667b61d648SEric Paris return has_ns_capability_noaudit(t, &init_user_ns, cap); 3673263245dSSerge E. Hallyn } 3683263245dSSerge E. Hallyn 3693263245dSSerge E. Hallyn /** 3703486740aSSerge E. Hallyn * ns_capable - Determine if the current task has a superior capability in effect 3713486740aSSerge E. Hallyn * @ns: The usernamespace we want the capability in 3723486740aSSerge E. Hallyn * @cap: The capability to be tested for 3733486740aSSerge E. Hallyn * 3743486740aSSerge E. Hallyn * Return true if the current task has the given superior capability currently 3753486740aSSerge E. Hallyn * available for use, false if not. 3763486740aSSerge E. Hallyn * 3773486740aSSerge E. Hallyn * This sets PF_SUPERPRIV on the task if the capability is available on the 3783486740aSSerge E. Hallyn * assumption that it's about to be used. 3793486740aSSerge E. Hallyn */ 3803486740aSSerge E. Hallyn bool ns_capable(struct user_namespace *ns, int cap) 38112b5989bSChris Wright { 382637d32dcSEric Paris if (unlikely(!cap_valid(cap))) { 383637d32dcSEric Paris printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap); 384637d32dcSEric Paris BUG(); 385637d32dcSEric Paris } 386637d32dcSEric Paris 387951880e6SLinus Torvalds if (security_capable(current_cred(), ns, cap) == 0) { 3885cd9c58fSDavid Howells current->flags |= PF_SUPERPRIV; 3893486740aSSerge E. Hallyn return true; 39012b5989bSChris Wright } 3913486740aSSerge E. Hallyn return false; 39212b5989bSChris Wright } 3933486740aSSerge E. Hallyn EXPORT_SYMBOL(ns_capable); 3943486740aSSerge E. Hallyn 3953486740aSSerge E. Hallyn /** 396105ddf49SEric Paris * capable - Determine if the current task has a superior capability in effect 397105ddf49SEric Paris * @cap: The capability to be tested for 3983486740aSSerge E. Hallyn * 399105ddf49SEric Paris * Return true if the current task has the given superior capability currently 400105ddf49SEric Paris * available for use, false if not. 401105ddf49SEric Paris * 402105ddf49SEric Paris * This sets PF_SUPERPRIV on the task if the capability is available on the 403105ddf49SEric Paris * assumption that it's about to be used. 4043486740aSSerge E. Hallyn */ 405105ddf49SEric Paris bool capable(int cap) 4063486740aSSerge E. Hallyn { 407105ddf49SEric Paris return ns_capable(&init_user_ns, cap); 4083486740aSSerge E. Hallyn } 409105ddf49SEric Paris EXPORT_SYMBOL(capable); 41047a150edSSerge E. Hallyn 41147a150edSSerge E. Hallyn /** 41247a150edSSerge E. Hallyn * nsown_capable - Check superior capability to one's own user_ns 41347a150edSSerge E. Hallyn * @cap: The capability in question 41447a150edSSerge E. Hallyn * 41547a150edSSerge E. Hallyn * Return true if the current task has the given superior capability 41647a150edSSerge E. Hallyn * targeted at its own user namespace. 41747a150edSSerge E. Hallyn */ 41847a150edSSerge E. Hallyn bool nsown_capable(int cap) 41947a150edSSerge E. Hallyn { 42047a150edSSerge E. Hallyn return ns_capable(current_user_ns(), cap); 42147a150edSSerge E. Hallyn } 4221a48e2acSEric W. Biederman 4231a48e2acSEric W. Biederman /** 4241a48e2acSEric W. Biederman * inode_capable - Check superior capability over inode 4251a48e2acSEric W. Biederman * @inode: The inode in question 4261a48e2acSEric W. Biederman * @cap: The capability in question 4271a48e2acSEric W. Biederman * 4281a48e2acSEric W. Biederman * Return true if the current task has the given superior capability 4291a48e2acSEric W. Biederman * targeted at it's own user namespace and that the given inode is owned 4301a48e2acSEric W. Biederman * by the current user namespace or a child namespace. 4311a48e2acSEric W. Biederman * 4321a48e2acSEric W. Biederman * Currently inodes can only be owned by the initial user namespace. 4331a48e2acSEric W. Biederman * 4341a48e2acSEric W. Biederman */ 4351a48e2acSEric W. Biederman bool inode_capable(const struct inode *inode, int cap) 4361a48e2acSEric W. Biederman { 4371a48e2acSEric W. Biederman struct user_namespace *ns = current_user_ns(); 4381a48e2acSEric W. Biederman 4391a48e2acSEric W. Biederman return ns_capable(ns, cap) && (ns == &init_user_ns); 4401a48e2acSEric W. Biederman } 441