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 if (sad->subj_tsk) { 336 char comm[TASK_COMM_LEN]; 337 338 audit_log_format(ab, " subj_pid=%d subj_comm=", 339 task_tgid_nr(sad->subj_tsk)); 340 audit_log_untrustedstring(ab, 341 get_task_comm(comm, sad->subj_tsk)); 342 } 343 } 344 345 /** 346 * smack_log - Audit the granting or denial of permissions. 347 * @subject_label : smack label of the requester 348 * @object_label : smack label of the object being accessed 349 * @request: requested permissions 350 * @result: result from smk_access 351 * @ad: auxiliary audit data 352 * 353 * Audit the granting or denial of permissions in accordance 354 * with the policy. 355 */ 356 void smack_log(char *subject_label, char *object_label, int request, 357 int result, struct smk_audit_info *ad) 358 { 359 #ifdef CONFIG_SECURITY_SMACK_BRINGUP 360 char request_buffer[SMK_NUM_ACCESS_TYPE + 5]; 361 #else 362 char request_buffer[SMK_NUM_ACCESS_TYPE + 1]; 363 #endif 364 struct smack_audit_data *sad; 365 struct common_audit_data *a = &ad->a; 366 367 /* check if we have to log the current event */ 368 if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0) 369 return; 370 if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) 371 return; 372 373 sad = a->smack_audit_data; 374 375 if (sad->function == NULL) 376 sad->function = "unknown"; 377 378 /* end preparing the audit data */ 379 smack_str_from_perm(request_buffer, request); 380 sad->subject = subject_label; 381 sad->object = object_label; 382 #ifdef CONFIG_SECURITY_SMACK_BRINGUP 383 /* 384 * The result may be positive in bringup mode. 385 * A positive result is an allow, but not for normal reasons. 386 * Mark it as successful, but don't filter it out even if 387 * the logging policy says to do so. 388 */ 389 if (result == SMACK_UNCONFINED_SUBJECT) 390 strcat(request_buffer, "(US)"); 391 else if (result == SMACK_UNCONFINED_OBJECT) 392 strcat(request_buffer, "(UO)"); 393 394 if (result > 0) 395 result = 0; 396 #endif 397 sad->request = request_buffer; 398 sad->result = result; 399 400 common_lsm_audit(a, smack_log_callback, NULL); 401 } 402 #else /* #ifdef CONFIG_AUDIT */ 403 void smack_log(char *subject_label, char *object_label, int request, 404 int result, struct smk_audit_info *ad) 405 { 406 } 407 #endif 408 409 DEFINE_MUTEX(smack_known_lock); 410 411 struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; 412 413 /** 414 * smk_insert_entry - insert a smack label into a hash map, 415 * @skp: smack label 416 * 417 * this function must be called under smack_known_lock 418 */ 419 void smk_insert_entry(struct smack_known *skp) 420 { 421 unsigned int hash; 422 struct hlist_head *head; 423 424 hash = full_name_hash(NULL, skp->smk_known, strlen(skp->smk_known)); 425 head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)]; 426 427 hlist_add_head_rcu(&skp->smk_hashed, head); 428 list_add_rcu(&skp->list, &smack_known_list); 429 } 430 431 /** 432 * smk_find_entry - find a label on the list, return the list entry 433 * @string: a text string that might be a Smack label 434 * 435 * Returns a pointer to the entry in the label list that 436 * matches the passed string or NULL if not found. 437 */ 438 struct smack_known *smk_find_entry(const char *string) 439 { 440 unsigned int hash; 441 struct hlist_head *head; 442 struct smack_known *skp; 443 444 hash = full_name_hash(NULL, string, strlen(string)); 445 head = &smack_known_hash[hash & (SMACK_HASH_SLOTS - 1)]; 446 447 hlist_for_each_entry_rcu(skp, head, smk_hashed) 448 if (strcmp(skp->smk_known, string) == 0) 449 return skp; 450 451 return NULL; 452 } 453 454 /** 455 * smk_parse_label_len - calculate the length of the starting segment 456 * in the string that constitutes a valid smack label 457 * @string: a text string that might contain a Smack label at the beginning 458 * @len: the maximum size to look into, may be zero if string is null-terminated 459 * 460 * Returns the length of the segment (0 < L < SMK_LONGLABEL) or an error code. 461 */ 462 int smk_parse_label_len(const char *string, int len) 463 { 464 int i; 465 466 if (len <= 0 || len > SMK_LONGLABEL) 467 len = SMK_LONGLABEL; 468 469 /* 470 * Reserve a leading '-' as an indicator that 471 * this isn't a label, but an option to interfaces 472 * including /smack/cipso and /smack/cipso2 473 */ 474 if (string[0] == '-') 475 return -EINVAL; 476 477 for (i = 0; i < len; i++) 478 if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || 479 string[i] == '"' || string[i] == '\\' || string[i] == '\'') 480 break; 481 482 if (i == 0 || i >= SMK_LONGLABEL) 483 return -EINVAL; 484 485 return i; 486 } 487 488 /** 489 * smk_parse_smack - copy the starting segment in the string 490 * that constitutes a valid smack label 491 * @string: a text string that might contain a Smack label at the beginning 492 * @len: the maximum size to look into, may be zero if string is null-terminated 493 * 494 * Returns a pointer to the copy of the label or an error code. 495 */ 496 char *smk_parse_smack(const char *string, int len) 497 { 498 char *smack; 499 int i = smk_parse_label_len(string, len); 500 501 if (i < 0) 502 return ERR_PTR(-EINVAL); 503 504 smack = kstrndup(string, i, GFP_NOFS); 505 if (!smack) 506 return ERR_PTR(-ENOMEM); 507 return smack; 508 } 509 510 /** 511 * smk_netlbl_mls - convert a catset to netlabel mls categories 512 * @level: MLS sensitivity level 513 * @catset: the Smack categories 514 * @sap: where to put the netlabel categories 515 * @len: number of bytes for the levels in a CIPSO IP option 516 * 517 * Allocates and fills attr.mls 518 * Returns 0 on success, error code on failure. 519 */ 520 int smk_netlbl_mls(int level, char *catset, struct netlbl_lsm_secattr *sap, 521 int len) 522 { 523 unsigned char *cp; 524 unsigned char m; 525 int cat; 526 int rc; 527 int byte; 528 529 sap->flags |= NETLBL_SECATTR_MLS_CAT; 530 sap->attr.mls.lvl = level; 531 sap->attr.mls.cat = NULL; 532 533 for (cat = 1, cp = catset, byte = 0; byte < len; cp++, byte++) 534 for (m = 0x80; m != 0; m >>= 1, cat++) { 535 if ((m & *cp) == 0) 536 continue; 537 rc = netlbl_catmap_setbit(&sap->attr.mls.cat, 538 cat, GFP_NOFS); 539 if (rc < 0) { 540 netlbl_catmap_free(sap->attr.mls.cat); 541 return rc; 542 } 543 } 544 545 return 0; 546 } 547 548 /** 549 * smack_populate_secattr - fill in the smack_known netlabel information 550 * @skp: pointer to the structure to fill 551 * 552 * Populate the netlabel secattr structure for a Smack label. 553 * 554 * Returns 0 unless creating the category mapping fails 555 */ 556 int smack_populate_secattr(struct smack_known *skp) 557 { 558 int slen; 559 560 skp->smk_netlabel.attr.secid = skp->smk_secid; 561 skp->smk_netlabel.domain = skp->smk_known; 562 skp->smk_netlabel.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); 563 if (skp->smk_netlabel.cache != NULL) { 564 skp->smk_netlabel.flags |= NETLBL_SECATTR_CACHE; 565 skp->smk_netlabel.cache->free = NULL; 566 skp->smk_netlabel.cache->data = skp; 567 } 568 skp->smk_netlabel.flags |= NETLBL_SECATTR_SECID | 569 NETLBL_SECATTR_MLS_LVL | 570 NETLBL_SECATTR_DOMAIN; 571 /* 572 * If direct labeling works use it. 573 * Otherwise use mapped labeling. 574 */ 575 slen = strlen(skp->smk_known); 576 if (slen < SMK_CIPSOLEN) 577 return smk_netlbl_mls(smack_cipso_direct, skp->smk_known, 578 &skp->smk_netlabel, slen); 579 580 return smk_netlbl_mls(smack_cipso_mapped, (char *)&skp->smk_secid, 581 &skp->smk_netlabel, sizeof(skp->smk_secid)); 582 } 583 584 /** 585 * smk_import_valid_allocated_label - import a label, return the list entry 586 * @smack: a text string that is a valid Smack label and may be kfree()ed. 587 * It is consumed: either becomes a part of the entry or kfree'ed. 588 * @gfp: Allocation type 589 * 590 * Returns: see description of smk_import_entry() 591 */ 592 static struct smack_known * 593 smk_import_allocated_label(char *smack, gfp_t gfp) 594 { 595 struct smack_known *skp; 596 int rc; 597 598 mutex_lock(&smack_known_lock); 599 600 skp = smk_find_entry(smack); 601 if (skp != NULL) 602 goto freeout; 603 604 skp = kzalloc_obj(*skp, gfp); 605 if (skp == NULL) { 606 skp = ERR_PTR(-ENOMEM); 607 goto freeout; 608 } 609 610 skp->smk_known = smack; 611 skp->smk_secid = smack_next_secid++; 612 613 rc = smack_populate_secattr(skp); 614 if (rc >= 0) { 615 INIT_LIST_HEAD(&skp->smk_rules); 616 mutex_init(&skp->smk_rules_lock); 617 /* 618 * Make sure that the entry is actually 619 * filled before putting it on the list. 620 */ 621 smk_insert_entry(skp); 622 goto unlockout; 623 } 624 kfree(skp); 625 skp = ERR_PTR(rc); 626 freeout: 627 kfree(smack); 628 unlockout: 629 mutex_unlock(&smack_known_lock); 630 631 return skp; 632 } 633 634 /** 635 * smk_import_entry - import a label, return the list entry 636 * @string: a text string that might contain a Smack label at the beginning 637 * @len: the maximum size to look into, may be zero if string is null-terminated 638 * 639 * Returns a pointer to the entry in the label list that 640 * matches the passed string, adding it if necessary, 641 * or an error code. 642 */ 643 struct smack_known *smk_import_entry(const char *string, int len) 644 { 645 char *smack = smk_parse_smack(string, len); 646 647 if (IS_ERR(smack)) 648 return ERR_CAST(smack); 649 650 return smk_import_allocated_label(smack, GFP_NOFS); 651 } 652 653 /** 654 * smk_import_valid_label - import a label, return the list entry 655 * @label: a text string that is a valid Smack label, not null-terminated 656 * @label_len: the length of the text string in the @label 657 * @gfp: the GFP mask used for allocating memory for the @label text string copy 658 * 659 * Return: see description of smk_import_entry() 660 */ 661 struct smack_known * 662 smk_import_valid_label(const char *label, int label_len, gfp_t gfp) 663 { 664 char *smack = kstrndup(label, label_len, gfp); 665 666 if (!smack) 667 return ERR_PTR(-ENOMEM); 668 669 return smk_import_allocated_label(smack, gfp); 670 } 671 672 /** 673 * smack_from_secid - find the Smack label associated with a secid 674 * @secid: an integer that might be associated with a Smack label 675 * 676 * Returns a pointer to the appropriate Smack label entry if there is one, 677 * otherwise a pointer to the invalid Smack label. 678 */ 679 struct smack_known *smack_from_secid(const u32 secid) 680 { 681 struct smack_known *skp; 682 683 rcu_read_lock(); 684 list_for_each_entry_rcu(skp, &smack_known_list, list) { 685 if (skp->smk_secid == secid) { 686 rcu_read_unlock(); 687 return skp; 688 } 689 } 690 691 /* 692 * If we got this far someone asked for the translation 693 * of a secid that is not on the list. 694 */ 695 rcu_read_unlock(); 696 return &smack_known_huh; 697 } 698 699 /* 700 * Unless a process is running with one of these labels 701 * even having CAP_MAC_OVERRIDE isn't enough to grant 702 * privilege to violate MAC policy. If no labels are 703 * designated (the empty list case) capabilities apply to 704 * everyone. 705 */ 706 LIST_HEAD(smack_onlycap_list); 707 DEFINE_MUTEX(smack_onlycap_lock); 708 709 /** 710 * smack_privileged_cred - are all privilege requirements met by cred 711 * @cap: The requested capability 712 * @cred: the credential to use 713 * 714 * Is the task privileged and allowed to be privileged 715 * by the onlycap rule. 716 * 717 * Returns true if the task is allowed to be privileged, false if it's not. 718 */ 719 bool smack_privileged_cred(int cap, const struct cred *cred) 720 { 721 struct task_smack *tsp = smack_cred(cred); 722 struct smack_known *skp = tsp->smk_task; 723 struct smack_known_list_elem *sklep; 724 int rc; 725 726 rc = cap_capable(cred, &init_user_ns, cap, CAP_OPT_NONE); 727 if (rc) 728 return false; 729 730 rcu_read_lock(); 731 if (list_empty(&smack_onlycap_list)) { 732 rcu_read_unlock(); 733 return true; 734 } 735 736 list_for_each_entry_rcu(sklep, &smack_onlycap_list, list) { 737 if (sklep->smk_label == skp) { 738 rcu_read_unlock(); 739 return true; 740 } 741 } 742 rcu_read_unlock(); 743 744 return false; 745 } 746 747 /** 748 * smack_privileged - are all privilege requirements met 749 * @cap: The requested capability 750 * 751 * Is the task privileged and allowed to be privileged 752 * by the onlycap rule. 753 * 754 * Returns true if the task is allowed to be privileged, false if it's not. 755 */ 756 bool smack_privileged(int cap) 757 { 758 /* 759 * All kernel tasks are privileged 760 */ 761 if (unlikely(current->flags & PF_KTHREAD)) 762 return true; 763 764 return smack_privileged_cred(cap, current_cred()); 765 } 766