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 10f5645d35SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11f5645d35SJoe Perches 12e68b75a0SEric Paris #include <linux/audit.h> 13c59ede7bSRandy.Dunlap #include <linux/capability.h> 141da177e4SLinus Torvalds #include <linux/mm.h> 159984de1aSPaul Gortmaker #include <linux/export.h> 161da177e4SLinus Torvalds #include <linux/security.h> 171da177e4SLinus Torvalds #include <linux/syscalls.h> 18b460cbc5SSerge E. Hallyn #include <linux/pid_namespace.h> 193486740aSSerge E. Hallyn #include <linux/user_namespace.h> 201da177e4SLinus Torvalds #include <asm/uaccess.h> 211da177e4SLinus Torvalds 221da177e4SLinus Torvalds /* 23e338d263SAndrew Morgan * Leveraged for setting/resetting capabilities 24e338d263SAndrew Morgan */ 25e338d263SAndrew Morgan 26e338d263SAndrew Morgan const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; 27e338d263SAndrew Morgan EXPORT_SYMBOL(__cap_empty_set); 28e338d263SAndrew Morgan 291f29fae2SSerge E. Hallyn int file_caps_enabled = 1; 301f29fae2SSerge E. Hallyn 311f29fae2SSerge E. Hallyn static int __init file_caps_disable(char *str) 321f29fae2SSerge E. Hallyn { 331f29fae2SSerge E. Hallyn file_caps_enabled = 0; 341f29fae2SSerge E. Hallyn return 1; 351f29fae2SSerge E. Hallyn } 361f29fae2SSerge E. Hallyn __setup("no_file_caps", file_caps_disable); 371f29fae2SSerge E. Hallyn 382813893fSIulia Manda #ifdef CONFIG_MULTIUSER 39e338d263SAndrew Morgan /* 40e338d263SAndrew Morgan * More recent versions of libcap are available from: 41e338d263SAndrew Morgan * 42e338d263SAndrew Morgan * http://www.kernel.org/pub/linux/libs/security/linux-privs/ 43e338d263SAndrew Morgan */ 44e338d263SAndrew Morgan 45e338d263SAndrew Morgan static void warn_legacy_capability_use(void) 46e338d263SAndrew Morgan { 47e338d263SAndrew Morgan char name[sizeof(current->comm)]; 48e338d263SAndrew Morgan 49f5645d35SJoe Perches pr_info_once("warning: `%s' uses 32-bit capabilities (legacy support in use)\n", 50e338d263SAndrew Morgan get_task_comm(name, current)); 51e338d263SAndrew Morgan } 52e338d263SAndrew Morgan 53e338d263SAndrew Morgan /* 54ca05a99aSAndrew G. Morgan * Version 2 capabilities worked fine, but the linux/capability.h file 55ca05a99aSAndrew G. Morgan * that accompanied their introduction encouraged their use without 56ca05a99aSAndrew G. Morgan * the necessary user-space source code changes. As such, we have 57ca05a99aSAndrew G. Morgan * created a version 3 with equivalent functionality to version 2, but 58ca05a99aSAndrew G. Morgan * with a header change to protect legacy source code from using 59ca05a99aSAndrew G. Morgan * version 2 when it wanted to use version 1. If your system has code 60ca05a99aSAndrew G. Morgan * that trips the following warning, it is using version 2 specific 61ca05a99aSAndrew G. Morgan * capabilities and may be doing so insecurely. 62ca05a99aSAndrew G. Morgan * 63ca05a99aSAndrew G. Morgan * The remedy is to either upgrade your version of libcap (to 2.10+, 64ca05a99aSAndrew G. Morgan * if the application is linked against it), or recompile your 65ca05a99aSAndrew G. Morgan * application with modern kernel headers and this warning will go 66ca05a99aSAndrew G. Morgan * away. 67ca05a99aSAndrew G. Morgan */ 68ca05a99aSAndrew G. Morgan 69ca05a99aSAndrew G. Morgan static void warn_deprecated_v2(void) 70ca05a99aSAndrew G. Morgan { 71ca05a99aSAndrew G. Morgan char name[sizeof(current->comm)]; 72ca05a99aSAndrew G. Morgan 73f5645d35SJoe Perches pr_info_once("warning: `%s' uses deprecated v2 capabilities in a way that may be insecure\n", 74ca05a99aSAndrew G. Morgan get_task_comm(name, current)); 75ca05a99aSAndrew G. Morgan } 76ca05a99aSAndrew G. Morgan 77ca05a99aSAndrew G. Morgan /* 78ca05a99aSAndrew G. Morgan * Version check. Return the number of u32s in each capability flag 79ca05a99aSAndrew G. Morgan * array, or a negative value on error. 80ca05a99aSAndrew G. Morgan */ 81ca05a99aSAndrew G. Morgan static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy) 82ca05a99aSAndrew G. Morgan { 83ca05a99aSAndrew G. Morgan __u32 version; 84ca05a99aSAndrew G. Morgan 85ca05a99aSAndrew G. Morgan if (get_user(version, &header->version)) 86ca05a99aSAndrew G. Morgan return -EFAULT; 87ca05a99aSAndrew G. Morgan 88ca05a99aSAndrew G. Morgan switch (version) { 89ca05a99aSAndrew G. Morgan case _LINUX_CAPABILITY_VERSION_1: 90ca05a99aSAndrew G. Morgan warn_legacy_capability_use(); 91ca05a99aSAndrew G. Morgan *tocopy = _LINUX_CAPABILITY_U32S_1; 92ca05a99aSAndrew G. Morgan break; 93ca05a99aSAndrew G. Morgan case _LINUX_CAPABILITY_VERSION_2: 94ca05a99aSAndrew G. Morgan warn_deprecated_v2(); 95ca05a99aSAndrew G. Morgan /* 96ca05a99aSAndrew G. Morgan * fall through - v3 is otherwise equivalent to v2. 97ca05a99aSAndrew G. Morgan */ 98ca05a99aSAndrew G. Morgan case _LINUX_CAPABILITY_VERSION_3: 99ca05a99aSAndrew G. Morgan *tocopy = _LINUX_CAPABILITY_U32S_3; 100ca05a99aSAndrew G. Morgan break; 101ca05a99aSAndrew G. Morgan default: 102ca05a99aSAndrew G. Morgan if (put_user((u32)_KERNEL_CAPABILITY_VERSION, &header->version)) 103ca05a99aSAndrew G. Morgan return -EFAULT; 104ca05a99aSAndrew G. Morgan return -EINVAL; 105ca05a99aSAndrew G. Morgan } 106ca05a99aSAndrew G. Morgan 107ca05a99aSAndrew G. Morgan return 0; 108ca05a99aSAndrew G. Morgan } 109ca05a99aSAndrew G. Morgan 110ab763c71SAndrew G. Morgan /* 111d84f4f99SDavid Howells * The only thing that can change the capabilities of the current 112d84f4f99SDavid Howells * process is the current process. As such, we can't be in this code 113d84f4f99SDavid Howells * at the same time as we are in the process of setting capabilities 114d84f4f99SDavid Howells * in this process. The net result is that we can limit our use of 115d84f4f99SDavid Howells * locks to when we are reading the caps of another process. 116ab763c71SAndrew G. Morgan */ 117ab763c71SAndrew G. Morgan static inline int cap_get_target_pid(pid_t pid, kernel_cap_t *pEp, 118ab763c71SAndrew G. Morgan kernel_cap_t *pIp, kernel_cap_t *pPp) 119ab763c71SAndrew G. Morgan { 120ab763c71SAndrew G. Morgan int ret; 121ab763c71SAndrew G. Morgan 122ab763c71SAndrew G. Morgan if (pid && (pid != task_pid_vnr(current))) { 123ab763c71SAndrew G. Morgan struct task_struct *target; 124ab763c71SAndrew G. Morgan 12586fc80f1SThomas Gleixner rcu_read_lock(); 126ab763c71SAndrew G. Morgan 127ab763c71SAndrew G. Morgan target = find_task_by_vpid(pid); 128ab763c71SAndrew G. Morgan if (!target) 129ab763c71SAndrew G. Morgan ret = -ESRCH; 130ab763c71SAndrew G. Morgan else 131ab763c71SAndrew G. Morgan ret = security_capget(target, pEp, pIp, pPp); 132ab763c71SAndrew G. Morgan 13386fc80f1SThomas Gleixner rcu_read_unlock(); 134ab763c71SAndrew G. Morgan } else 135ab763c71SAndrew G. Morgan ret = security_capget(current, pEp, pIp, pPp); 136ab763c71SAndrew G. Morgan 137ab763c71SAndrew G. Morgan return ret; 138ab763c71SAndrew G. Morgan } 139ab763c71SAndrew G. Morgan 140207a7ba8SRandy Dunlap /** 1411da177e4SLinus Torvalds * sys_capget - get the capabilities of a given process. 142207a7ba8SRandy Dunlap * @header: pointer to struct that contains capability version and 143207a7ba8SRandy Dunlap * target pid data 144207a7ba8SRandy Dunlap * @dataptr: pointer to struct that contains the effective, permitted, 145207a7ba8SRandy Dunlap * and inheritable capabilities that are returned 146207a7ba8SRandy Dunlap * 147207a7ba8SRandy Dunlap * Returns 0 on success and < 0 on error. 1481da177e4SLinus Torvalds */ 149b290ebe2SHeiko Carstens SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) 1501da177e4SLinus Torvalds { 1511da177e4SLinus Torvalds int ret = 0; 1521da177e4SLinus Torvalds pid_t pid; 153e338d263SAndrew Morgan unsigned tocopy; 154e338d263SAndrew Morgan kernel_cap_t pE, pI, pP; 1551da177e4SLinus Torvalds 156ca05a99aSAndrew G. Morgan ret = cap_validate_magic(header, &tocopy); 157c4a5af54SAndrew G. Morgan if ((dataptr == NULL) || (ret != 0)) 158c4a5af54SAndrew G. Morgan return ((dataptr == NULL) && (ret == -EINVAL)) ? 0 : ret; 1591da177e4SLinus Torvalds 1601da177e4SLinus Torvalds if (get_user(pid, &header->pid)) 1611da177e4SLinus Torvalds return -EFAULT; 1621da177e4SLinus Torvalds 1631da177e4SLinus Torvalds if (pid < 0) 1641da177e4SLinus Torvalds return -EINVAL; 1651da177e4SLinus Torvalds 166ab763c71SAndrew G. Morgan ret = cap_get_target_pid(pid, &pE, &pI, &pP); 167e338d263SAndrew Morgan if (!ret) { 168ca05a99aSAndrew G. Morgan struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; 169e338d263SAndrew Morgan unsigned i; 170e338d263SAndrew Morgan 171e338d263SAndrew Morgan for (i = 0; i < tocopy; i++) { 172e338d263SAndrew Morgan kdata[i].effective = pE.cap[i]; 173e338d263SAndrew Morgan kdata[i].permitted = pP.cap[i]; 174e338d263SAndrew Morgan kdata[i].inheritable = pI.cap[i]; 175e338d263SAndrew Morgan } 176e338d263SAndrew Morgan 177e338d263SAndrew Morgan /* 178ca05a99aSAndrew G. Morgan * Note, in the case, tocopy < _KERNEL_CAPABILITY_U32S, 179e338d263SAndrew Morgan * we silently drop the upper capabilities here. This 180e338d263SAndrew Morgan * has the effect of making older libcap 181e338d263SAndrew Morgan * implementations implicitly drop upper capability 182e338d263SAndrew Morgan * bits when they perform a: capget/modify/capset 183e338d263SAndrew Morgan * sequence. 184e338d263SAndrew Morgan * 185e338d263SAndrew Morgan * This behavior is considered fail-safe 186e338d263SAndrew Morgan * behavior. Upgrading the application to a newer 187e338d263SAndrew Morgan * version of libcap will enable access to the newer 188e338d263SAndrew Morgan * capabilities. 189e338d263SAndrew Morgan * 190e338d263SAndrew Morgan * An alternative would be to return an error here 191e338d263SAndrew Morgan * (-ERANGE), but that causes legacy applications to 192a6c8c690SFabian Frederick * unexpectedly fail; the capget/modify/capset aborts 193e338d263SAndrew Morgan * before modification is attempted and the application 194e338d263SAndrew Morgan * fails. 195e338d263SAndrew Morgan */ 196e338d263SAndrew Morgan if (copy_to_user(dataptr, kdata, tocopy 197e338d263SAndrew Morgan * sizeof(struct __user_cap_data_struct))) { 1981da177e4SLinus Torvalds return -EFAULT; 199e338d263SAndrew Morgan } 200e338d263SAndrew Morgan } 2011da177e4SLinus Torvalds 2021da177e4SLinus Torvalds return ret; 2031da177e4SLinus Torvalds } 2041da177e4SLinus Torvalds 205207a7ba8SRandy Dunlap /** 206ab763c71SAndrew G. Morgan * sys_capset - set capabilities for a process or (*) a group of processes 207207a7ba8SRandy Dunlap * @header: pointer to struct that contains capability version and 208207a7ba8SRandy Dunlap * target pid data 209207a7ba8SRandy Dunlap * @data: pointer to struct that contains the effective, permitted, 210207a7ba8SRandy Dunlap * and inheritable capabilities 211207a7ba8SRandy Dunlap * 2121cdcbec1SDavid Howells * Set capabilities for the current process only. The ability to any other 2131cdcbec1SDavid Howells * process(es) has been deprecated and removed. 2141da177e4SLinus Torvalds * 2151da177e4SLinus Torvalds * The restrictions on setting capabilities are specified as: 2161da177e4SLinus Torvalds * 2171cdcbec1SDavid Howells * I: any raised capabilities must be a subset of the old permitted 2181cdcbec1SDavid Howells * P: any raised capabilities must be a subset of the old permitted 2191cdcbec1SDavid Howells * E: must be set to a subset of new permitted 220207a7ba8SRandy Dunlap * 221207a7ba8SRandy Dunlap * Returns 0 on success and < 0 on error. 2221da177e4SLinus Torvalds */ 223b290ebe2SHeiko Carstens SYSCALL_DEFINE2(capset, cap_user_header_t, header, const cap_user_data_t, data) 2241da177e4SLinus Torvalds { 225ca05a99aSAndrew G. Morgan struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; 226825332e4SArjan van de Ven unsigned i, tocopy, copybytes; 2271da177e4SLinus Torvalds kernel_cap_t inheritable, permitted, effective; 228d84f4f99SDavid Howells struct cred *new; 2291da177e4SLinus Torvalds int ret; 2301da177e4SLinus Torvalds pid_t pid; 2311da177e4SLinus Torvalds 232ca05a99aSAndrew G. Morgan ret = cap_validate_magic(header, &tocopy); 233ca05a99aSAndrew G. Morgan if (ret != 0) 234ca05a99aSAndrew G. Morgan return ret; 2351da177e4SLinus Torvalds 2361da177e4SLinus Torvalds if (get_user(pid, &header->pid)) 2371da177e4SLinus Torvalds return -EFAULT; 2381da177e4SLinus Torvalds 2391cdcbec1SDavid Howells /* may only affect current now */ 2401cdcbec1SDavid Howells if (pid != 0 && pid != task_pid_vnr(current)) 2411cdcbec1SDavid Howells return -EPERM; 2421cdcbec1SDavid Howells 243825332e4SArjan van de Ven copybytes = tocopy * sizeof(struct __user_cap_data_struct); 244825332e4SArjan van de Ven if (copybytes > sizeof(kdata)) 245825332e4SArjan van de Ven return -EFAULT; 246825332e4SArjan van de Ven 247825332e4SArjan van de Ven if (copy_from_user(&kdata, data, copybytes)) 2481da177e4SLinus Torvalds return -EFAULT; 249e338d263SAndrew Morgan 250e338d263SAndrew Morgan for (i = 0; i < tocopy; i++) { 251e338d263SAndrew Morgan effective.cap[i] = kdata[i].effective; 252e338d263SAndrew Morgan permitted.cap[i] = kdata[i].permitted; 253e338d263SAndrew Morgan inheritable.cap[i] = kdata[i].inheritable; 254e338d263SAndrew Morgan } 255ca05a99aSAndrew G. Morgan while (i < _KERNEL_CAPABILITY_U32S) { 256e338d263SAndrew Morgan effective.cap[i] = 0; 257e338d263SAndrew Morgan permitted.cap[i] = 0; 258e338d263SAndrew Morgan inheritable.cap[i] = 0; 259e338d263SAndrew Morgan i++; 260e338d263SAndrew Morgan } 2611da177e4SLinus Torvalds 2627d8b6c63SEric Paris effective.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 2637d8b6c63SEric Paris permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 2647d8b6c63SEric Paris inheritable.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK; 2657d8b6c63SEric Paris 266d84f4f99SDavid Howells new = prepare_creds(); 267d84f4f99SDavid Howells if (!new) 268d84f4f99SDavid Howells return -ENOMEM; 269d84f4f99SDavid Howells 270d84f4f99SDavid Howells ret = security_capset(new, current_cred(), 271d84f4f99SDavid Howells &effective, &inheritable, &permitted); 272d84f4f99SDavid Howells if (ret < 0) 273d84f4f99SDavid Howells goto error; 274d84f4f99SDavid Howells 275ca24a23eSEric W. Biederman audit_log_capset(new, current_cred()); 276e68b75a0SEric Paris 277d84f4f99SDavid Howells return commit_creds(new); 2781da177e4SLinus Torvalds 279d84f4f99SDavid Howells error: 280d84f4f99SDavid Howells abort_creds(new); 2811da177e4SLinus Torvalds return ret; 2821da177e4SLinus Torvalds } 28312b5989bSChris Wright 2845cd9c58fSDavid Howells /** 28525e75703SEric Paris * has_ns_capability - Does a task have a capability in a specific user ns 2863263245dSSerge E. Hallyn * @t: The task in question 2873263245dSSerge E. Hallyn * @ns: target user namespace 2883263245dSSerge E. Hallyn * @cap: The capability to be tested for 2893263245dSSerge E. Hallyn * 2903263245dSSerge E. Hallyn * Return true if the specified task has the given superior capability 2913263245dSSerge E. Hallyn * currently in effect to the specified user namespace, false if not. 2923263245dSSerge E. Hallyn * 2933263245dSSerge E. Hallyn * Note that this does not set PF_SUPERPRIV on the task. 2943263245dSSerge E. Hallyn */ 2953263245dSSerge E. Hallyn bool has_ns_capability(struct task_struct *t, 2963263245dSSerge E. Hallyn struct user_namespace *ns, int cap) 2973263245dSSerge E. Hallyn { 2982920a840SEric Paris int ret; 2992920a840SEric Paris 3002920a840SEric Paris rcu_read_lock(); 3012920a840SEric Paris ret = security_capable(__task_cred(t), ns, cap); 3022920a840SEric Paris rcu_read_unlock(); 3033263245dSSerge E. Hallyn 3043263245dSSerge E. Hallyn return (ret == 0); 3053263245dSSerge E. Hallyn } 3063263245dSSerge E. Hallyn 3073263245dSSerge E. Hallyn /** 30825e75703SEric Paris * has_capability - Does a task have a capability in init_user_ns 30925e75703SEric Paris * @t: The task in question 31025e75703SEric Paris * @cap: The capability to be tested for 31125e75703SEric Paris * 31225e75703SEric Paris * Return true if the specified task has the given superior capability 31325e75703SEric Paris * currently in effect to the initial user namespace, false if not. 31425e75703SEric Paris * 31525e75703SEric Paris * Note that this does not set PF_SUPERPRIV on the task. 31625e75703SEric Paris */ 31725e75703SEric Paris bool has_capability(struct task_struct *t, int cap) 31825e75703SEric Paris { 31925e75703SEric Paris return has_ns_capability(t, &init_user_ns, cap); 32025e75703SEric Paris } 32125e75703SEric Paris 32225e75703SEric Paris /** 3237b61d648SEric Paris * has_ns_capability_noaudit - Does a task have a capability (unaudited) 3247b61d648SEric Paris * in a specific user ns. 3257b61d648SEric Paris * @t: The task in question 3267b61d648SEric Paris * @ns: target user namespace 3277b61d648SEric Paris * @cap: The capability to be tested for 3287b61d648SEric Paris * 3297b61d648SEric Paris * Return true if the specified task has the given superior capability 3307b61d648SEric Paris * currently in effect to the specified user namespace, false if not. 3317b61d648SEric Paris * Do not write an audit message for the check. 3327b61d648SEric Paris * 3337b61d648SEric Paris * Note that this does not set PF_SUPERPRIV on the task. 3347b61d648SEric Paris */ 3357b61d648SEric Paris bool has_ns_capability_noaudit(struct task_struct *t, 3367b61d648SEric Paris struct user_namespace *ns, int cap) 3377b61d648SEric Paris { 3387b61d648SEric Paris int ret; 3397b61d648SEric Paris 3407b61d648SEric Paris rcu_read_lock(); 3417b61d648SEric Paris ret = security_capable_noaudit(__task_cred(t), ns, cap); 3427b61d648SEric Paris rcu_read_unlock(); 3437b61d648SEric Paris 3447b61d648SEric Paris return (ret == 0); 3457b61d648SEric Paris } 3467b61d648SEric Paris 3477b61d648SEric Paris /** 3487b61d648SEric Paris * has_capability_noaudit - Does a task have a capability (unaudited) in the 3497b61d648SEric Paris * initial user ns 3503263245dSSerge E. Hallyn * @t: The task in question 3513263245dSSerge E. Hallyn * @cap: The capability to be tested for 3523263245dSSerge E. Hallyn * 3533263245dSSerge E. Hallyn * Return true if the specified task has the given superior capability 3543263245dSSerge E. Hallyn * currently in effect to init_user_ns, false if not. Don't write an 3553263245dSSerge E. Hallyn * audit message for the check. 3563263245dSSerge E. Hallyn * 3573263245dSSerge E. Hallyn * Note that this does not set PF_SUPERPRIV on the task. 3583263245dSSerge E. Hallyn */ 3593263245dSSerge E. Hallyn bool has_capability_noaudit(struct task_struct *t, int cap) 3603263245dSSerge E. Hallyn { 3617b61d648SEric Paris return has_ns_capability_noaudit(t, &init_user_ns, cap); 3623263245dSSerge E. Hallyn } 3633263245dSSerge E. Hallyn 3643263245dSSerge E. Hallyn /** 3653486740aSSerge E. Hallyn * ns_capable - Determine if the current task has a superior capability in effect 3663486740aSSerge E. Hallyn * @ns: The usernamespace we want the capability in 3673486740aSSerge E. Hallyn * @cap: The capability to be tested for 3683486740aSSerge E. Hallyn * 3693486740aSSerge E. Hallyn * Return true if the current task has the given superior capability currently 3703486740aSSerge E. Hallyn * available for use, false if not. 3713486740aSSerge E. Hallyn * 3723486740aSSerge E. Hallyn * This sets PF_SUPERPRIV on the task if the capability is available on the 3733486740aSSerge E. Hallyn * assumption that it's about to be used. 3743486740aSSerge E. Hallyn */ 3753486740aSSerge E. Hallyn bool ns_capable(struct user_namespace *ns, int cap) 37612b5989bSChris Wright { 377637d32dcSEric Paris if (unlikely(!cap_valid(cap))) { 378f5645d35SJoe Perches pr_crit("capable() called with invalid cap=%u\n", cap); 379637d32dcSEric Paris BUG(); 380637d32dcSEric Paris } 381637d32dcSEric Paris 382951880e6SLinus Torvalds if (security_capable(current_cred(), ns, cap) == 0) { 3835cd9c58fSDavid Howells current->flags |= PF_SUPERPRIV; 3843486740aSSerge E. Hallyn return true; 38512b5989bSChris Wright } 3863486740aSSerge E. Hallyn return false; 38712b5989bSChris Wright } 3883486740aSSerge E. Hallyn EXPORT_SYMBOL(ns_capable); 3893486740aSSerge E. Hallyn 3902813893fSIulia Manda 3912813893fSIulia Manda /** 3922813893fSIulia Manda * capable - Determine if the current task has a superior capability in effect 3932813893fSIulia Manda * @cap: The capability to be tested for 3942813893fSIulia Manda * 3952813893fSIulia Manda * Return true if the current task has the given superior capability currently 3962813893fSIulia Manda * available for use, false if not. 3972813893fSIulia Manda * 3982813893fSIulia Manda * This sets PF_SUPERPRIV on the task if the capability is available on the 3992813893fSIulia Manda * assumption that it's about to be used. 4002813893fSIulia Manda */ 4012813893fSIulia Manda bool capable(int cap) 4022813893fSIulia Manda { 4032813893fSIulia Manda return ns_capable(&init_user_ns, cap); 4042813893fSIulia Manda } 4052813893fSIulia Manda EXPORT_SYMBOL(capable); 4062813893fSIulia Manda #endif /* CONFIG_MULTIUSER */ 4072813893fSIulia Manda 4083486740aSSerge E. Hallyn /** 409935d8aabSLinus Torvalds * file_ns_capable - Determine if the file's opener had a capability in effect 410935d8aabSLinus Torvalds * @file: The file we want to check 411935d8aabSLinus Torvalds * @ns: The usernamespace we want the capability in 412935d8aabSLinus Torvalds * @cap: The capability to be tested for 413935d8aabSLinus Torvalds * 414935d8aabSLinus Torvalds * Return true if task that opened the file had a capability in effect 415935d8aabSLinus Torvalds * when the file was opened. 416935d8aabSLinus Torvalds * 417935d8aabSLinus Torvalds * This does not set PF_SUPERPRIV because the caller may not 418935d8aabSLinus Torvalds * actually be privileged. 419935d8aabSLinus Torvalds */ 420a6c8c690SFabian Frederick bool file_ns_capable(const struct file *file, struct user_namespace *ns, 421a6c8c690SFabian Frederick int cap) 422935d8aabSLinus Torvalds { 423935d8aabSLinus Torvalds if (WARN_ON_ONCE(!cap_valid(cap))) 424935d8aabSLinus Torvalds return false; 425935d8aabSLinus Torvalds 426935d8aabSLinus Torvalds if (security_capable(file->f_cred, ns, cap) == 0) 427935d8aabSLinus Torvalds return true; 428935d8aabSLinus Torvalds 429935d8aabSLinus Torvalds return false; 430935d8aabSLinus Torvalds } 431935d8aabSLinus Torvalds EXPORT_SYMBOL(file_ns_capable); 432935d8aabSLinus Torvalds 433935d8aabSLinus Torvalds /** 43423adbe12SAndy Lutomirski * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped 4351a48e2acSEric W. Biederman * @inode: The inode in question 4361a48e2acSEric W. Biederman * @cap: The capability in question 4371a48e2acSEric W. Biederman * 43823adbe12SAndy Lutomirski * Return true if the current task has the given capability targeted at 43923adbe12SAndy Lutomirski * its own user namespace and that the given inode's uid and gid are 44023adbe12SAndy Lutomirski * mapped into the current user namespace. 4411a48e2acSEric W. Biederman */ 44223adbe12SAndy Lutomirski bool capable_wrt_inode_uidgid(const struct inode *inode, int cap) 4431a48e2acSEric W. Biederman { 4441a48e2acSEric W. Biederman struct user_namespace *ns = current_user_ns(); 4451a48e2acSEric W. Biederman 44623adbe12SAndy Lutomirski return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) && 44723adbe12SAndy Lutomirski kgid_has_mapping(ns, inode->i_gid); 4481a48e2acSEric W. Biederman } 44923adbe12SAndy Lutomirski EXPORT_SYMBOL(capable_wrt_inode_uidgid); 450