Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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