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