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