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