1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 4 * 5 * Author: 6 * Casey Schaufler <casey@schaufler-ca.com> 7 */ 8 9 #include <linux/types.h> 10 #include <linux/slab.h> 11 #include <linux/fs.h> 12 #include <linux/sched.h> 13 #include "smack.h" 14 15 struct smack_known smack_known_huh = { 16 .smk_known = "?", 17 .smk_secid = 2, 18 }; 19 20 struct smack_known smack_known_hat = { 21 .smk_known = "^", 22 .smk_secid = 3, 23 }; 24 25 struct smack_known smack_known_star = { 26 .smk_known = "*", 27 .smk_secid = 4, 28 }; 29 30 struct smack_known smack_known_floor = { 31 .smk_known = "_", 32 .smk_secid = 5, 33 }; 34 35 struct smack_known smack_known_web = { 36 .smk_known = "@", 37 .smk_secid = 7, 38 }; 39 40 LIST_HEAD(smack_known_list); 41 42 /* 43 * The initial value needs to be bigger than any of the 44 * known values above. 45 */ 46 static u32 smack_next_secid = 10; 47 48 #ifdef CONFIG_AUDIT 49 /* 50 * what events do we log 51 * can be overwritten at run-time by /smack/logging 52 */ 53 int log_policy = SMACK_AUDIT_DENIED; 54 #endif /* CONFIG_AUDIT */ 55 56 /** 57 * smk_access_entry - look up matching access rule 58 * @subject_label: a pointer to the subject's Smack label 59 * @object_label: a pointer to the object's Smack label 60 * @rule_list: the list of rules to search 61 * 62 * This function looks up the subject/object pair in the 63 * access rule list and returns the access mode. If no 64 * entry is found returns -ENOENT. 65 * 66 * NOTE: 67 * 68 * Earlier versions of this function allowed for labels that 69 * were not on the label list. This was done to allow for 70 * labels to come over the network that had never been seen 71 * before on this host. Unless the receiving socket has the 72 * star label this will always result in a failure check. The 73 * star labeled socket case is now handled in the networking 74 * hooks so there is no case where the label is not on the 75 * label list. Checking to see if the address of two labels 76 * is the same is now a reliable test. 77 * 78 * Do the object check first because that is more 79 * likely to differ. 80 * 81 * Allowing write access implies allowing locking. 82 */ 83 int smk_access_entry(char *subject_label, char *object_label, 84 struct list_head *rule_list) 85 { 86 struct smack_rule *srp; 87 88 list_for_each_entry_rcu(srp, rule_list, list) { 89 if (srp->smk_object->smk_known == object_label && 90 srp->smk_subject->smk_known == subject_label) { 91 int may = srp->smk_access; 92 /* 93 * MAY_WRITE implies MAY_LOCK. 94 */ 95 if ((may & MAY_WRITE) == MAY_WRITE) 96 may |= MAY_LOCK; 97 return may; 98 } 99 } 100 101 return -ENOENT; 102 } 103 104 /** 105 * smk_access - determine if a subject has a specific access to an object 106 * @subject: a pointer to the subject's Smack label entry 107 * @object: a pointer to the object's Smack label entry 108 * @request: the access requested, in "MAY" format 109 * @a : a pointer to the audit data 110 * 111 * This function looks up the subject/object pair in the 112 * access rule list and returns 0 if the access is permitted, 113 * non zero otherwise. 114 * 115 * Smack labels are shared on smack_list 116 */ 117 int smk_access(struct smack_known *subject, struct smack_known *object, 118 int request, struct smk_audit_info *a) 119 { 120 int may = MAY_NOT; 121 int rc = 0; 122 123 /* 124 * Hardcoded comparisons. 125 */ 126 /* 127 * A star subject can't access any object. 128 */ 129 if (subject == &smack_known_star) { 130 rc = -EACCES; 131 goto out_audit; 132 } 133 /* 134 * An internet object can be accessed by any subject. 135 * Tasks cannot be assigned the internet label. 136 * An internet subject can access any object. 137 */ 138 if (object == &smack_known_web || subject == &smack_known_web) 139 goto out_audit; 140 /* 141 * A star object can be accessed by any subject. 142 */ 143 if (object == &smack_known_star) 144 goto out_audit; 145 /* 146 * An object can be accessed in any way by a subject 147 * with the same label. 148 */ 149 if (subject->smk_known == object->smk_known) 150 goto out_audit; 151 /* 152 * A hat subject can read or lock any object. 153 * A floor object can be read or locked by any subject. 154 */ 155 if ((request & MAY_ANYREAD) == request || 156 (request & MAY_LOCK) == request) { 157 if (object == &smack_known_floor) 158 goto out_audit; 159 if (subject == &smack_known_hat) 160 goto out_audit; 161 } 162 /* 163 * Beyond here an explicit relationship is required. 164 * If the requested access is contained in the available 165 * access (e.g. read is included in readwrite) it's 166 * good. A negative response from smk_access_entry() 167 * indicates there is no entry for this pair. 168 */ 169 rcu_read_lock(); 170 may = smk_access_entry(subject->smk_known, object->smk_known, 171 &subject->smk_rules); 172 rcu_read_unlock(); 173 174 if (may <= 0 || (request & may) != request) { 175 rc = -EACCES; 176 goto out_audit; 177 } 178 #ifdef CONFIG_SECURITY_SMACK_BRINGUP 179 /* 180 * Return a positive value if using bringup mode. 181 * This allows the hooks to identify checks that 182 * succeed because of "b" rules. 183 */ 184 if (may & MAY_BRINGUP) 185 rc = SMACK_BRINGUP_ALLOW; 186 #endif 187 188 out_audit: 189 190 #ifdef CONFIG_SECURITY_SMACK_BRINGUP 191 if (rc < 0) { 192 if (object == smack_unconfined) 193 rc = SMACK_UNCONFINED_OBJECT; 194 if (subject == smack_unconfined) 195 rc = SMACK_UNCONFINED_SUBJECT; 196 } 197 #endif 198 199 #ifdef CONFIG_AUDIT 200 if (a) 201 smack_log(subject->smk_known, object->smk_known, 202 request, rc, a); 203 #endif 204 205 return rc; 206 } 207 208 /** 209 * smk_tskacc - determine if a task has a specific access to an object 210 * @tsp: a pointer to the subject's task 211 * @obj_known: a pointer to the object's label entry 212 * @mode: the access requested, in "MAY" format 213 * @a : common audit data 214 * 215 * This function checks the subject task's label/object label pair 216 * in the access rule list and returns 0 if the access is permitted, 217 * non zero otherwise. It allows that the task may have the capability 218 * to override the rules. 219 */ 220 int smk_tskacc(struct task_smack *tsp, struct smack_known *obj_known, 221 u32 mode, struct smk_audit_info *a) 222 { 223 struct smack_known *sbj_known = smk_of_task(tsp); 224 int may; 225 int rc; 226 227 /* 228 * Check the global rule list 229 */ 230 rc = smk_access(sbj_known, obj_known, mode, NULL); 231 if (rc >= 0) { 232 /* 233 * If there is an entry in the task's rule list 234 * it can further restrict access. 235 */ 236 may = smk_access_entry(sbj_known->smk_known, 237 obj_known->smk_known, 238 &tsp->smk_rules); 239 if (may < 0) 240 goto out_audit; 241 if ((mode & may) == mode) 242 goto out_audit; 243 rc = -EACCES; 244 } 245 246 /* 247 * Allow for privileged to override policy. 248 */ 249 if (rc != 0 && smack_privileged(CAP_MAC_OVERRIDE)) 250 rc = 0; 251 252 out_audit: 253 #ifdef CONFIG_AUDIT 254 if (a) 255 smack_log(sbj_known->smk_known, obj_known->smk_known, 256 mode, rc, a); 257 #endif 258 return rc; 259 } 260 261 /** 262 * smk_curacc - determine if current has a specific access to an object 263 * @obj_known: a pointer to the object's Smack label entry 264 * @mode: the access requested, in "MAY" format 265 * @a : common audit data 266 * 267 * This function checks the current subject label/object label pair 268 * in the access rule list and returns 0 if the access is permitted, 269 * non zero otherwise. It allows that current may have the capability 270 * to override the rules. 271 */ 272 int smk_curacc(struct smack_known *obj_known, 273 u32 mode, struct smk_audit_info *a) 274 { 275 struct task_smack *tsp = smack_cred(current_cred()); 276 277 return smk_tskacc(tsp, obj_known, mode, a); 278 } 279 280 /** 281 * smack_str_from_perm : helper to translate an int to a 282 * readable string 283 * @string : the string to fill 284 * @access : the int 285 * 286 */ 287 int smack_str_from_perm(char *string, int access) 288 { 289 int i = 0; 290 291 if (access & MAY_READ) 292 string[i++] = 'r'; 293 if (access & MAY_WRITE) 294 string[i++] = 'w'; 295 if (access & MAY_EXEC) 296 string[i++] = 'x'; 297 if (access & MAY_APPEND) 298 string[i++] = 'a'; 299 if (access & MAY_TRANSMUTE) 300 string[i++] = 't'; 301 if (access & MAY_LOCK) 302 string[i++] = 'l'; 303 if (access & MAY_BRINGUP) 304 string[i++] = 'b'; 305 if (i == 0) 306 string[i++] = '-'; 307 string[i] = '\0'; 308 return i; 309 } 310 311 #ifdef CONFIG_AUDIT 312 /** 313 * smack_log_callback - SMACK specific information 314 * will be called by generic audit code 315 * @ab : the audit_buffer 316 * @a : audit_data 317 * 318 */ 319 static void smack_log_callback(struct audit_buffer *ab, void *a) 320 { 321 struct common_audit_data *ad = a; 322 struct smack_audit_data *sad = ad->smack_audit_data; 323 audit_log_format(ab, "lsm=SMACK fn=%s action=%s", 324 ad->smack_audit_data->function, 325 sad->result ? "denied" : "granted"); 326 audit_log_format(ab, " subject="); 327 audit_log_untrustedstring(ab, sad->subject); 328 audit_log_format(ab, " object="); 329 audit_log_untrustedstring(ab, sad->object); 330 if (sad->request[0] == '\0') 331 audit_log_format(ab, " labels_differ"); 332 else 333 audit_log_format(ab, " requested=%s", sad->request); 334 } 335 336 /** 337 * smack_log - Audit the granting or denial of permissions. 338 * @subject_label : smack label of the requester 339 * @object_label : smack label of the object being accessed 340 * @request: requested permissions 341 * @result: result from smk_access 342 * @ad: auxiliary audit data 343 * 344 * Audit the granting or denial of permissions in accordance 345 * with the policy. 346 */ 347 void smack_log(char *subject_label, char *object_label, int request, 348 int result, struct smk_audit_info *ad) 349 { 350 #ifdef CONFIG_SECURITY_SMACK_BRINGUP 351 char request_buffer[SMK_NUM_ACCESS_TYPE + 5]; 352 #else 353 char request_buffer[SMK_NUM_ACCESS_TYPE + 1]; 354 #endif 355 struct smack_audit_data *sad; 356 struct common_audit_data *a = &ad->a; 357 358 /* check if we have to log the current event */ 359 if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) 360 return; 361 if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) 362 return; 363 364 sad = a->smack_audit_data; 365 366 if (sad->function == NULL) 367 sad->function = "unknown"; 368 369 /* end preparing the audit data */ 370 smack_str_from_perm(request_buffer, request); 371 sad->subject = subject_label; 372 sad->object = object_label; 373 #ifdef CONFIG_SECURITY_SMACK_BRINGUP 374 /* 375 * The result may be positive in bringup mode. 376 * A positive result is an allow, but not for normal reasons. 377 * Mark it as successful, but don't filter it out even if 378 * the logging policy says to do so. 379 */ 380 if (result == SMACK_UNCONFINED_SUBJECT) 381 strcat(request_buffer, "(US)"); 382 else if (result == SMACK_UNCONFINED_OBJECT) 383 strcat(request_buffer, "(UO)"); 384 385 if (result > 0) 386 result = 0; 387 #endif 388 sad->request = request_buffer; 389 sad->result = result; 390 391 common_lsm_audit(a, smack_log_callback, NULL); 392 } 393 #else /* #ifdef CONFIG_AUDIT */ 394 void smack_log(char *subject_label, char *object_label, int request, 395 int result, struct smk_audit_info *ad) 396 { 397 } 398 #endif 399 400 DEFINE_MUTEX(smack_known_lock); 401 402 struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; 403 404 /** 405 * smk_insert_entry - insert a smack label into a hash map, 406 * @skp: smack label 407 * 408 * this function must be called under smack_known_lock 409 */ 410 void smk_insert_entry(struct smack_known *skp) 411 { 412 unsigned int hash; 413 struct hlist_head *head; 414 415 hash = full_name_hash(NULL, skp->smk_known, strlen(skp->smk_known)); 416 head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)]; 417 418 hlist_add_head_rcu(&skp->smk_hashed, head); 419 list_add_rcu(&skp->list, &smack_known_list); 420 } 421 422 /** 423 * smk_find_entry - find a label on the list, return the list entry 424 * @string: a text string that might be a Smack label 425 * 426 * Returns a pointer to the entry in the label list that 427 * matches the passed string or NULL if not found. 428 */ 429 struct smack_known *smk_find_entry(const char *string) 430 { 431 unsigned int hash; 432 struct hlist_head *head; 433 struct smack_known *skp; 434 435 hash = full_name_hash(NULL, string, strlen(string)); 436 head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)]; 437 438 hlist_for_each_entry_rcu(skp, head, smk_hashed) 439 if (strcmp(skp->smk_known, string) == 0) 440 return skp; 441 442 return NULL; 443 } 444 445 /** 446 * smk_parse_label_len - calculate the length of the starting segment 447 * in the string that constitutes a valid smack label 448 * @string: a text string that might contain a Smack label at the beginning 449 * @len: the maximum size to look into, may be zero if string is null-terminated 450 * 451 * Returns the length of the segment (0 < L < SMK_LONGLABEL) or an error code. 452 */ 453 int smk_parse_label_len(const char *string, int len) 454 { 455 int i; 456 457 if (len <= 0 || len > SMK_LONGLABEL) 458 len = SMK_LONGLABEL; 459 460 /* 461 * Reserve a leading '-' as an indicator that 462 * this isn't a label, but an option to interfaces 463 * including /smack/cipso and /smack/cipso2 464 */ 465 if (string[0] == '-') 466 return -EINVAL; 467 468 for (i = 0; i < len; i++) 469 if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || 470 string[i] == '"' || string[i] == '\\' || string[i] == '\'') 471 break; 472 473 if (i == 0 || i >= SMK_LONGLABEL) 474 return -EINVAL; 475 476 return i; 477 } 478 479 /** 480 * smk_parse_smack - copy the starting segment in the string 481 * that constitutes a valid smack label 482 * @string: a text string that might contain a Smack label at the beginning 483 * @len: the maximum size to look into, may be zero if string is null-terminated 484 * 485 * Returns a pointer to the copy of the label or an error code. 486 */ 487 char *smk_parse_smack(const char *string, int len) 488 { 489 char *smack; 490 int i = smk_parse_label_len(string, len); 491 492 if (i < 0) 493 return ERR_PTR(-EINVAL); 494 495 smack = kstrndup(string, i, GFP_NOFS); 496 if (!smack) 497 return ERR_PTR(-ENOMEM); 498 return smack; 499 } 500 501 /** 502 * smk_netlbl_mls - convert a catset to netlabel mls categories 503 * @level: MLS sensitivity level 504 * @catset: the Smack categories 505 * @sap: where to put the netlabel categories 506 * @len: number of bytes for the levels in a CIPSO IP option 507 * 508 * Allocates and fills attr.mls 509 * Returns 0 on success, error code on failure. 510 */ 511 int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap, 512 int len) 513 { 514 unsigned char *cp; 515 unsigned char m; 516 int cat; 517 int rc; 518 int byte; 519 520 sap->flags |= NETLBL_SECATTR_MLS_CAT; 521 sap->attr.mls.lvl = level; 522 sap->attr.mls.cat = NULL; 523 524 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 525 for (m = 0x80; m != 0; m >>= 1, cat++) { 526 if ((m & *cp) == 0) 527 continue; 528 rc = netlbl_catmap_setbit(&sap->attr.mls.cat, 529 cat, GFP_NOFS); 530 if (rc < 0) { 531 netlbl_catmap_free(sap->attr.mls.cat); 532 return rc; 533 } 534 } 535 536 return 0; 537 } 538 539 /** 540 * smack_populate_secattr - fill in the smack_known netlabel information 541 * @skp: pointer to the structure to fill 542 * 543 * Populate the netlabel secattr structure for a Smack label. 544 * 545 * Returns 0 unless creating the category mapping fails 546 */ 547 int smack_populate_secattr(struct smack_known *skp) 548 { 549 int slen; 550 551 skp->smk_netlabel.attr.secid = skp->smk_secid; 552 skp->smk_netlabel.domain = skp->smk_known; 553 skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); 554 if (skp->smk_netlabel.cache != NULL) { 555 skp->smk_netlabel.flags |= NETLBL_SECATTR_CACHE; 556 skp->smk_netlabel.cache->free = NULL; 557 skp->smk_netlabel.cache->data = skp; 558 } 559 skp->smk_netlabel.flags |= NETLBL_SECATTR_SECID | 560 NETLBL_SECATTR_MLS_LVL | 561 NETLBL_SECATTR_DOMAIN; 562 /* 563 * If direct labeling works use it. 564 * Otherwise use mapped labeling. 565 */ 566 slen = strlen(skp->smk_known); 567 if (slen < SMK_CIPSOLEN) 568 return smk_netlbl_mls(smack_cipso_direct, skp->smk_known, 569 &skp->smk_netlabel, slen); 570 571 return smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid, 572 &skp->smk_netlabel, sizeof(skp->smk_secid)); 573 } 574 575 /** 576 * smk_import_valid_allocated_label - import a label, return the list entry 577 * @smack: a text string that is a valid Smack label and may be kfree()ed. 578 * It is consumed: either becomes a part of the entry or kfree'ed. 579 * @gfp: Allocation type 580 * 581 * Returns: see description of smk_import_entry() 582 */ 583 static struct smack_known * 584 smk_import_allocated_label(char *smack, gfp_t gfp) 585 { 586 struct smack_known *skp; 587 int rc; 588 589 mutex_lock(&smack_known_lock); 590 591 skp = smk_find_entry(smack); 592 if (skp != NULL) 593 goto freeout; 594 595 skp = kzalloc(sizeof(*skp), gfp); 596 if (skp == NULL) { 597 skp = ERR_PTR(-ENOMEM); 598 goto freeout; 599 } 600 601 skp->smk_known = smack; 602 skp->smk_secid = smack_next_secid++; 603 604 rc = smack_populate_secattr(skp); 605 if (rc >= 0) { 606 INIT_LIST_HEAD(&skp->smk_rules); 607 mutex_init(&skp->smk_rules_lock); 608 /* 609 * Make sure that the entry is actually 610 * filled before putting it on the list. 611 */ 612 smk_insert_entry(skp); 613 goto unlockout; 614 } 615 kfree(skp); 616 skp = ERR_PTR(rc); 617 freeout: 618 kfree(smack); 619 unlockout: 620 mutex_unlock(&smack_known_lock); 621 622 return skp; 623 } 624 625 /** 626 * smk_import_entry - import a label, return the list entry 627 * @string: a text string that might contain a Smack label at the beginning 628 * @len: the maximum size to look into, may be zero if string is null-terminated 629 * 630 * Returns a pointer to the entry in the label list that 631 * matches the passed string, adding it if necessary, 632 * or an error code. 633 */ 634 struct smack_known *smk_import_entry(const char *string, int len) 635 { 636 char *smack = smk_parse_smack(string, len); 637 638 if (IS_ERR(smack)) 639 return ERR_CAST(smack); 640 641 return smk_import_allocated_label(smack, GFP_NOFS); 642 } 643 644 /** 645 * smk_import_valid_label - import a label, return the list entry 646 * @label: a text string that is a valid Smack label, not null-terminated 647 * @label_len: the length of the text string in the @label 648 * @gfp: the GFP mask used for allocating memory for the @label text string copy 649 * 650 * Return: see description of smk_import_entry() 651 */ 652 struct smack_known * 653 smk_import_valid_label(const char *label, int label_len, gfp_t gfp) 654 { 655 char *smack = kstrndup(label, label_len, gfp); 656 657 if (!smack) 658 return ERR_PTR(-ENOMEM); 659 660 return smk_import_allocated_label(smack, gfp); 661 } 662 663 /** 664 * smack_from_secid - find the Smack label associated with a secid 665 * @secid: an integer that might be associated with a Smack label 666 * 667 * Returns a pointer to the appropriate Smack label entry if there is one, 668 * otherwise a pointer to the invalid Smack label. 669 */ 670 struct smack_known *smack_from_secid(const u32 secid) 671 { 672 struct smack_known *skp; 673 674 rcu_read_lock(); 675 list_for_each_entry_rcu(skp, &smack_known_list, list) { 676 if (skp->smk_secid == secid) { 677 rcu_read_unlock(); 678 return skp; 679 } 680 } 681 682 /* 683 * If we got this far someone asked for the translation 684 * of a secid that is not on the list. 685 */ 686 rcu_read_unlock(); 687 return &smack_known_huh; 688 } 689 690 /* 691 * Unless a process is running with one of these labels 692 * even having CAP_MAC_OVERRIDE isn't enough to grant 693 * privilege to violate MAC policy. If no labels are 694 * designated (the empty list case) capabilities apply to 695 * everyone. 696 */ 697 LIST_HEAD(smack_onlycap_list); 698 DEFINE_MUTEX(smack_onlycap_lock); 699 700 /** 701 * smack_privileged_cred - are all privilege requirements met by cred 702 * @cap: The requested capability 703 * @cred: the credential to use 704 * 705 * Is the task privileged and allowed to be privileged 706 * by the onlycap rule. 707 * 708 * Returns true if the task is allowed to be privileged, false if it's not. 709 */ 710 bool smack_privileged_cred(int cap, const struct cred *cred) 711 { 712 struct task_smack *tsp = smack_cred(cred); 713 struct smack_known *skp = tsp->smk_task; 714 struct smack_known_list_elem *sklep; 715 int rc; 716 717 rc = cap_capable(cred, &init_user_ns, cap, CAP_OPT_NONE); 718 if (rc) 719 return false; 720 721 rcu_read_lock(); 722 if (list_empty(&smack_onlycap_list)) { 723 rcu_read_unlock(); 724 return true; 725 } 726 727 list_for_each_entry_rcu(sklep, &smack_onlycap_list, list) { 728 if (sklep->smk_label == skp) { 729 rcu_read_unlock(); 730 return true; 731 } 732 } 733 rcu_read_unlock(); 734 735 return false; 736 } 737 738 /** 739 * smack_privileged - are all privilege requirements met 740 * @cap: The requested capability 741 * 742 * Is the task privileged and allowed to be privileged 743 * by the onlycap rule. 744 * 745 * Returns true if the task is allowed to be privileged, false if it's not. 746 */ 747 bool smack_privileged(int cap) 748 { 749 /* 750 * All kernel tasks are privileged 751 */ 752 if (unlikely(current->flags & PF_KTHREAD)) 753 return true; 754 755 return smack_privileged_cred(cap, current_cred()); 756 } 757