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

TOMOYO Linux Cross Reference
Linux/security/ipe/policy_fs.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ 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.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /security/ipe/policy_fs.c (Version linux-6.12-rc7) and /security/ipe/policy_fs.c (Version linux-4.16.18)


  1 // SPDX-License-Identifier: GPL-2.0                 1 
  2 /*                                                
  3  * Copyright (C) 2020-2024 Microsoft Corporati    
  4  */                                               
  5 #include <linux/fs.h>                             
  6 #include <linux/namei.h>                          
  7 #include <linux/types.h>                          
  8 #include <linux/dcache.h>                         
  9 #include <linux/security.h>                       
 10                                                   
 11 #include "ipe.h"                                  
 12 #include "policy.h"                               
 13 #include "eval.h"                                 
 14 #include "fs.h"                                   
 15                                                   
 16 #define MAX_VERSION_SIZE ARRAY_SIZE("65535.655    
 17                                                   
 18 /**                                               
 19  * ipefs_file - defines a file in securityfs.     
 20  */                                               
 21 struct ipefs_file {                               
 22         const char *name;                         
 23         umode_t access;                           
 24         const struct file_operations *fops;       
 25 };                                                
 26                                                   
 27 /**                                               
 28  * read_pkcs7() - Read handler for "ipe/polici    
 29  * @f: Supplies a file structure representing     
 30  * @data: Supplies a buffer passed to the writ    
 31  * @len: Supplies the length of @data.            
 32  * @offset: unused.                               
 33  *                                                
 34  * @data will be populated with the pkcs7 blob    
 35  * on success. If the policy is unsigned (like    
 36  * will return -ENOENT.                           
 37  *                                                
 38  * Return:                                        
 39  * * Length of buffer written   - Success         
 40  * * %-ENOENT                   - Policy initi    
 41  */                                               
 42 static ssize_t read_pkcs7(struct file *f, char    
 43                           size_t len, loff_t *    
 44 {                                                 
 45         const struct ipe_policy *p = NULL;        
 46         struct inode *root = NULL;                
 47         int rc = 0;                               
 48                                                   
 49         root = d_inode(f->f_path.dentry->d_par    
 50                                                   
 51         inode_lock_shared(root);                  
 52         p = (struct ipe_policy *)root->i_priva    
 53         if (!p) {                                 
 54                 rc = -ENOENT;                     
 55                 goto out;                         
 56         }                                         
 57                                                   
 58         if (!p->pkcs7) {                          
 59                 rc = -ENOENT;                     
 60                 goto out;                         
 61         }                                         
 62                                                   
 63         rc = simple_read_from_buffer(data, len    
 64                                                   
 65 out:                                              
 66         inode_unlock_shared(root);                
 67                                                   
 68         return rc;                                
 69 }                                                 
 70                                                   
 71 /**                                               
 72  * read_policy() - Read handler for "ipe/polic    
 73  * @f: Supplies a file structure representing     
 74  * @data: Supplies a buffer passed to the writ    
 75  * @len: Supplies the length of @data.            
 76  * @offset: unused.                               
 77  *                                                
 78  * @data will be populated with the plain-text    
 79  * on success.                                    
 80  *                                                
 81  * Return:                                        
 82  * * Length of buffer written   - Success         
 83  * * %-ENOENT                   - Policy initi    
 84  */                                               
 85 static ssize_t read_policy(struct file *f, cha    
 86                            size_t len, loff_t     
 87 {                                                 
 88         const struct ipe_policy *p = NULL;        
 89         struct inode *root = NULL;                
 90         int rc = 0;                               
 91                                                   
 92         root = d_inode(f->f_path.dentry->d_par    
 93                                                   
 94         inode_lock_shared(root);                  
 95         p = (struct ipe_policy *)root->i_priva    
 96         if (!p) {                                 
 97                 rc = -ENOENT;                     
 98                 goto out;                         
 99         }                                         
100                                                   
101         rc = simple_read_from_buffer(data, len    
102                                                   
103 out:                                              
104         inode_unlock_shared(root);                
105                                                   
106         return rc;                                
107 }                                                 
108                                                   
109 /**                                               
110  * read_name() - Read handler for "ipe/policie    
111  * @f: Supplies a file structure representing     
112  * @data: Supplies a buffer passed to the writ    
113  * @len: Supplies the length of @data.            
114  * @offset: unused.                               
115  *                                                
116  * @data will be populated with the policy_nam    
117  *                                                
118  * Return:                                        
119  * * Length of buffer written   - Success         
120  * * %-ENOENT                   - Policy initi    
121  */                                               
122 static ssize_t read_name(struct file *f, char     
123                          size_t len, loff_t *o    
124 {                                                 
125         const struct ipe_policy *p = NULL;        
126         struct inode *root = NULL;                
127         int rc = 0;                               
128                                                   
129         root = d_inode(f->f_path.dentry->d_par    
130                                                   
131         inode_lock_shared(root);                  
132         p = (struct ipe_policy *)root->i_priva    
133         if (!p) {                                 
134                 rc = -ENOENT;                     
135                 goto out;                         
136         }                                         
137                                                   
138         rc = simple_read_from_buffer(data, len    
139                                      strlen(p-    
140                                                   
141 out:                                              
142         inode_unlock_shared(root);                
143                                                   
144         return rc;                                
145 }                                                 
146                                                   
147 /**                                               
148  * read_version() - Read handler for "ipe/poli    
149  * @f: Supplies a file structure representing     
150  * @data: Supplies a buffer passed to the writ    
151  * @len: Supplies the length of @data.            
152  * @offset: unused.                               
153  *                                                
154  * @data will be populated with the version st    
155  *                                                
156  * Return:                                        
157  * * Length of buffer written   - Success         
158  * * %-ENOENT                   - Policy initi    
159  */                                               
160 static ssize_t read_version(struct file *f, ch    
161                             size_t len, loff_t    
162 {                                                 
163         char buffer[MAX_VERSION_SIZE] = { 0 };    
164         const struct ipe_policy *p = NULL;        
165         struct inode *root = NULL;                
166         size_t strsize = 0;                       
167         ssize_t rc = 0;                           
168                                                   
169         root = d_inode(f->f_path.dentry->d_par    
170                                                   
171         inode_lock_shared(root);                  
172         p = (struct ipe_policy *)root->i_priva    
173         if (!p) {                                 
174                 rc = -ENOENT;                     
175                 goto out;                         
176         }                                         
177                                                   
178         strsize = scnprintf(buffer, ARRAY_SIZE    
179                             p->parsed->version    
180                             p->parsed->version    
181                                                   
182         rc = simple_read_from_buffer(data, len    
183                                                   
184 out:                                              
185         inode_unlock_shared(root);                
186                                                   
187         return rc;                                
188 }                                                 
189                                                   
190 /**                                               
191  * setactive() - Write handler for "ipe/polici    
192  * @f: Supplies a file structure representing     
193  * @data: Supplies a buffer passed to the writ    
194  * @len: Supplies the length of @data.            
195  * @offset: unused.                               
196  *                                                
197  * Return:                                        
198  * * Length of buffer written   - Success         
199  * * %-EPERM                    - Insufficient    
200  * * %-EINVAL                   - Invalid inpu    
201  * * %-ENOENT                   - Policy initi    
202  */                                               
203 static ssize_t setactive(struct file *f, const    
204                          size_t len, loff_t *o    
205 {                                                 
206         const struct ipe_policy *p = NULL;        
207         struct inode *root = NULL;                
208         bool value = false;                       
209         int rc = 0;                               
210                                                   
211         if (!file_ns_capable(f, &init_user_ns,    
212                 return -EPERM;                    
213                                                   
214         rc = kstrtobool_from_user(data, len, &    
215         if (rc)                                   
216                 return rc;                        
217                                                   
218         if (!value)                               
219                 return -EINVAL;                   
220                                                   
221         root = d_inode(f->f_path.dentry->d_par    
222         inode_lock(root);                         
223                                                   
224         p = (struct ipe_policy *)root->i_priva    
225         if (!p) {                                 
226                 rc = -ENOENT;                     
227                 goto out;                         
228         }                                         
229                                                   
230         rc = ipe_set_active_pol(p);               
231                                                   
232 out:                                              
233         inode_unlock(root);                       
234         return (rc < 0) ? rc : len;               
235 }                                                 
236                                                   
237 /**                                               
238  * getactive() - Read handler for "ipe/policie    
239  * @f: Supplies a file structure representing     
240  * @data: Supplies a buffer passed to the writ    
241  * @len: Supplies the length of @data.            
242  * @offset: unused.                               
243  *                                                
244  * @data will be populated with the 1 or 0 dep    
245  * corresponding policy is active.                
246  *                                                
247  * Return:                                        
248  * * Length of buffer written   - Success         
249  * * %-ENOENT                   - Policy initi    
250  */                                               
251 static ssize_t getactive(struct file *f, char     
252                          size_t len, loff_t *o    
253 {                                                 
254         const struct ipe_policy *p = NULL;        
255         struct inode *root = NULL;                
256         const char *str;                          
257         int rc = 0;                               
258                                                   
259         root = d_inode(f->f_path.dentry->d_par    
260                                                   
261         inode_lock_shared(root);                  
262         p = (struct ipe_policy *)root->i_priva    
263         if (!p) {                                 
264                 inode_unlock_shared(root);        
265                 return -ENOENT;                   
266         }                                         
267         inode_unlock_shared(root);                
268                                                   
269         str = (p == rcu_access_pointer(ipe_act    
270         rc = simple_read_from_buffer(data, len    
271                                                   
272         return rc;                                
273 }                                                 
274                                                   
275 /**                                               
276  * update_policy() - Write handler for "ipe/po    
277  * @f: Supplies a file structure representing     
278  * @data: Supplies a buffer passed to the writ    
279  * @len: Supplies the length of @data.            
280  * @offset: unused.                               
281  *                                                
282  * On success this updates the policy represen    
283  * in-place.                                      
284  *                                                
285  * Return: Length of buffer written on success    
286  * the function will return the -errno.           
287  */                                               
288 static ssize_t update_policy(struct file *f, c    
289                              size_t len, loff_    
290 {                                                 
291         struct inode *root = NULL;                
292         char *copy = NULL;                        
293         int rc = 0;                               
294                                                   
295         if (!file_ns_capable(f, &init_user_ns,    
296                 return -EPERM;                    
297                                                   
298         copy = memdup_user(data, len);            
299         if (IS_ERR(copy))                         
300                 return PTR_ERR(copy);             
301                                                   
302         root = d_inode(f->f_path.dentry->d_par    
303         inode_lock(root);                         
304         rc = ipe_update_policy(root, NULL, 0,     
305         inode_unlock(root);                       
306                                                   
307         kfree(copy);                              
308         if (rc)                                   
309                 return rc;                        
310                                                   
311         return len;                               
312 }                                                 
313                                                   
314 /**                                               
315  * delete_policy() - write handler for  "ipe/p    
316  * @f: Supplies a file structure representing     
317  * @data: Supplies a buffer passed to the writ    
318  * @len: Supplies the length of @data.            
319  * @offset: unused.                               
320  *                                                
321  * On success this deletes the policy represen    
322  *                                                
323  * Return:                                        
324  * * Length of buffer written   - Success         
325  * * %-EPERM                    - Insufficient    
326  * * %-EINVAL                   - Invalid inpu    
327  * * %-ENOENT                   - Policy initi    
328  */                                               
329 static ssize_t delete_policy(struct file *f, c    
330                              size_t len, loff_    
331 {                                                 
332         struct ipe_policy *ap = NULL;             
333         struct ipe_policy *p = NULL;              
334         struct inode *root = NULL;                
335         bool value = false;                       
336         int rc = 0;                               
337                                                   
338         if (!file_ns_capable(f, &init_user_ns,    
339                 return -EPERM;                    
340                                                   
341         rc = kstrtobool_from_user(data, len, &    
342         if (rc)                                   
343                 return rc;                        
344                                                   
345         if (!value)                               
346                 return -EINVAL;                   
347                                                   
348         root = d_inode(f->f_path.dentry->d_par    
349         inode_lock(root);                         
350         p = (struct ipe_policy *)root->i_priva    
351         if (!p) {                                 
352                 inode_unlock(root);               
353                 return -ENOENT;                   
354         }                                         
355                                                   
356         mutex_lock(&ipe_policy_lock);             
357         ap = rcu_dereference_protected(ipe_act    
358                                        lockdep    
359         if (p == ap) {                            
360                 mutex_unlock(&ipe_policy_lock)    
361                 inode_unlock(root);               
362                 return -EPERM;                    
363         }                                         
364         mutex_unlock(&ipe_policy_lock);           
365                                                   
366         root->i_private = NULL;                   
367         inode_unlock(root);                       
368                                                   
369         synchronize_rcu();                        
370         ipe_free_policy(p);                       
371                                                   
372         return len;                               
373 }                                                 
374                                                   
375 static const struct file_operations content_fo    
376         .read = read_policy,                      
377 };                                                
378                                                   
379 static const struct file_operations pkcs7_fops    
380         .read = read_pkcs7,                       
381 };                                                
382                                                   
383 static const struct file_operations name_fops     
384         .read = read_name,                        
385 };                                                
386                                                   
387 static const struct file_operations ver_fops =    
388         .read = read_version,                     
389 };                                                
390                                                   
391 static const struct file_operations active_fop    
392         .write = setactive,                       
393         .read = getactive,                        
394 };                                                
395                                                   
396 static const struct file_operations update_fop    
397         .write = update_policy,                   
398 };                                                
399                                                   
400 static const struct file_operations delete_fop    
401         .write = delete_policy,                   
402 };                                                
403                                                   
404 /**                                               
405  * policy_subdir - files under a policy subdir    
406  */                                               
407 static const struct ipefs_file policy_subdir[]    
408         { "pkcs7", 0444, &pkcs7_fops },           
409         { "policy", 0444, &content_fops },        
410         { "name", 0444, &name_fops },             
411         { "version", 0444, &ver_fops },           
412         { "active", 0600, &active_fops },         
413         { "update", 0200, &update_fops },         
414         { "delete", 0200, &delete_fops },         
415 };                                                
416                                                   
417 /**                                               
418  * ipe_del_policyfs_node() - Delete a security    
419  * @p: Supplies a pointer to the policy to del    
420  */                                               
421 void ipe_del_policyfs_node(struct ipe_policy *    
422 {                                                 
423         securityfs_recursive_remove(p->policyf    
424         p->policyfs = NULL;                       
425 }                                                 
426                                                   
427 /**                                               
428  * ipe_new_policyfs_node() - Create a security    
429  * @p: Supplies a pointer to the policy to cre    
430  *                                                
431  * Return: %0 on success. If an error occurs,     
432  * the -errno.                                    
433  */                                               
434 int ipe_new_policyfs_node(struct ipe_policy *p    
435 {                                                 
436         const struct ipefs_file *f = NULL;        
437         struct dentry *policyfs = NULL;           
438         struct inode *root = NULL;                
439         struct dentry *d = NULL;                  
440         size_t i = 0;                             
441         int rc = 0;                               
442                                                   
443         if (p->policyfs)                          
444                 return 0;                         
445                                                   
446         policyfs = securityfs_create_dir(p->pa    
447         if (IS_ERR(policyfs))                     
448                 return PTR_ERR(policyfs);         
449                                                   
450         root = d_inode(policyfs);                 
451                                                   
452         for (i = 0; i < ARRAY_SIZE(policy_subd    
453                 f = &policy_subdir[i];            
454                                                   
455                 d = securityfs_create_file(f->    
456                                            NUL    
457                 if (IS_ERR(d)) {                  
458                         rc = PTR_ERR(d);          
459                         goto err;                 
460                 }                                 
461         }                                         
462                                                   
463         inode_lock(root);                         
464         p->policyfs = policyfs;                   
465         root->i_private = p;                      
466         inode_unlock(root);                       
467                                                   
468         return 0;                                 
469 err:                                              
470         securityfs_recursive_remove(policyfs);    
471         return rc;                                
472 }                                                 
473                                                   

~ [ 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