~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/capability.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /kernel/capability.c (Version linux-6.11.5) and /kernel/capability.c (Version ccs-tools-1.8.9)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*                                                
  3  * linux/kernel/capability.c                      
  4  *                                                
  5  * Copyright (C) 1997  Andrew Main <zefram@fys    
  6  *                                                
  7  * Integrated into 2.1.97+,  Andrew G. Morgan     
  8  * 30 May 2002: Cleanup, Robert M. Love <rml@t    
  9  */                                               
 10                                                   
 11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt       
 12                                                   
 13 #include <linux/audit.h>                          
 14 #include <linux/capability.h>                     
 15 #include <linux/mm.h>                             
 16 #include <linux/export.h>                         
 17 #include <linux/security.h>                       
 18 #include <linux/syscalls.h>                       
 19 #include <linux/pid_namespace.h>                  
 20 #include <linux/user_namespace.h>                 
 21 #include <linux/uaccess.h>                        
 22                                                   
 23 int file_caps_enabled = 1;                        
 24                                                   
 25 static int __init file_caps_disable(char *str)    
 26 {                                                 
 27         file_caps_enabled = 0;                    
 28         return 1;                                 
 29 }                                                 
 30 __setup("no_file_caps", file_caps_disable);       
 31                                                   
 32 #ifdef CONFIG_MULTIUSER                           
 33 /*                                                
 34  * More recent versions of libcap are availabl    
 35  *                                                
 36  *   http://www.kernel.org/pub/linux/libs/secu    
 37  */                                               
 38                                                   
 39 static void warn_legacy_capability_use(void)      
 40 {                                                 
 41         char name[sizeof(current->comm)];         
 42                                                   
 43         pr_info_once("warning: `%s' uses 32-bi    
 44                      get_task_comm(name, curre    
 45 }                                                 
 46                                                   
 47 /*                                                
 48  * Version 2 capabilities worked fine, but the    
 49  * that accompanied their introduction encoura    
 50  * the necessary user-space source code change    
 51  * created a version 3 with equivalent functio    
 52  * with a header change to protect legacy sour    
 53  * version 2 when it wanted to use version 1.     
 54  * that trips the following warning, it is usi    
 55  * capabilities and may be doing so insecurely    
 56  *                                                
 57  * The remedy is to either upgrade your versio    
 58  * if the application is linked against it), o    
 59  * application with modern kernel headers and     
 60  * away.                                          
 61  */                                               
 62                                                   
 63 static void warn_deprecated_v2(void)              
 64 {                                                 
 65         char name[sizeof(current->comm)];         
 66                                                   
 67         pr_info_once("warning: `%s' uses depre    
 68                      get_task_comm(name, curre    
 69 }                                                 
 70                                                   
 71 /*                                                
 72  * Version check. Return the number of u32s in    
 73  * array, or a negative value on error.           
 74  */                                               
 75 static int cap_validate_magic(cap_user_header_    
 76 {                                                 
 77         __u32 version;                            
 78                                                   
 79         if (get_user(version, &header->version    
 80                 return -EFAULT;                   
 81                                                   
 82         switch (version) {                        
 83         case _LINUX_CAPABILITY_VERSION_1:         
 84                 warn_legacy_capability_use();     
 85                 *tocopy = _LINUX_CAPABILITY_U3    
 86                 break;                            
 87         case _LINUX_CAPABILITY_VERSION_2:         
 88                 warn_deprecated_v2();             
 89                 fallthrough;    /* v3 is other    
 90         case _LINUX_CAPABILITY_VERSION_3:         
 91                 *tocopy = _LINUX_CAPABILITY_U3    
 92                 break;                            
 93         default:                                  
 94                 if (put_user((u32)_KERNEL_CAPA    
 95                         return -EFAULT;           
 96                 return -EINVAL;                   
 97         }                                         
 98                                                   
 99         return 0;                                 
100 }                                                 
101                                                   
102 /*                                                
103  * The only thing that can change the capabili    
104  * process is the current process. As such, we    
105  * at the same time as we are in the process o    
106  * in this process. The net result is that we     
107  * locks to when we are reading the caps of an    
108  */                                               
109 static inline int cap_get_target_pid(pid_t pid    
110                                      kernel_ca    
111 {                                                 
112         int ret;                                  
113                                                   
114         if (pid && (pid != task_pid_vnr(curren    
115                 const struct task_struct *targ    
116                                                   
117                 rcu_read_lock();                  
118                                                   
119                 target = find_task_by_vpid(pid    
120                 if (!target)                      
121                         ret = -ESRCH;             
122                 else                              
123                         ret = security_capget(    
124                                                   
125                 rcu_read_unlock();                
126         } else                                    
127                 ret = security_capget(current,    
128                                                   
129         return ret;                               
130 }                                                 
131                                                   
132 /**                                               
133  * sys_capget - get the capabilities of a give    
134  * @header: pointer to struct that contains ca    
135  *      target pid data                           
136  * @dataptr: pointer to struct that contains t    
137  *      and inheritable capabilities that are     
138  *                                                
139  * Returns 0 on success and < 0 on error.         
140  */                                               
141 SYSCALL_DEFINE2(capget, cap_user_header_t, hea    
142 {                                                 
143         int ret = 0;                              
144         pid_t pid;                                
145         unsigned tocopy;                          
146         kernel_cap_t pE, pI, pP;                  
147         struct __user_cap_data_struct kdata[2]    
148                                                   
149         ret = cap_validate_magic(header, &toco    
150         if ((dataptr == NULL) || (ret != 0))      
151                 return ((dataptr == NULL) && (    
152                                                   
153         if (get_user(pid, &header->pid))          
154                 return -EFAULT;                   
155                                                   
156         if (pid < 0)                              
157                 return -EINVAL;                   
158                                                   
159         ret = cap_get_target_pid(pid, &pE, &pI    
160         if (ret)                                  
161                 return ret;                       
162                                                   
163         /*                                        
164          * Annoying legacy format with 64-bit     
165          * as two sets of 32-bit fields, so we    
166          * capability values up.                  
167          */                                       
168         kdata[0].effective   = pE.val; kdata[1    
169         kdata[0].permitted   = pP.val; kdata[1    
170         kdata[0].inheritable = pI.val; kdata[1    
171                                                   
172         /*                                        
173          * Note, in the case, tocopy < _KERNEL    
174          * we silently drop the upper capabili    
175          * has the effect of making older libc    
176          * implementations implicitly drop upp    
177          * bits when they perform a: capget/mo    
178          * sequence.                              
179          *                                        
180          * This behavior is considered fail-sa    
181          * behavior. Upgrading the application    
182          * version of libcap will enable acces    
183          * capabilities.                          
184          *                                        
185          * An alternative would be to return a    
186          * (-ERANGE), but that causes legacy a    
187          * unexpectedly fail; the capget/modif    
188          * before modification is attempted an    
189          * fails.                                 
190          */                                       
191         if (copy_to_user(dataptr, kdata, tocop    
192                 return -EFAULT;                   
193                                                   
194         return 0;                                 
195 }                                                 
196                                                   
197 static kernel_cap_t mk_kernel_cap(u32 low, u32    
198 {                                                 
199         return (kernel_cap_t) { (low | ((u64)h    
200 }                                                 
201                                                   
202 /**                                               
203  * sys_capset - set capabilities for a process    
204  * @header: pointer to struct that contains ca    
205  *      target pid data                           
206  * @data: pointer to struct that contains the     
207  *      and inheritable capabilities              
208  *                                                
209  * Set capabilities for the current process on    
210  * process(es) has been deprecated and removed    
211  *                                                
212  * The restrictions on setting capabilities ar    
213  *                                                
214  * I: any raised capabilities must be a subset    
215  * P: any raised capabilities must be a subset    
216  * E: must be set to a subset of new permitted    
217  *                                                
218  * Returns 0 on success and < 0 on error.         
219  */                                               
220 SYSCALL_DEFINE2(capset, cap_user_header_t, hea    
221 {                                                 
222         struct __user_cap_data_struct kdata[2]    
223         unsigned tocopy, copybytes;               
224         kernel_cap_t inheritable, permitted, e    
225         struct cred *new;                         
226         int ret;                                  
227         pid_t pid;                                
228                                                   
229         ret = cap_validate_magic(header, &toco    
230         if (ret != 0)                             
231                 return ret;                       
232                                                   
233         if (get_user(pid, &header->pid))          
234                 return -EFAULT;                   
235                                                   
236         /* may only affect current now */         
237         if (pid != 0 && pid != task_pid_vnr(cu    
238                 return -EPERM;                    
239                                                   
240         copybytes = tocopy * sizeof(struct __u    
241         if (copybytes > sizeof(kdata))            
242                 return -EFAULT;                   
243                                                   
244         if (copy_from_user(&kdata, data, copyb    
245                 return -EFAULT;                   
246                                                   
247         effective   = mk_kernel_cap(kdata[0].e    
248         permitted   = mk_kernel_cap(kdata[0].p    
249         inheritable = mk_kernel_cap(kdata[0].i    
250                                                   
251         new = prepare_creds();                    
252         if (!new)                                 
253                 return -ENOMEM;                   
254                                                   
255         ret = security_capset(new, current_cre    
256                               &effective, &inh    
257         if (ret < 0)                              
258                 goto error;                       
259                                                   
260         audit_log_capset(new, current_cred());    
261                                                   
262         return commit_creds(new);                 
263                                                   
264 error:                                            
265         abort_creds(new);                         
266         return ret;                               
267 }                                                 
268                                                   
269 /**                                               
270  * has_ns_capability - Does a task have a capa    
271  * @t: The task in question                       
272  * @ns: target user namespace                     
273  * @cap: The capability to be tested for          
274  *                                                
275  * Return true if the specified task has the g    
276  * currently in effect to the specified user n    
277  *                                                
278  * Note that this does not set PF_SUPERPRIV on    
279  */                                               
280 bool has_ns_capability(struct task_struct *t,     
281                        struct user_namespace *    
282 {                                                 
283         int ret;                                  
284                                                   
285         rcu_read_lock();                          
286         ret = security_capable(__task_cred(t),    
287         rcu_read_unlock();                        
288                                                   
289         return (ret == 0);                        
290 }                                                 
291                                                   
292 /**                                               
293  * has_capability - Does a task have a capabil    
294  * @t: The task in question                       
295  * @cap: The capability to be tested for          
296  *                                                
297  * Return true if the specified task has the g    
298  * currently in effect to the initial user nam    
299  *                                                
300  * Note that this does not set PF_SUPERPRIV on    
301  */                                               
302 bool has_capability(struct task_struct *t, int    
303 {                                                 
304         return has_ns_capability(t, &init_user    
305 }                                                 
306 EXPORT_SYMBOL(has_capability);                    
307                                                   
308 /**                                               
309  * has_ns_capability_noaudit - Does a task hav    
310  * in a specific user ns.                         
311  * @t: The task in question                       
312  * @ns: target user namespace                     
313  * @cap: The capability to be tested for          
314  *                                                
315  * Return true if the specified task has the g    
316  * currently in effect to the specified user n    
317  * Do not write an audit message for the check    
318  *                                                
319  * Note that this does not set PF_SUPERPRIV on    
320  */                                               
321 bool has_ns_capability_noaudit(struct task_str    
322                                struct user_nam    
323 {                                                 
324         int ret;                                  
325                                                   
326         rcu_read_lock();                          
327         ret = security_capable(__task_cred(t),    
328         rcu_read_unlock();                        
329                                                   
330         return (ret == 0);                        
331 }                                                 
332                                                   
333 /**                                               
334  * has_capability_noaudit - Does a task have a    
335  * initial user ns                                
336  * @t: The task in question                       
337  * @cap: The capability to be tested for          
338  *                                                
339  * Return true if the specified task has the g    
340  * currently in effect to init_user_ns, false     
341  * audit message for the check.                   
342  *                                                
343  * Note that this does not set PF_SUPERPRIV on    
344  */                                               
345 bool has_capability_noaudit(struct task_struct    
346 {                                                 
347         return has_ns_capability_noaudit(t, &i    
348 }                                                 
349 EXPORT_SYMBOL(has_capability_noaudit);            
350                                                   
351 static bool ns_capable_common(struct user_name    
352                               int cap,            
353                               unsigned int opt    
354 {                                                 
355         int capable;                              
356                                                   
357         if (unlikely(!cap_valid(cap))) {          
358                 pr_crit("capable() called with    
359                 BUG();                            
360         }                                         
361                                                   
362         capable = security_capable(current_cre    
363         if (capable == 0) {                       
364                 current->flags |= PF_SUPERPRIV    
365                 return true;                      
366         }                                         
367         return false;                             
368 }                                                 
369                                                   
370 /**                                               
371  * ns_capable - Determine if the current task     
372  * @ns:  The usernamespace we want the capabil    
373  * @cap: The capability to be tested for          
374  *                                                
375  * Return true if the current task has the giv    
376  * available for use, false if not.               
377  *                                                
378  * This sets PF_SUPERPRIV on the task if the c    
379  * assumption that it's about to be used.         
380  */                                               
381 bool ns_capable(struct user_namespace *ns, int    
382 {                                                 
383         return ns_capable_common(ns, cap, CAP_    
384 }                                                 
385 EXPORT_SYMBOL(ns_capable);                        
386                                                   
387 /**                                               
388  * ns_capable_noaudit - Determine if the curre    
389  * (unaudited) in effect                          
390  * @ns:  The usernamespace we want the capabil    
391  * @cap: The capability to be tested for          
392  *                                                
393  * Return true if the current task has the giv    
394  * available for use, false if not.               
395  *                                                
396  * This sets PF_SUPERPRIV on the task if the c    
397  * assumption that it's about to be used.         
398  */                                               
399 bool ns_capable_noaudit(struct user_namespace     
400 {                                                 
401         return ns_capable_common(ns, cap, CAP_    
402 }                                                 
403 EXPORT_SYMBOL(ns_capable_noaudit);                
404                                                   
405 /**                                               
406  * ns_capable_setid - Determine if the current    
407  * in effect, while signalling that this check    
408  * setid or setgroups syscall.                    
409  * @ns:  The usernamespace we want the capabil    
410  * @cap: The capability to be tested for          
411  *                                                
412  * Return true if the current task has the giv    
413  * available for use, false if not.               
414  *                                                
415  * This sets PF_SUPERPRIV on the task if the c    
416  * assumption that it's about to be used.         
417  */                                               
418 bool ns_capable_setid(struct user_namespace *n    
419 {                                                 
420         return ns_capable_common(ns, cap, CAP_    
421 }                                                 
422 EXPORT_SYMBOL(ns_capable_setid);                  
423                                                   
424 /**                                               
425  * capable - Determine if the current task has    
426  * @cap: The capability to be tested for          
427  *                                                
428  * Return true if the current task has the giv    
429  * available for use, false if not.               
430  *                                                
431  * This sets PF_SUPERPRIV on the task if the c    
432  * assumption that it's about to be used.         
433  */                                               
434 bool capable(int cap)                             
435 {                                                 
436         return ns_capable(&init_user_ns, cap);    
437 }                                                 
438 EXPORT_SYMBOL(capable);                           
439 #endif /* CONFIG_MULTIUSER */                     
440                                                   
441 /**                                               
442  * file_ns_capable - Determine if the file's o    
443  * @file:  The file we want to check              
444  * @ns:  The usernamespace we want the capabil    
445  * @cap: The capability to be tested for          
446  *                                                
447  * Return true if task that opened the file ha    
448  * when the file was opened.                      
449  *                                                
450  * This does not set PF_SUPERPRIV because the     
451  * actually be privileged.                        
452  */                                               
453 bool file_ns_capable(const struct file *file,     
454                      int cap)                     
455 {                                                 
456                                                   
457         if (WARN_ON_ONCE(!cap_valid(cap)))        
458                 return false;                     
459                                                   
460         if (security_capable(file->f_cred, ns,    
461                 return true;                      
462                                                   
463         return false;                             
464 }                                                 
465 EXPORT_SYMBOL(file_ns_capable);                   
466                                                   
467 /**                                               
468  * privileged_wrt_inode_uidgid - Do capabiliti    
469  * @ns: The user namespace in question            
470  * @idmap: idmap of the mount @inode was found    
471  * @inode: The inode in question                  
472  *                                                
473  * Return true if the inode uid and gid are wi    
474  */                                               
475 bool privileged_wrt_inode_uidgid(struct user_n    
476                                  struct mnt_id    
477                                  const struct     
478 {                                                 
479         return vfsuid_has_mapping(ns, i_uid_in    
480                vfsgid_has_mapping(ns, i_gid_in    
481 }                                                 
482                                                   
483 /**                                               
484  * capable_wrt_inode_uidgid - Check nsown_capa    
485  * @idmap: idmap of the mount @inode was found    
486  * @inode: The inode in question                  
487  * @cap: The capability in question               
488  *                                                
489  * Return true if the current task has the giv    
490  * its own user namespace and that the given i    
491  * mapped into the current user namespace.        
492  */                                               
493 bool capable_wrt_inode_uidgid(struct mnt_idmap    
494                               const struct ino    
495 {                                                 
496         struct user_namespace *ns = current_us    
497                                                   
498         return ns_capable(ns, cap) &&             
499                privileged_wrt_inode_uidgid(ns,    
500 }                                                 
501 EXPORT_SYMBOL(capable_wrt_inode_uidgid);          
502                                                   
503 /**                                               
504  * ptracer_capable - Determine if the ptracer     
505  * @tsk: The task that may be ptraced             
506  * @ns: The user namespace to search for CAP_S    
507  *                                                
508  * Return true if the task that is ptracing th    
509  * in the specified user namespace.               
510  */                                               
511 bool ptracer_capable(struct task_struct *tsk,     
512 {                                                 
513         int ret = 0;  /* An absent tracer adds    
514         const struct cred *cred;                  
515                                                   
516         rcu_read_lock();                          
517         cred = rcu_dereference(tsk->ptracer_cr    
518         if (cred)                                 
519                 ret = security_capable(cred, n    
520                                        CAP_OPT    
521         rcu_read_unlock();                        
522         return (ret == 0);                        
523 }                                                 
524                                                   

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php