1 /* 2 * Copyright (C) 2007 Casey Schaufler <casey@schaufler-ca.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, version 2. 7 * 8 * Authors: 9 * Casey Schaufler <casey@schaufler-ca.com> 10 * Ahmed S. Darwish <darwish.07@gmail.com> 11 * 12 * Special thanks to the authors of selinuxfs. 13 * 14 * Karl MacMillan <kmacmillan@tresys.com> 15 * James Morris <jmorris@redhat.com> 16 * 17 */ 18 19 #include <linux/kernel.h> 20 #include <linux/vmalloc.h> 21 #include <linux/security.h> 22 #include <linux/mutex.h> 23 #include <net/netlabel.h> 24 #include <net/cipso_ipv4.h> 25 #include <linux/seq_file.h> 26 #include <linux/ctype.h> 27 #include "smack.h" 28 29 /* 30 * smackfs pseudo filesystem. 31 */ 32 33 enum smk_inos { 34 SMK_ROOT_INO = 2, 35 SMK_LOAD = 3, /* load policy */ 36 SMK_CIPSO = 4, /* load label -> CIPSO mapping */ 37 SMK_DOI = 5, /* CIPSO DOI */ 38 SMK_DIRECT = 6, /* CIPSO level indicating direct label */ 39 SMK_AMBIENT = 7, /* internet ambient label */ 40 SMK_NLTYPE = 8, /* label scheme to use by default */ 41 }; 42 43 /* 44 * List locks 45 */ 46 static DEFINE_MUTEX(smack_list_lock); 47 static DEFINE_MUTEX(smack_cipso_lock); 48 49 /* 50 * This is the "ambient" label for network traffic. 51 * If it isn't somehow marked, use this. 52 * It can be reset via smackfs/ambient 53 */ 54 char *smack_net_ambient = smack_known_floor.smk_known; 55 56 /* 57 * This is the default packet marking scheme for network traffic. 58 * It can be reset via smackfs/nltype 59 */ 60 int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4; 61 62 /* 63 * This is the level in a CIPSO header that indicates a 64 * smack label is contained directly in the category set. 65 * It can be reset via smackfs/direct 66 */ 67 int smack_cipso_direct = SMACK_CIPSO_DIRECT_DEFAULT; 68 69 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 70 struct smk_list_entry *smack_list; 71 72 #define SEQ_READ_FINISHED 1 73 74 /* 75 * Disable concurrent writing open() operations 76 */ 77 static struct semaphore smack_write_sem; 78 79 /* 80 * Values for parsing cipso rules 81 * SMK_DIGITLEN: Length of a digit field in a rule. 82 * SMK_CIPSOMEN: Minimum possible cipso rule length. 83 */ 84 #define SMK_DIGITLEN 4 85 #define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN) 86 87 /* 88 * Seq_file read operations for /smack/load 89 */ 90 91 static void *load_seq_start(struct seq_file *s, loff_t *pos) 92 { 93 if (*pos == SEQ_READ_FINISHED) 94 return NULL; 95 96 return smack_list; 97 } 98 99 static void *load_seq_next(struct seq_file *s, void *v, loff_t *pos) 100 { 101 struct smk_list_entry *skp = ((struct smk_list_entry *) v)->smk_next; 102 103 if (skp == NULL) 104 *pos = SEQ_READ_FINISHED; 105 106 return skp; 107 } 108 109 static int load_seq_show(struct seq_file *s, void *v) 110 { 111 struct smk_list_entry *slp = (struct smk_list_entry *) v; 112 struct smack_rule *srp = &slp->smk_rule; 113 114 seq_printf(s, "%s %s", (char *)srp->smk_subject, 115 (char *)srp->smk_object); 116 117 seq_putc(s, ' '); 118 119 if (srp->smk_access & MAY_READ) 120 seq_putc(s, 'r'); 121 if (srp->smk_access & MAY_WRITE) 122 seq_putc(s, 'w'); 123 if (srp->smk_access & MAY_EXEC) 124 seq_putc(s, 'x'); 125 if (srp->smk_access & MAY_APPEND) 126 seq_putc(s, 'a'); 127 if (srp->smk_access == 0) 128 seq_putc(s, '-'); 129 130 seq_putc(s, '\n'); 131 132 return 0; 133 } 134 135 static void load_seq_stop(struct seq_file *s, void *v) 136 { 137 /* No-op */ 138 } 139 140 static struct seq_operations load_seq_ops = { 141 .start = load_seq_start, 142 .next = load_seq_next, 143 .show = load_seq_show, 144 .stop = load_seq_stop, 145 }; 146 147 /** 148 * smk_open_load - open() for /smack/load 149 * @inode: inode structure representing file 150 * @file: "load" file pointer 151 * 152 * For reading, use load_seq_* seq_file reading operations. 153 */ 154 static int smk_open_load(struct inode *inode, struct file *file) 155 { 156 if ((file->f_flags & O_ACCMODE) == O_RDONLY) 157 return seq_open(file, &load_seq_ops); 158 159 if (down_interruptible(&smack_write_sem)) 160 return -ERESTARTSYS; 161 162 return 0; 163 } 164 165 /** 166 * smk_release_load - release() for /smack/load 167 * @inode: inode structure representing file 168 * @file: "load" file pointer 169 * 170 * For a reading session, use the seq_file release 171 * implementation. 172 * Otherwise, we are at the end of a writing session so 173 * clean everything up. 174 */ 175 static int smk_release_load(struct inode *inode, struct file *file) 176 { 177 if ((file->f_flags & O_ACCMODE) == O_RDONLY) 178 return seq_release(inode, file); 179 180 up(&smack_write_sem); 181 return 0; 182 } 183 184 /** 185 * smk_set_access - add a rule to the rule list 186 * @srp: the new rule to add 187 * 188 * Looks through the current subject/object/access list for 189 * the subject/object pair and replaces the access that was 190 * there. If the pair isn't found add it with the specified 191 * access. 192 */ 193 static void smk_set_access(struct smack_rule *srp) 194 { 195 struct smk_list_entry *sp; 196 struct smk_list_entry *newp; 197 198 mutex_lock(&smack_list_lock); 199 200 for (sp = smack_list; sp != NULL; sp = sp->smk_next) 201 if (sp->smk_rule.smk_subject == srp->smk_subject && 202 sp->smk_rule.smk_object == srp->smk_object) { 203 sp->smk_rule.smk_access = srp->smk_access; 204 break; 205 } 206 207 if (sp == NULL) { 208 newp = kzalloc(sizeof(struct smk_list_entry), GFP_KERNEL); 209 newp->smk_rule = *srp; 210 newp->smk_next = smack_list; 211 smack_list = newp; 212 } 213 214 mutex_unlock(&smack_list_lock); 215 216 return; 217 } 218 219 /** 220 * smk_write_load - write() for /smack/load 221 * @filp: file pointer, not actually used 222 * @buf: where to get the data from 223 * @count: bytes sent 224 * @ppos: where to start - must be 0 225 * 226 * Get one smack access rule from above. 227 * The format is exactly: 228 * char subject[SMK_LABELLEN] 229 * char object[SMK_LABELLEN] 230 * char access[SMK_ACCESSKINDS] 231 * 232 * Anything following is commentary and ignored. 233 * 234 * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes. 235 */ 236 #define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS) 237 238 static ssize_t smk_write_load(struct file *file, const char __user *buf, 239 size_t count, loff_t *ppos) 240 { 241 struct smack_rule rule; 242 char *data; 243 int rc = -EINVAL; 244 245 /* 246 * Must have privilege. 247 * No partial writes. 248 * Enough data must be present. 249 */ 250 if (!capable(CAP_MAC_ADMIN)) 251 return -EPERM; 252 if (*ppos != 0) 253 return -EINVAL; 254 if (count < MINIMUM_LOAD) 255 return -EINVAL; 256 257 data = kzalloc(count, GFP_KERNEL); 258 if (data == NULL) 259 return -ENOMEM; 260 261 if (copy_from_user(data, buf, count) != 0) { 262 rc = -EFAULT; 263 goto out; 264 } 265 266 rule.smk_subject = smk_import(data, 0); 267 if (rule.smk_subject == NULL) 268 goto out; 269 270 rule.smk_object = smk_import(data + SMK_LABELLEN, 0); 271 if (rule.smk_object == NULL) 272 goto out; 273 274 rule.smk_access = 0; 275 276 switch (data[SMK_LABELLEN + SMK_LABELLEN]) { 277 case '-': 278 break; 279 case 'r': 280 case 'R': 281 rule.smk_access |= MAY_READ; 282 break; 283 default: 284 goto out; 285 } 286 287 switch (data[SMK_LABELLEN + SMK_LABELLEN + 1]) { 288 case '-': 289 break; 290 case 'w': 291 case 'W': 292 rule.smk_access |= MAY_WRITE; 293 break; 294 default: 295 goto out; 296 } 297 298 switch (data[SMK_LABELLEN + SMK_LABELLEN + 2]) { 299 case '-': 300 break; 301 case 'x': 302 case 'X': 303 rule.smk_access |= MAY_EXEC; 304 break; 305 default: 306 goto out; 307 } 308 309 switch (data[SMK_LABELLEN + SMK_LABELLEN + 3]) { 310 case '-': 311 break; 312 case 'a': 313 case 'A': 314 rule.smk_access |= MAY_READ; 315 break; 316 default: 317 goto out; 318 } 319 320 smk_set_access(&rule); 321 rc = count; 322 323 out: 324 kfree(data); 325 return rc; 326 } 327 328 static const struct file_operations smk_load_ops = { 329 .open = smk_open_load, 330 .read = seq_read, 331 .llseek = seq_lseek, 332 .write = smk_write_load, 333 .release = smk_release_load, 334 }; 335 336 /** 337 * smk_cipso_doi - initialize the CIPSO domain 338 */ 339 void smk_cipso_doi(void) 340 { 341 int rc; 342 struct cipso_v4_doi *doip; 343 struct netlbl_audit audit_info; 344 345 rc = netlbl_cfg_map_del(NULL, &audit_info); 346 if (rc != 0) 347 printk(KERN_WARNING "%s:%d remove rc = %d\n", 348 __func__, __LINE__, rc); 349 350 doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL); 351 if (doip == NULL) 352 panic("smack: Failed to initialize cipso DOI.\n"); 353 doip->map.std = NULL; 354 doip->doi = smk_cipso_doi_value; 355 doip->type = CIPSO_V4_MAP_PASS; 356 doip->tags[0] = CIPSO_V4_TAG_RBITMAP; 357 for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++) 358 doip->tags[rc] = CIPSO_V4_TAG_INVALID; 359 360 rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info); 361 if (rc != 0) 362 printk(KERN_WARNING "%s:%d add rc = %d\n", 363 __func__, __LINE__, rc); 364 } 365 366 /* 367 * Seq_file read operations for /smack/cipso 368 */ 369 370 static void *cipso_seq_start(struct seq_file *s, loff_t *pos) 371 { 372 if (*pos == SEQ_READ_FINISHED) 373 return NULL; 374 375 return smack_known; 376 } 377 378 static void *cipso_seq_next(struct seq_file *s, void *v, loff_t *pos) 379 { 380 struct smack_known *skp = ((struct smack_known *) v)->smk_next; 381 382 /* 383 * Omit labels with no associated cipso value 384 */ 385 while (skp != NULL && !skp->smk_cipso) 386 skp = skp->smk_next; 387 388 if (skp == NULL) 389 *pos = SEQ_READ_FINISHED; 390 391 return skp; 392 } 393 394 /* 395 * Print cipso labels in format: 396 * label level[/cat[,cat]] 397 */ 398 static int cipso_seq_show(struct seq_file *s, void *v) 399 { 400 struct smack_known *skp = (struct smack_known *) v; 401 struct smack_cipso *scp = skp->smk_cipso; 402 char *cbp; 403 char sep = '/'; 404 int cat = 1; 405 int i; 406 unsigned char m; 407 408 if (scp == NULL) 409 return 0; 410 411 seq_printf(s, "%s %3d", (char *)&skp->smk_known, scp->smk_level); 412 413 cbp = scp->smk_catset; 414 for (i = 0; i < SMK_LABELLEN; i++) 415 for (m = 0x80; m != 0; m >>= 1) { 416 if (m & cbp[i]) { 417 seq_printf(s, "%c%d", sep, cat); 418 sep = ','; 419 } 420 cat++; 421 } 422 423 seq_putc(s, '\n'); 424 425 return 0; 426 } 427 428 static void cipso_seq_stop(struct seq_file *s, void *v) 429 { 430 /* No-op */ 431 } 432 433 static struct seq_operations cipso_seq_ops = { 434 .start = cipso_seq_start, 435 .stop = cipso_seq_stop, 436 .next = cipso_seq_next, 437 .show = cipso_seq_show, 438 }; 439 440 /** 441 * smk_open_cipso - open() for /smack/cipso 442 * @inode: inode structure representing file 443 * @file: "cipso" file pointer 444 * 445 * Connect our cipso_seq_* operations with /smack/cipso 446 * file_operations 447 */ 448 static int smk_open_cipso(struct inode *inode, struct file *file) 449 { 450 return seq_open(file, &cipso_seq_ops); 451 } 452 453 /** 454 * smk_write_cipso - write() for /smack/cipso 455 * @filp: file pointer, not actually used 456 * @buf: where to get the data from 457 * @count: bytes sent 458 * @ppos: where to start 459 * 460 * Accepts only one cipso rule per write call. 461 * Returns number of bytes written or error code, as appropriate 462 */ 463 static ssize_t smk_write_cipso(struct file *file, const char __user *buf, 464 size_t count, loff_t *ppos) 465 { 466 struct smack_known *skp; 467 struct smack_cipso *scp = NULL; 468 char mapcatset[SMK_LABELLEN]; 469 int maplevel; 470 int cat; 471 int catlen; 472 ssize_t rc = -EINVAL; 473 char *data = NULL; 474 char *rule; 475 int ret; 476 int i; 477 478 /* 479 * Must have privilege. 480 * No partial writes. 481 * Enough data must be present. 482 */ 483 if (!capable(CAP_MAC_ADMIN)) 484 return -EPERM; 485 if (*ppos != 0) 486 return -EINVAL; 487 if (count <= SMK_CIPSOMIN) 488 return -EINVAL; 489 490 data = kzalloc(count + 1, GFP_KERNEL); 491 if (data == NULL) 492 return -ENOMEM; 493 494 if (copy_from_user(data, buf, count) != 0) { 495 rc = -EFAULT; 496 goto unlockedout; 497 } 498 499 data[count] = '\0'; 500 rule = data; 501 /* 502 * Only allow one writer at a time. Writes should be 503 * quite rare and small in any case. 504 */ 505 mutex_lock(&smack_cipso_lock); 506 507 skp = smk_import_entry(rule, 0); 508 if (skp == NULL) 509 goto out; 510 511 rule += SMK_LABELLEN;; 512 ret = sscanf(rule, "%d", &maplevel); 513 if (ret != 1 || maplevel > SMACK_CIPSO_MAXLEVEL) 514 goto out; 515 516 rule += SMK_DIGITLEN; 517 ret = sscanf(rule, "%d", &catlen); 518 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) 519 goto out; 520 521 if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) 522 goto out; 523 524 memset(mapcatset, 0, sizeof(mapcatset)); 525 526 for (i = 0; i < catlen; i++) { 527 rule += SMK_DIGITLEN; 528 ret = sscanf(rule, "%d", &cat); 529 if (ret != 1 || cat > SMACK_CIPSO_MAXCATVAL) 530 goto out; 531 532 smack_catset_bit(cat, mapcatset); 533 } 534 535 if (skp->smk_cipso == NULL) { 536 scp = kzalloc(sizeof(struct smack_cipso), GFP_KERNEL); 537 if (scp == NULL) { 538 rc = -ENOMEM; 539 goto out; 540 } 541 } 542 543 spin_lock_bh(&skp->smk_cipsolock); 544 545 if (scp == NULL) 546 scp = skp->smk_cipso; 547 else 548 skp->smk_cipso = scp; 549 550 scp->smk_level = maplevel; 551 memcpy(scp->smk_catset, mapcatset, sizeof(mapcatset)); 552 553 spin_unlock_bh(&skp->smk_cipsolock); 554 555 rc = count; 556 out: 557 mutex_unlock(&smack_cipso_lock); 558 unlockedout: 559 kfree(data); 560 return rc; 561 } 562 563 static const struct file_operations smk_cipso_ops = { 564 .open = smk_open_cipso, 565 .read = seq_read, 566 .llseek = seq_lseek, 567 .write = smk_write_cipso, 568 .release = seq_release, 569 }; 570 571 /** 572 * smk_read_doi - read() for /smack/doi 573 * @filp: file pointer, not actually used 574 * @buf: where to put the result 575 * @count: maximum to send along 576 * @ppos: where to start 577 * 578 * Returns number of bytes read or error code, as appropriate 579 */ 580 static ssize_t smk_read_doi(struct file *filp, char __user *buf, 581 size_t count, loff_t *ppos) 582 { 583 char temp[80]; 584 ssize_t rc; 585 586 if (*ppos != 0) 587 return 0; 588 589 sprintf(temp, "%d", smk_cipso_doi_value); 590 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 591 592 return rc; 593 } 594 595 /** 596 * smk_write_doi - write() for /smack/doi 597 * @filp: file pointer, not actually used 598 * @buf: where to get the data from 599 * @count: bytes sent 600 * @ppos: where to start 601 * 602 * Returns number of bytes written or error code, as appropriate 603 */ 604 static ssize_t smk_write_doi(struct file *file, const char __user *buf, 605 size_t count, loff_t *ppos) 606 { 607 char temp[80]; 608 int i; 609 610 if (!capable(CAP_MAC_ADMIN)) 611 return -EPERM; 612 613 if (count >= sizeof(temp) || count == 0) 614 return -EINVAL; 615 616 if (copy_from_user(temp, buf, count) != 0) 617 return -EFAULT; 618 619 temp[count] = '\0'; 620 621 if (sscanf(temp, "%d", &i) != 1) 622 return -EINVAL; 623 624 smk_cipso_doi_value = i; 625 626 smk_cipso_doi(); 627 628 return count; 629 } 630 631 static const struct file_operations smk_doi_ops = { 632 .read = smk_read_doi, 633 .write = smk_write_doi, 634 }; 635 636 /** 637 * smk_read_direct - read() for /smack/direct 638 * @filp: file pointer, not actually used 639 * @buf: where to put the result 640 * @count: maximum to send along 641 * @ppos: where to start 642 * 643 * Returns number of bytes read or error code, as appropriate 644 */ 645 static ssize_t smk_read_direct(struct file *filp, char __user *buf, 646 size_t count, loff_t *ppos) 647 { 648 char temp[80]; 649 ssize_t rc; 650 651 if (*ppos != 0) 652 return 0; 653 654 sprintf(temp, "%d", smack_cipso_direct); 655 rc = simple_read_from_buffer(buf, count, ppos, temp, strlen(temp)); 656 657 return rc; 658 } 659 660 /** 661 * smk_write_direct - write() for /smack/direct 662 * @filp: file pointer, not actually used 663 * @buf: where to get the data from 664 * @count: bytes sent 665 * @ppos: where to start 666 * 667 * Returns number of bytes written or error code, as appropriate 668 */ 669 static ssize_t smk_write_direct(struct file *file, const char __user *buf, 670 size_t count, loff_t *ppos) 671 { 672 char temp[80]; 673 int i; 674 675 if (!capable(CAP_MAC_ADMIN)) 676 return -EPERM; 677 678 if (count >= sizeof(temp) || count == 0) 679 return -EINVAL; 680 681 if (copy_from_user(temp, buf, count) != 0) 682 return -EFAULT; 683 684 temp[count] = '\0'; 685 686 if (sscanf(temp, "%d", &i) != 1) 687 return -EINVAL; 688 689 smack_cipso_direct = i; 690 691 return count; 692 } 693 694 static const struct file_operations smk_direct_ops = { 695 .read = smk_read_direct, 696 .write = smk_write_direct, 697 }; 698 699 /** 700 * smk_read_ambient - read() for /smack/ambient 701 * @filp: file pointer, not actually used 702 * @buf: where to put the result 703 * @cn: maximum to send along 704 * @ppos: where to start 705 * 706 * Returns number of bytes read or error code, as appropriate 707 */ 708 static ssize_t smk_read_ambient(struct file *filp, char __user *buf, 709 size_t cn, loff_t *ppos) 710 { 711 ssize_t rc; 712 char out[SMK_LABELLEN]; 713 int asize; 714 715 if (*ppos != 0) 716 return 0; 717 /* 718 * Being careful to avoid a problem in the case where 719 * smack_net_ambient gets changed in midstream. 720 * Since smack_net_ambient is always set with a value 721 * from the label list, including initially, and those 722 * never get freed, the worst case is that the pointer 723 * gets changed just after this strncpy, in which case 724 * the value passed up is incorrect. Locking around 725 * smack_net_ambient wouldn't be any better than this 726 * copy scheme as by the time the caller got to look 727 * at the ambient value it would have cleared the lock 728 * and been changed. 729 */ 730 strncpy(out, smack_net_ambient, SMK_LABELLEN); 731 asize = strlen(out) + 1; 732 733 if (cn < asize) 734 return -EINVAL; 735 736 rc = simple_read_from_buffer(buf, cn, ppos, out, asize); 737 738 return rc; 739 } 740 741 /** 742 * smk_write_ambient - write() for /smack/ambient 743 * @filp: file pointer, not actually used 744 * @buf: where to get the data from 745 * @count: bytes sent 746 * @ppos: where to start 747 * 748 * Returns number of bytes written or error code, as appropriate 749 */ 750 static ssize_t smk_write_ambient(struct file *file, const char __user *buf, 751 size_t count, loff_t *ppos) 752 { 753 char in[SMK_LABELLEN]; 754 char *smack; 755 756 if (!capable(CAP_MAC_ADMIN)) 757 return -EPERM; 758 759 if (count >= SMK_LABELLEN) 760 return -EINVAL; 761 762 if (copy_from_user(in, buf, count) != 0) 763 return -EFAULT; 764 765 smack = smk_import(in, count); 766 if (smack == NULL) 767 return -EINVAL; 768 769 smack_net_ambient = smack; 770 771 return count; 772 } 773 774 static const struct file_operations smk_ambient_ops = { 775 .read = smk_read_ambient, 776 .write = smk_write_ambient, 777 }; 778 779 struct option_names { 780 int o_number; 781 char *o_name; 782 char *o_alias; 783 }; 784 785 static struct option_names netlbl_choices[] = { 786 { NETLBL_NLTYPE_RIPSO, 787 NETLBL_NLTYPE_RIPSO_NAME, "ripso" }, 788 { NETLBL_NLTYPE_CIPSOV4, 789 NETLBL_NLTYPE_CIPSOV4_NAME, "cipsov4" }, 790 { NETLBL_NLTYPE_CIPSOV4, 791 NETLBL_NLTYPE_CIPSOV4_NAME, "cipso" }, 792 { NETLBL_NLTYPE_CIPSOV6, 793 NETLBL_NLTYPE_CIPSOV6_NAME, "cipsov6" }, 794 { NETLBL_NLTYPE_UNLABELED, 795 NETLBL_NLTYPE_UNLABELED_NAME, "unlabeled" }, 796 }; 797 798 /** 799 * smk_read_nltype - read() for /smack/nltype 800 * @filp: file pointer, not actually used 801 * @buf: where to put the result 802 * @count: maximum to send along 803 * @ppos: where to start 804 * 805 * Returns number of bytes read or error code, as appropriate 806 */ 807 static ssize_t smk_read_nltype(struct file *filp, char __user *buf, 808 size_t count, loff_t *ppos) 809 { 810 char bound[40]; 811 ssize_t rc; 812 int i; 813 814 if (count < SMK_LABELLEN) 815 return -EINVAL; 816 817 if (*ppos != 0) 818 return 0; 819 820 sprintf(bound, "unknown"); 821 822 for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) 823 if (smack_net_nltype == netlbl_choices[i].o_number) { 824 sprintf(bound, "%s", netlbl_choices[i].o_name); 825 break; 826 } 827 828 rc = simple_read_from_buffer(buf, count, ppos, bound, strlen(bound)); 829 830 return rc; 831 } 832 833 /** 834 * smk_write_nltype - write() for /smack/nltype 835 * @filp: file pointer, not actually used 836 * @buf: where to get the data from 837 * @count: bytes sent 838 * @ppos: where to start 839 * 840 * Returns number of bytes written or error code, as appropriate 841 */ 842 static ssize_t smk_write_nltype(struct file *file, const char __user *buf, 843 size_t count, loff_t *ppos) 844 { 845 char bound[40]; 846 char *cp; 847 int i; 848 849 if (!capable(CAP_MAC_ADMIN)) 850 return -EPERM; 851 852 if (count >= 40) 853 return -EINVAL; 854 855 if (copy_from_user(bound, buf, count) != 0) 856 return -EFAULT; 857 858 bound[count] = '\0'; 859 cp = strchr(bound, ' '); 860 if (cp != NULL) 861 *cp = '\0'; 862 cp = strchr(bound, '\n'); 863 if (cp != NULL) 864 *cp = '\0'; 865 866 for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) 867 if (strcmp(bound, netlbl_choices[i].o_name) == 0 || 868 strcmp(bound, netlbl_choices[i].o_alias) == 0) { 869 smack_net_nltype = netlbl_choices[i].o_number; 870 return count; 871 } 872 /* 873 * Not a valid choice. 874 */ 875 return -EINVAL; 876 } 877 878 static const struct file_operations smk_nltype_ops = { 879 .read = smk_read_nltype, 880 .write = smk_write_nltype, 881 }; 882 883 /** 884 * smk_fill_super - fill the /smackfs superblock 885 * @sb: the empty superblock 886 * @data: unused 887 * @silent: unused 888 * 889 * Fill in the well known entries for /smack 890 * 891 * Returns 0 on success, an error code on failure 892 */ 893 static int smk_fill_super(struct super_block *sb, void *data, int silent) 894 { 895 int rc; 896 struct inode *root_inode; 897 898 static struct tree_descr smack_files[] = { 899 [SMK_LOAD] = 900 {"load", &smk_load_ops, S_IRUGO|S_IWUSR}, 901 [SMK_CIPSO] = 902 {"cipso", &smk_cipso_ops, S_IRUGO|S_IWUSR}, 903 [SMK_DOI] = 904 {"doi", &smk_doi_ops, S_IRUGO|S_IWUSR}, 905 [SMK_DIRECT] = 906 {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, 907 [SMK_AMBIENT] = 908 {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, 909 [SMK_NLTYPE] = 910 {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR}, 911 /* last one */ {""} 912 }; 913 914 rc = simple_fill_super(sb, SMACK_MAGIC, smack_files); 915 if (rc != 0) { 916 printk(KERN_ERR "%s failed %d while creating inodes\n", 917 __func__, rc); 918 return rc; 919 } 920 921 root_inode = sb->s_root->d_inode; 922 root_inode->i_security = new_inode_smack(smack_known_floor.smk_known); 923 924 return 0; 925 } 926 927 /** 928 * smk_get_sb - get the smackfs superblock 929 * @fs_type: passed along without comment 930 * @flags: passed along without comment 931 * @dev_name: passed along without comment 932 * @data: passed along without comment 933 * @mnt: passed along without comment 934 * 935 * Just passes everything along. 936 * 937 * Returns what the lower level code does. 938 */ 939 static int smk_get_sb(struct file_system_type *fs_type, 940 int flags, const char *dev_name, void *data, 941 struct vfsmount *mnt) 942 { 943 return get_sb_single(fs_type, flags, data, smk_fill_super, mnt); 944 } 945 946 static struct file_system_type smk_fs_type = { 947 .name = "smackfs", 948 .get_sb = smk_get_sb, 949 .kill_sb = kill_litter_super, 950 }; 951 952 static struct vfsmount *smackfs_mount; 953 954 /** 955 * init_smk_fs - get the smackfs superblock 956 * 957 * register the smackfs 958 * 959 * Returns 0 unless the registration fails. 960 */ 961 static int __init init_smk_fs(void) 962 { 963 int err; 964 965 err = register_filesystem(&smk_fs_type); 966 if (!err) { 967 smackfs_mount = kern_mount(&smk_fs_type); 968 if (IS_ERR(smackfs_mount)) { 969 printk(KERN_ERR "smackfs: could not mount!\n"); 970 err = PTR_ERR(smackfs_mount); 971 smackfs_mount = NULL; 972 } 973 } 974 975 sema_init(&smack_write_sem, 1); 976 smk_cipso_doi(); 977 978 return err; 979 } 980 981 __initcall(init_smk_fs); 982