1 /* Updated: Karl MacMillan <kmacmillan@tresys.com> 2 * 3 * Added conditional policy language extensions 4 * 5 * Copyright (C) 2003 - 2004 Tresys Technology, LLC 6 * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com> 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, version 2. 10 */ 11 12 #include <linux/kernel.h> 13 #include <linux/pagemap.h> 14 #include <linux/slab.h> 15 #include <linux/vmalloc.h> 16 #include <linux/fs.h> 17 #include <linux/mutex.h> 18 #include <linux/init.h> 19 #include <linux/string.h> 20 #include <linux/security.h> 21 #include <linux/major.h> 22 #include <linux/seq_file.h> 23 #include <linux/percpu.h> 24 #include <linux/audit.h> 25 #include <asm/uaccess.h> 26 #include <asm/semaphore.h> 27 28 /* selinuxfs pseudo filesystem for exporting the security policy API. 29 Based on the proc code and the fs/nfsd/nfsctl.c code. */ 30 31 #include "flask.h" 32 #include "avc.h" 33 #include "avc_ss.h" 34 #include "security.h" 35 #include "objsec.h" 36 #include "conditional.h" 37 38 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 39 40 #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT 41 #define SELINUX_COMPAT_NET_VALUE 0 42 #else 43 #define SELINUX_COMPAT_NET_VALUE 1 44 #endif 45 46 int selinux_compat_net = SELINUX_COMPAT_NET_VALUE; 47 48 static int __init checkreqprot_setup(char *str) 49 { 50 selinux_checkreqprot = simple_strtoul(str,NULL,0) ? 1 : 0; 51 return 1; 52 } 53 __setup("checkreqprot=", checkreqprot_setup); 54 55 static int __init selinux_compat_net_setup(char *str) 56 { 57 selinux_compat_net = simple_strtoul(str,NULL,0) ? 1 : 0; 58 return 1; 59 } 60 __setup("selinux_compat_net=", selinux_compat_net_setup); 61 62 63 static DEFINE_MUTEX(sel_mutex); 64 65 /* global data for booleans */ 66 static struct dentry *bool_dir = NULL; 67 static int bool_num = 0; 68 static int *bool_pending_values = NULL; 69 70 extern void selnl_notify_setenforce(int val); 71 72 /* Check whether a task is allowed to use a security operation. */ 73 static int task_has_security(struct task_struct *tsk, 74 u32 perms) 75 { 76 struct task_security_struct *tsec; 77 78 tsec = tsk->security; 79 if (!tsec) 80 return -EACCES; 81 82 return avc_has_perm(tsec->sid, SECINITSID_SECURITY, 83 SECCLASS_SECURITY, perms, NULL); 84 } 85 86 enum sel_inos { 87 SEL_ROOT_INO = 2, 88 SEL_LOAD, /* load policy */ 89 SEL_ENFORCE, /* get or set enforcing status */ 90 SEL_CONTEXT, /* validate context */ 91 SEL_ACCESS, /* compute access decision */ 92 SEL_CREATE, /* compute create labeling decision */ 93 SEL_RELABEL, /* compute relabeling decision */ 94 SEL_USER, /* compute reachable user contexts */ 95 SEL_POLICYVERS, /* return policy version for this kernel */ 96 SEL_COMMIT_BOOLS, /* commit new boolean values */ 97 SEL_MLS, /* return if MLS policy is enabled */ 98 SEL_DISABLE, /* disable SELinux until next reboot */ 99 SEL_AVC, /* AVC management directory */ 100 SEL_MEMBER, /* compute polyinstantiation membership decision */ 101 SEL_CHECKREQPROT, /* check requested protection, not kernel-applied one */ 102 SEL_COMPAT_NET, /* whether to use old compat network packet controls */ 103 }; 104 105 #define TMPBUFLEN 12 106 static ssize_t sel_read_enforce(struct file *filp, char __user *buf, 107 size_t count, loff_t *ppos) 108 { 109 char tmpbuf[TMPBUFLEN]; 110 ssize_t length; 111 112 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_enforcing); 113 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 114 } 115 116 #ifdef CONFIG_SECURITY_SELINUX_DEVELOP 117 static ssize_t sel_write_enforce(struct file * file, const char __user * buf, 118 size_t count, loff_t *ppos) 119 120 { 121 char *page; 122 ssize_t length; 123 int new_value; 124 125 if (count >= PAGE_SIZE) 126 return -ENOMEM; 127 if (*ppos != 0) { 128 /* No partial writes. */ 129 return -EINVAL; 130 } 131 page = (char*)get_zeroed_page(GFP_KERNEL); 132 if (!page) 133 return -ENOMEM; 134 length = -EFAULT; 135 if (copy_from_user(page, buf, count)) 136 goto out; 137 138 length = -EINVAL; 139 if (sscanf(page, "%d", &new_value) != 1) 140 goto out; 141 142 if (new_value != selinux_enforcing) { 143 length = task_has_security(current, SECURITY__SETENFORCE); 144 if (length) 145 goto out; 146 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 147 "enforcing=%d old_enforcing=%d auid=%u", new_value, 148 selinux_enforcing, 149 audit_get_loginuid(current->audit_context)); 150 selinux_enforcing = new_value; 151 if (selinux_enforcing) 152 avc_ss_reset(0); 153 selnl_notify_setenforce(selinux_enforcing); 154 } 155 length = count; 156 out: 157 free_page((unsigned long) page); 158 return length; 159 } 160 #else 161 #define sel_write_enforce NULL 162 #endif 163 164 static struct file_operations sel_enforce_ops = { 165 .read = sel_read_enforce, 166 .write = sel_write_enforce, 167 }; 168 169 #ifdef CONFIG_SECURITY_SELINUX_DISABLE 170 static ssize_t sel_write_disable(struct file * file, const char __user * buf, 171 size_t count, loff_t *ppos) 172 173 { 174 char *page; 175 ssize_t length; 176 int new_value; 177 extern int selinux_disable(void); 178 179 if (count >= PAGE_SIZE) 180 return -ENOMEM; 181 if (*ppos != 0) { 182 /* No partial writes. */ 183 return -EINVAL; 184 } 185 page = (char*)get_zeroed_page(GFP_KERNEL); 186 if (!page) 187 return -ENOMEM; 188 length = -EFAULT; 189 if (copy_from_user(page, buf, count)) 190 goto out; 191 192 length = -EINVAL; 193 if (sscanf(page, "%d", &new_value) != 1) 194 goto out; 195 196 if (new_value) { 197 length = selinux_disable(); 198 if (length < 0) 199 goto out; 200 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 201 "selinux=0 auid=%u", 202 audit_get_loginuid(current->audit_context)); 203 } 204 205 length = count; 206 out: 207 free_page((unsigned long) page); 208 return length; 209 } 210 #else 211 #define sel_write_disable NULL 212 #endif 213 214 static struct file_operations sel_disable_ops = { 215 .write = sel_write_disable, 216 }; 217 218 static ssize_t sel_read_policyvers(struct file *filp, char __user *buf, 219 size_t count, loff_t *ppos) 220 { 221 char tmpbuf[TMPBUFLEN]; 222 ssize_t length; 223 224 length = scnprintf(tmpbuf, TMPBUFLEN, "%u", POLICYDB_VERSION_MAX); 225 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 226 } 227 228 static struct file_operations sel_policyvers_ops = { 229 .read = sel_read_policyvers, 230 }; 231 232 /* declaration for sel_write_load */ 233 static int sel_make_bools(void); 234 235 static ssize_t sel_read_mls(struct file *filp, char __user *buf, 236 size_t count, loff_t *ppos) 237 { 238 char tmpbuf[TMPBUFLEN]; 239 ssize_t length; 240 241 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled); 242 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 243 } 244 245 static struct file_operations sel_mls_ops = { 246 .read = sel_read_mls, 247 }; 248 249 static ssize_t sel_write_load(struct file * file, const char __user * buf, 250 size_t count, loff_t *ppos) 251 252 { 253 int ret; 254 ssize_t length; 255 void *data = NULL; 256 257 mutex_lock(&sel_mutex); 258 259 length = task_has_security(current, SECURITY__LOAD_POLICY); 260 if (length) 261 goto out; 262 263 if (*ppos != 0) { 264 /* No partial writes. */ 265 length = -EINVAL; 266 goto out; 267 } 268 269 if ((count > 64 * 1024 * 1024) 270 || (data = vmalloc(count)) == NULL) { 271 length = -ENOMEM; 272 goto out; 273 } 274 275 length = -EFAULT; 276 if (copy_from_user(data, buf, count) != 0) 277 goto out; 278 279 length = security_load_policy(data, count); 280 if (length) 281 goto out; 282 283 ret = sel_make_bools(); 284 if (ret) 285 length = ret; 286 else 287 length = count; 288 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, 289 "policy loaded auid=%u", 290 audit_get_loginuid(current->audit_context)); 291 out: 292 mutex_unlock(&sel_mutex); 293 vfree(data); 294 return length; 295 } 296 297 static struct file_operations sel_load_ops = { 298 .write = sel_write_load, 299 }; 300 301 static ssize_t sel_write_context(struct file * file, char *buf, size_t size) 302 { 303 char *canon; 304 u32 sid, len; 305 ssize_t length; 306 307 length = task_has_security(current, SECURITY__CHECK_CONTEXT); 308 if (length) 309 return length; 310 311 length = security_context_to_sid(buf, size, &sid); 312 if (length < 0) 313 return length; 314 315 length = security_sid_to_context(sid, &canon, &len); 316 if (length < 0) 317 return length; 318 319 if (len > SIMPLE_TRANSACTION_LIMIT) { 320 printk(KERN_ERR "%s: context size (%u) exceeds payload " 321 "max\n", __FUNCTION__, len); 322 length = -ERANGE; 323 goto out; 324 } 325 326 memcpy(buf, canon, len); 327 length = len; 328 out: 329 kfree(canon); 330 return length; 331 } 332 333 static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, 334 size_t count, loff_t *ppos) 335 { 336 char tmpbuf[TMPBUFLEN]; 337 ssize_t length; 338 339 length = scnprintf(tmpbuf, TMPBUFLEN, "%u", selinux_checkreqprot); 340 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 341 } 342 343 static ssize_t sel_write_checkreqprot(struct file * file, const char __user * buf, 344 size_t count, loff_t *ppos) 345 { 346 char *page; 347 ssize_t length; 348 unsigned int new_value; 349 350 length = task_has_security(current, SECURITY__SETCHECKREQPROT); 351 if (length) 352 return length; 353 354 if (count >= PAGE_SIZE) 355 return -ENOMEM; 356 if (*ppos != 0) { 357 /* No partial writes. */ 358 return -EINVAL; 359 } 360 page = (char*)get_zeroed_page(GFP_KERNEL); 361 if (!page) 362 return -ENOMEM; 363 length = -EFAULT; 364 if (copy_from_user(page, buf, count)) 365 goto out; 366 367 length = -EINVAL; 368 if (sscanf(page, "%u", &new_value) != 1) 369 goto out; 370 371 selinux_checkreqprot = new_value ? 1 : 0; 372 length = count; 373 out: 374 free_page((unsigned long) page); 375 return length; 376 } 377 static struct file_operations sel_checkreqprot_ops = { 378 .read = sel_read_checkreqprot, 379 .write = sel_write_checkreqprot, 380 }; 381 382 static ssize_t sel_read_compat_net(struct file *filp, char __user *buf, 383 size_t count, loff_t *ppos) 384 { 385 char tmpbuf[TMPBUFLEN]; 386 ssize_t length; 387 388 length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_compat_net); 389 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 390 } 391 392 static ssize_t sel_write_compat_net(struct file * file, const char __user * buf, 393 size_t count, loff_t *ppos) 394 { 395 char *page; 396 ssize_t length; 397 int new_value; 398 399 length = task_has_security(current, SECURITY__LOAD_POLICY); 400 if (length) 401 return length; 402 403 if (count >= PAGE_SIZE) 404 return -ENOMEM; 405 if (*ppos != 0) { 406 /* No partial writes. */ 407 return -EINVAL; 408 } 409 page = (char*)get_zeroed_page(GFP_KERNEL); 410 if (!page) 411 return -ENOMEM; 412 length = -EFAULT; 413 if (copy_from_user(page, buf, count)) 414 goto out; 415 416 length = -EINVAL; 417 if (sscanf(page, "%d", &new_value) != 1) 418 goto out; 419 420 selinux_compat_net = new_value ? 1 : 0; 421 length = count; 422 out: 423 free_page((unsigned long) page); 424 return length; 425 } 426 static struct file_operations sel_compat_net_ops = { 427 .read = sel_read_compat_net, 428 .write = sel_write_compat_net, 429 }; 430 431 /* 432 * Remaining nodes use transaction based IO methods like nfsd/nfsctl.c 433 */ 434 static ssize_t sel_write_access(struct file * file, char *buf, size_t size); 435 static ssize_t sel_write_create(struct file * file, char *buf, size_t size); 436 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size); 437 static ssize_t sel_write_user(struct file * file, char *buf, size_t size); 438 static ssize_t sel_write_member(struct file * file, char *buf, size_t size); 439 440 static ssize_t (*write_op[])(struct file *, char *, size_t) = { 441 [SEL_ACCESS] = sel_write_access, 442 [SEL_CREATE] = sel_write_create, 443 [SEL_RELABEL] = sel_write_relabel, 444 [SEL_USER] = sel_write_user, 445 [SEL_MEMBER] = sel_write_member, 446 [SEL_CONTEXT] = sel_write_context, 447 }; 448 449 static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) 450 { 451 ino_t ino = file->f_dentry->d_inode->i_ino; 452 char *data; 453 ssize_t rv; 454 455 if (ino >= ARRAY_SIZE(write_op) || !write_op[ino]) 456 return -EINVAL; 457 458 data = simple_transaction_get(file, buf, size); 459 if (IS_ERR(data)) 460 return PTR_ERR(data); 461 462 rv = write_op[ino](file, data, size); 463 if (rv>0) { 464 simple_transaction_set(file, rv); 465 rv = size; 466 } 467 return rv; 468 } 469 470 static struct file_operations transaction_ops = { 471 .write = selinux_transaction_write, 472 .read = simple_transaction_read, 473 .release = simple_transaction_release, 474 }; 475 476 /* 477 * payload - write methods 478 * If the method has a response, the response should be put in buf, 479 * and the length returned. Otherwise return 0 or and -error. 480 */ 481 482 static ssize_t sel_write_access(struct file * file, char *buf, size_t size) 483 { 484 char *scon, *tcon; 485 u32 ssid, tsid; 486 u16 tclass; 487 u32 req; 488 struct av_decision avd; 489 ssize_t length; 490 491 length = task_has_security(current, SECURITY__COMPUTE_AV); 492 if (length) 493 return length; 494 495 length = -ENOMEM; 496 scon = kzalloc(size+1, GFP_KERNEL); 497 if (!scon) 498 return length; 499 500 tcon = kzalloc(size+1, GFP_KERNEL); 501 if (!tcon) 502 goto out; 503 504 length = -EINVAL; 505 if (sscanf(buf, "%s %s %hu %x", scon, tcon, &tclass, &req) != 4) 506 goto out2; 507 508 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 509 if (length < 0) 510 goto out2; 511 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 512 if (length < 0) 513 goto out2; 514 515 length = security_compute_av(ssid, tsid, tclass, req, &avd); 516 if (length < 0) 517 goto out2; 518 519 length = scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, 520 "%x %x %x %x %u", 521 avd.allowed, avd.decided, 522 avd.auditallow, avd.auditdeny, 523 avd.seqno); 524 out2: 525 kfree(tcon); 526 out: 527 kfree(scon); 528 return length; 529 } 530 531 static ssize_t sel_write_create(struct file * file, char *buf, size_t size) 532 { 533 char *scon, *tcon; 534 u32 ssid, tsid, newsid; 535 u16 tclass; 536 ssize_t length; 537 char *newcon; 538 u32 len; 539 540 length = task_has_security(current, SECURITY__COMPUTE_CREATE); 541 if (length) 542 return length; 543 544 length = -ENOMEM; 545 scon = kzalloc(size+1, GFP_KERNEL); 546 if (!scon) 547 return length; 548 549 tcon = kzalloc(size+1, GFP_KERNEL); 550 if (!tcon) 551 goto out; 552 553 length = -EINVAL; 554 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 555 goto out2; 556 557 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 558 if (length < 0) 559 goto out2; 560 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 561 if (length < 0) 562 goto out2; 563 564 length = security_transition_sid(ssid, tsid, tclass, &newsid); 565 if (length < 0) 566 goto out2; 567 568 length = security_sid_to_context(newsid, &newcon, &len); 569 if (length < 0) 570 goto out2; 571 572 if (len > SIMPLE_TRANSACTION_LIMIT) { 573 printk(KERN_ERR "%s: context size (%u) exceeds payload " 574 "max\n", __FUNCTION__, len); 575 length = -ERANGE; 576 goto out3; 577 } 578 579 memcpy(buf, newcon, len); 580 length = len; 581 out3: 582 kfree(newcon); 583 out2: 584 kfree(tcon); 585 out: 586 kfree(scon); 587 return length; 588 } 589 590 static ssize_t sel_write_relabel(struct file * file, char *buf, size_t size) 591 { 592 char *scon, *tcon; 593 u32 ssid, tsid, newsid; 594 u16 tclass; 595 ssize_t length; 596 char *newcon; 597 u32 len; 598 599 length = task_has_security(current, SECURITY__COMPUTE_RELABEL); 600 if (length) 601 return length; 602 603 length = -ENOMEM; 604 scon = kzalloc(size+1, GFP_KERNEL); 605 if (!scon) 606 return length; 607 608 tcon = kzalloc(size+1, GFP_KERNEL); 609 if (!tcon) 610 goto out; 611 612 length = -EINVAL; 613 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 614 goto out2; 615 616 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 617 if (length < 0) 618 goto out2; 619 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 620 if (length < 0) 621 goto out2; 622 623 length = security_change_sid(ssid, tsid, tclass, &newsid); 624 if (length < 0) 625 goto out2; 626 627 length = security_sid_to_context(newsid, &newcon, &len); 628 if (length < 0) 629 goto out2; 630 631 if (len > SIMPLE_TRANSACTION_LIMIT) { 632 length = -ERANGE; 633 goto out3; 634 } 635 636 memcpy(buf, newcon, len); 637 length = len; 638 out3: 639 kfree(newcon); 640 out2: 641 kfree(tcon); 642 out: 643 kfree(scon); 644 return length; 645 } 646 647 static ssize_t sel_write_user(struct file * file, char *buf, size_t size) 648 { 649 char *con, *user, *ptr; 650 u32 sid, *sids; 651 ssize_t length; 652 char *newcon; 653 int i, rc; 654 u32 len, nsids; 655 656 length = task_has_security(current, SECURITY__COMPUTE_USER); 657 if (length) 658 return length; 659 660 length = -ENOMEM; 661 con = kzalloc(size+1, GFP_KERNEL); 662 if (!con) 663 return length; 664 665 user = kzalloc(size+1, GFP_KERNEL); 666 if (!user) 667 goto out; 668 669 length = -EINVAL; 670 if (sscanf(buf, "%s %s", con, user) != 2) 671 goto out2; 672 673 length = security_context_to_sid(con, strlen(con)+1, &sid); 674 if (length < 0) 675 goto out2; 676 677 length = security_get_user_sids(sid, user, &sids, &nsids); 678 if (length < 0) 679 goto out2; 680 681 length = sprintf(buf, "%u", nsids) + 1; 682 ptr = buf + length; 683 for (i = 0; i < nsids; i++) { 684 rc = security_sid_to_context(sids[i], &newcon, &len); 685 if (rc) { 686 length = rc; 687 goto out3; 688 } 689 if ((length + len) >= SIMPLE_TRANSACTION_LIMIT) { 690 kfree(newcon); 691 length = -ERANGE; 692 goto out3; 693 } 694 memcpy(ptr, newcon, len); 695 kfree(newcon); 696 ptr += len; 697 length += len; 698 } 699 out3: 700 kfree(sids); 701 out2: 702 kfree(user); 703 out: 704 kfree(con); 705 return length; 706 } 707 708 static ssize_t sel_write_member(struct file * file, char *buf, size_t size) 709 { 710 char *scon, *tcon; 711 u32 ssid, tsid, newsid; 712 u16 tclass; 713 ssize_t length; 714 char *newcon; 715 u32 len; 716 717 length = task_has_security(current, SECURITY__COMPUTE_MEMBER); 718 if (length) 719 return length; 720 721 length = -ENOMEM; 722 scon = kzalloc(size+1, GFP_KERNEL); 723 if (!scon) 724 return length; 725 726 tcon = kzalloc(size+1, GFP_KERNEL); 727 if (!tcon) 728 goto out; 729 730 length = -EINVAL; 731 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 732 goto out2; 733 734 length = security_context_to_sid(scon, strlen(scon)+1, &ssid); 735 if (length < 0) 736 goto out2; 737 length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid); 738 if (length < 0) 739 goto out2; 740 741 length = security_member_sid(ssid, tsid, tclass, &newsid); 742 if (length < 0) 743 goto out2; 744 745 length = security_sid_to_context(newsid, &newcon, &len); 746 if (length < 0) 747 goto out2; 748 749 if (len > SIMPLE_TRANSACTION_LIMIT) { 750 printk(KERN_ERR "%s: context size (%u) exceeds payload " 751 "max\n", __FUNCTION__, len); 752 length = -ERANGE; 753 goto out3; 754 } 755 756 memcpy(buf, newcon, len); 757 length = len; 758 out3: 759 kfree(newcon); 760 out2: 761 kfree(tcon); 762 out: 763 kfree(scon); 764 return length; 765 } 766 767 static struct inode *sel_make_inode(struct super_block *sb, int mode) 768 { 769 struct inode *ret = new_inode(sb); 770 771 if (ret) { 772 ret->i_mode = mode; 773 ret->i_uid = ret->i_gid = 0; 774 ret->i_blksize = PAGE_CACHE_SIZE; 775 ret->i_blocks = 0; 776 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; 777 } 778 return ret; 779 } 780 781 #define BOOL_INO_OFFSET 30 782 783 static ssize_t sel_read_bool(struct file *filep, char __user *buf, 784 size_t count, loff_t *ppos) 785 { 786 char *page = NULL; 787 ssize_t length; 788 ssize_t ret; 789 int cur_enforcing; 790 struct inode *inode; 791 792 mutex_lock(&sel_mutex); 793 794 ret = -EFAULT; 795 796 /* check to see if this file has been deleted */ 797 if (!filep->f_op) 798 goto out; 799 800 if (count > PAGE_SIZE) { 801 ret = -EINVAL; 802 goto out; 803 } 804 if (!(page = (char*)get_zeroed_page(GFP_KERNEL))) { 805 ret = -ENOMEM; 806 goto out; 807 } 808 809 inode = filep->f_dentry->d_inode; 810 cur_enforcing = security_get_bool_value(inode->i_ino - BOOL_INO_OFFSET); 811 if (cur_enforcing < 0) { 812 ret = cur_enforcing; 813 goto out; 814 } 815 816 length = scnprintf(page, PAGE_SIZE, "%d %d", cur_enforcing, 817 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET]); 818 ret = simple_read_from_buffer(buf, count, ppos, page, length); 819 out: 820 mutex_unlock(&sel_mutex); 821 if (page) 822 free_page((unsigned long)page); 823 return ret; 824 } 825 826 static ssize_t sel_write_bool(struct file *filep, const char __user *buf, 827 size_t count, loff_t *ppos) 828 { 829 char *page = NULL; 830 ssize_t length = -EFAULT; 831 int new_value; 832 struct inode *inode; 833 834 mutex_lock(&sel_mutex); 835 836 length = task_has_security(current, SECURITY__SETBOOL); 837 if (length) 838 goto out; 839 840 /* check to see if this file has been deleted */ 841 if (!filep->f_op) 842 goto out; 843 844 if (count >= PAGE_SIZE) { 845 length = -ENOMEM; 846 goto out; 847 } 848 if (*ppos != 0) { 849 /* No partial writes. */ 850 goto out; 851 } 852 page = (char*)get_zeroed_page(GFP_KERNEL); 853 if (!page) { 854 length = -ENOMEM; 855 goto out; 856 } 857 858 if (copy_from_user(page, buf, count)) 859 goto out; 860 861 length = -EINVAL; 862 if (sscanf(page, "%d", &new_value) != 1) 863 goto out; 864 865 if (new_value) 866 new_value = 1; 867 868 inode = filep->f_dentry->d_inode; 869 bool_pending_values[inode->i_ino - BOOL_INO_OFFSET] = new_value; 870 length = count; 871 872 out: 873 mutex_unlock(&sel_mutex); 874 if (page) 875 free_page((unsigned long) page); 876 return length; 877 } 878 879 static struct file_operations sel_bool_ops = { 880 .read = sel_read_bool, 881 .write = sel_write_bool, 882 }; 883 884 static ssize_t sel_commit_bools_write(struct file *filep, 885 const char __user *buf, 886 size_t count, loff_t *ppos) 887 { 888 char *page = NULL; 889 ssize_t length = -EFAULT; 890 int new_value; 891 892 mutex_lock(&sel_mutex); 893 894 length = task_has_security(current, SECURITY__SETBOOL); 895 if (length) 896 goto out; 897 898 /* check to see if this file has been deleted */ 899 if (!filep->f_op) 900 goto out; 901 902 if (count >= PAGE_SIZE) { 903 length = -ENOMEM; 904 goto out; 905 } 906 if (*ppos != 0) { 907 /* No partial writes. */ 908 goto out; 909 } 910 page = (char*)get_zeroed_page(GFP_KERNEL); 911 if (!page) { 912 length = -ENOMEM; 913 goto out; 914 } 915 916 if (copy_from_user(page, buf, count)) 917 goto out; 918 919 length = -EINVAL; 920 if (sscanf(page, "%d", &new_value) != 1) 921 goto out; 922 923 if (new_value && bool_pending_values) { 924 security_set_bools(bool_num, bool_pending_values); 925 } 926 927 length = count; 928 929 out: 930 mutex_unlock(&sel_mutex); 931 if (page) 932 free_page((unsigned long) page); 933 return length; 934 } 935 936 static struct file_operations sel_commit_bools_ops = { 937 .write = sel_commit_bools_write, 938 }; 939 940 /* delete booleans - partial revoke() from 941 * fs/proc/generic.c proc_kill_inodes */ 942 static void sel_remove_bools(struct dentry *de) 943 { 944 struct list_head *p, *node; 945 struct super_block *sb = de->d_sb; 946 947 spin_lock(&dcache_lock); 948 node = de->d_subdirs.next; 949 while (node != &de->d_subdirs) { 950 struct dentry *d = list_entry(node, struct dentry, d_u.d_child); 951 list_del_init(node); 952 953 if (d->d_inode) { 954 d = dget_locked(d); 955 spin_unlock(&dcache_lock); 956 d_delete(d); 957 simple_unlink(de->d_inode, d); 958 dput(d); 959 spin_lock(&dcache_lock); 960 } 961 node = de->d_subdirs.next; 962 } 963 964 spin_unlock(&dcache_lock); 965 966 file_list_lock(); 967 list_for_each(p, &sb->s_files) { 968 struct file * filp = list_entry(p, struct file, f_u.fu_list); 969 struct dentry * dentry = filp->f_dentry; 970 971 if (dentry->d_parent != de) { 972 continue; 973 } 974 filp->f_op = NULL; 975 } 976 file_list_unlock(); 977 } 978 979 #define BOOL_DIR_NAME "booleans" 980 981 static int sel_make_bools(void) 982 { 983 int i, ret = 0; 984 ssize_t len; 985 struct dentry *dentry = NULL; 986 struct dentry *dir = bool_dir; 987 struct inode *inode = NULL; 988 struct inode_security_struct *isec; 989 char **names = NULL, *page; 990 int num; 991 int *values = NULL; 992 u32 sid; 993 994 /* remove any existing files */ 995 kfree(bool_pending_values); 996 bool_pending_values = NULL; 997 998 sel_remove_bools(dir); 999 1000 if (!(page = (char*)get_zeroed_page(GFP_KERNEL))) 1001 return -ENOMEM; 1002 1003 ret = security_get_bools(&num, &names, &values); 1004 if (ret != 0) 1005 goto out; 1006 1007 for (i = 0; i < num; i++) { 1008 dentry = d_alloc_name(dir, names[i]); 1009 if (!dentry) { 1010 ret = -ENOMEM; 1011 goto err; 1012 } 1013 inode = sel_make_inode(dir->d_sb, S_IFREG | S_IRUGO | S_IWUSR); 1014 if (!inode) { 1015 ret = -ENOMEM; 1016 goto err; 1017 } 1018 1019 len = snprintf(page, PAGE_SIZE, "/%s/%s", BOOL_DIR_NAME, names[i]); 1020 if (len < 0) { 1021 ret = -EINVAL; 1022 goto err; 1023 } else if (len >= PAGE_SIZE) { 1024 ret = -ENAMETOOLONG; 1025 goto err; 1026 } 1027 isec = (struct inode_security_struct*)inode->i_security; 1028 if ((ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid))) 1029 goto err; 1030 isec->sid = sid; 1031 isec->initialized = 1; 1032 inode->i_fop = &sel_bool_ops; 1033 inode->i_ino = i + BOOL_INO_OFFSET; 1034 d_add(dentry, inode); 1035 } 1036 bool_num = num; 1037 bool_pending_values = values; 1038 out: 1039 free_page((unsigned long)page); 1040 if (names) { 1041 for (i = 0; i < num; i++) 1042 kfree(names[i]); 1043 kfree(names); 1044 } 1045 return ret; 1046 err: 1047 kfree(values); 1048 sel_remove_bools(dir); 1049 ret = -ENOMEM; 1050 goto out; 1051 } 1052 1053 #define NULL_FILE_NAME "null" 1054 1055 struct dentry *selinux_null = NULL; 1056 1057 static ssize_t sel_read_avc_cache_threshold(struct file *filp, char __user *buf, 1058 size_t count, loff_t *ppos) 1059 { 1060 char tmpbuf[TMPBUFLEN]; 1061 ssize_t length; 1062 1063 length = scnprintf(tmpbuf, TMPBUFLEN, "%u", avc_cache_threshold); 1064 return simple_read_from_buffer(buf, count, ppos, tmpbuf, length); 1065 } 1066 1067 static ssize_t sel_write_avc_cache_threshold(struct file * file, 1068 const char __user * buf, 1069 size_t count, loff_t *ppos) 1070 1071 { 1072 char *page; 1073 ssize_t ret; 1074 int new_value; 1075 1076 if (count >= PAGE_SIZE) { 1077 ret = -ENOMEM; 1078 goto out; 1079 } 1080 1081 if (*ppos != 0) { 1082 /* No partial writes. */ 1083 ret = -EINVAL; 1084 goto out; 1085 } 1086 1087 page = (char*)get_zeroed_page(GFP_KERNEL); 1088 if (!page) { 1089 ret = -ENOMEM; 1090 goto out; 1091 } 1092 1093 if (copy_from_user(page, buf, count)) { 1094 ret = -EFAULT; 1095 goto out_free; 1096 } 1097 1098 if (sscanf(page, "%u", &new_value) != 1) { 1099 ret = -EINVAL; 1100 goto out; 1101 } 1102 1103 if (new_value != avc_cache_threshold) { 1104 ret = task_has_security(current, SECURITY__SETSECPARAM); 1105 if (ret) 1106 goto out_free; 1107 avc_cache_threshold = new_value; 1108 } 1109 ret = count; 1110 out_free: 1111 free_page((unsigned long)page); 1112 out: 1113 return ret; 1114 } 1115 1116 static ssize_t sel_read_avc_hash_stats(struct file *filp, char __user *buf, 1117 size_t count, loff_t *ppos) 1118 { 1119 char *page; 1120 ssize_t ret = 0; 1121 1122 page = (char *)__get_free_page(GFP_KERNEL); 1123 if (!page) { 1124 ret = -ENOMEM; 1125 goto out; 1126 } 1127 ret = avc_get_hash_stats(page); 1128 if (ret >= 0) 1129 ret = simple_read_from_buffer(buf, count, ppos, page, ret); 1130 free_page((unsigned long)page); 1131 out: 1132 return ret; 1133 } 1134 1135 static struct file_operations sel_avc_cache_threshold_ops = { 1136 .read = sel_read_avc_cache_threshold, 1137 .write = sel_write_avc_cache_threshold, 1138 }; 1139 1140 static struct file_operations sel_avc_hash_stats_ops = { 1141 .read = sel_read_avc_hash_stats, 1142 }; 1143 1144 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS 1145 static struct avc_cache_stats *sel_avc_get_stat_idx(loff_t *idx) 1146 { 1147 int cpu; 1148 1149 for (cpu = *idx; cpu < NR_CPUS; ++cpu) { 1150 if (!cpu_possible(cpu)) 1151 continue; 1152 *idx = cpu + 1; 1153 return &per_cpu(avc_cache_stats, cpu); 1154 } 1155 return NULL; 1156 } 1157 1158 static void *sel_avc_stats_seq_start(struct seq_file *seq, loff_t *pos) 1159 { 1160 loff_t n = *pos - 1; 1161 1162 if (*pos == 0) 1163 return SEQ_START_TOKEN; 1164 1165 return sel_avc_get_stat_idx(&n); 1166 } 1167 1168 static void *sel_avc_stats_seq_next(struct seq_file *seq, void *v, loff_t *pos) 1169 { 1170 return sel_avc_get_stat_idx(pos); 1171 } 1172 1173 static int sel_avc_stats_seq_show(struct seq_file *seq, void *v) 1174 { 1175 struct avc_cache_stats *st = v; 1176 1177 if (v == SEQ_START_TOKEN) 1178 seq_printf(seq, "lookups hits misses allocations reclaims " 1179 "frees\n"); 1180 else 1181 seq_printf(seq, "%u %u %u %u %u %u\n", st->lookups, 1182 st->hits, st->misses, st->allocations, 1183 st->reclaims, st->frees); 1184 return 0; 1185 } 1186 1187 static void sel_avc_stats_seq_stop(struct seq_file *seq, void *v) 1188 { } 1189 1190 static struct seq_operations sel_avc_cache_stats_seq_ops = { 1191 .start = sel_avc_stats_seq_start, 1192 .next = sel_avc_stats_seq_next, 1193 .show = sel_avc_stats_seq_show, 1194 .stop = sel_avc_stats_seq_stop, 1195 }; 1196 1197 static int sel_open_avc_cache_stats(struct inode *inode, struct file *file) 1198 { 1199 return seq_open(file, &sel_avc_cache_stats_seq_ops); 1200 } 1201 1202 static struct file_operations sel_avc_cache_stats_ops = { 1203 .open = sel_open_avc_cache_stats, 1204 .read = seq_read, 1205 .llseek = seq_lseek, 1206 .release = seq_release, 1207 }; 1208 #endif 1209 1210 static int sel_make_avc_files(struct dentry *dir) 1211 { 1212 int i, ret = 0; 1213 static struct tree_descr files[] = { 1214 { "cache_threshold", 1215 &sel_avc_cache_threshold_ops, S_IRUGO|S_IWUSR }, 1216 { "hash_stats", &sel_avc_hash_stats_ops, S_IRUGO }, 1217 #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS 1218 { "cache_stats", &sel_avc_cache_stats_ops, S_IRUGO }, 1219 #endif 1220 }; 1221 1222 for (i = 0; i < ARRAY_SIZE(files); i++) { 1223 struct inode *inode; 1224 struct dentry *dentry; 1225 1226 dentry = d_alloc_name(dir, files[i].name); 1227 if (!dentry) { 1228 ret = -ENOMEM; 1229 goto out; 1230 } 1231 1232 inode = sel_make_inode(dir->d_sb, S_IFREG|files[i].mode); 1233 if (!inode) { 1234 ret = -ENOMEM; 1235 goto out; 1236 } 1237 inode->i_fop = files[i].ops; 1238 d_add(dentry, inode); 1239 } 1240 out: 1241 return ret; 1242 } 1243 1244 static int sel_make_dir(struct inode *dir, struct dentry *dentry) 1245 { 1246 int ret = 0; 1247 struct inode *inode; 1248 1249 inode = sel_make_inode(dir->i_sb, S_IFDIR | S_IRUGO | S_IXUGO); 1250 if (!inode) { 1251 ret = -ENOMEM; 1252 goto out; 1253 } 1254 inode->i_op = &simple_dir_inode_operations; 1255 inode->i_fop = &simple_dir_operations; 1256 /* directory inodes start off with i_nlink == 2 (for "." entry) */ 1257 inode->i_nlink++; 1258 d_add(dentry, inode); 1259 /* bump link count on parent directory, too */ 1260 dir->i_nlink++; 1261 out: 1262 return ret; 1263 } 1264 1265 static int sel_fill_super(struct super_block * sb, void * data, int silent) 1266 { 1267 int ret; 1268 struct dentry *dentry; 1269 struct inode *inode, *root_inode; 1270 struct inode_security_struct *isec; 1271 1272 static struct tree_descr selinux_files[] = { 1273 [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR}, 1274 [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR}, 1275 [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO}, 1276 [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO}, 1277 [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO}, 1278 [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO}, 1279 [SEL_USER] = {"user", &transaction_ops, S_IRUGO|S_IWUGO}, 1280 [SEL_POLICYVERS] = {"policyvers", &sel_policyvers_ops, S_IRUGO}, 1281 [SEL_COMMIT_BOOLS] = {"commit_pending_bools", &sel_commit_bools_ops, S_IWUSR}, 1282 [SEL_MLS] = {"mls", &sel_mls_ops, S_IRUGO}, 1283 [SEL_DISABLE] = {"disable", &sel_disable_ops, S_IWUSR}, 1284 [SEL_MEMBER] = {"member", &transaction_ops, S_IRUGO|S_IWUGO}, 1285 [SEL_CHECKREQPROT] = {"checkreqprot", &sel_checkreqprot_ops, S_IRUGO|S_IWUSR}, 1286 [SEL_COMPAT_NET] = {"compat_net", &sel_compat_net_ops, S_IRUGO|S_IWUSR}, 1287 /* last one */ {""} 1288 }; 1289 ret = simple_fill_super(sb, SELINUX_MAGIC, selinux_files); 1290 if (ret) 1291 goto err; 1292 1293 root_inode = sb->s_root->d_inode; 1294 1295 dentry = d_alloc_name(sb->s_root, BOOL_DIR_NAME); 1296 if (!dentry) { 1297 ret = -ENOMEM; 1298 goto err; 1299 } 1300 1301 ret = sel_make_dir(root_inode, dentry); 1302 if (ret) 1303 goto err; 1304 1305 bool_dir = dentry; 1306 1307 dentry = d_alloc_name(sb->s_root, NULL_FILE_NAME); 1308 if (!dentry) { 1309 ret = -ENOMEM; 1310 goto err; 1311 } 1312 1313 inode = sel_make_inode(sb, S_IFCHR | S_IRUGO | S_IWUGO); 1314 if (!inode) { 1315 ret = -ENOMEM; 1316 goto err; 1317 } 1318 isec = (struct inode_security_struct*)inode->i_security; 1319 isec->sid = SECINITSID_DEVNULL; 1320 isec->sclass = SECCLASS_CHR_FILE; 1321 isec->initialized = 1; 1322 1323 init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO, MKDEV(MEM_MAJOR, 3)); 1324 d_add(dentry, inode); 1325 selinux_null = dentry; 1326 1327 dentry = d_alloc_name(sb->s_root, "avc"); 1328 if (!dentry) { 1329 ret = -ENOMEM; 1330 goto err; 1331 } 1332 1333 ret = sel_make_dir(root_inode, dentry); 1334 if (ret) 1335 goto err; 1336 1337 ret = sel_make_avc_files(dentry); 1338 if (ret) 1339 goto err; 1340 out: 1341 return ret; 1342 err: 1343 printk(KERN_ERR "%s: failed while creating inodes\n", __FUNCTION__); 1344 goto out; 1345 } 1346 1347 static int sel_get_sb(struct file_system_type *fs_type, 1348 int flags, const char *dev_name, void *data, 1349 struct vfsmount *mnt) 1350 { 1351 return get_sb_single(fs_type, flags, data, sel_fill_super, mnt); 1352 } 1353 1354 static struct file_system_type sel_fs_type = { 1355 .name = "selinuxfs", 1356 .get_sb = sel_get_sb, 1357 .kill_sb = kill_litter_super, 1358 }; 1359 1360 struct vfsmount *selinuxfs_mount; 1361 1362 static int __init init_sel_fs(void) 1363 { 1364 int err; 1365 1366 if (!selinux_enabled) 1367 return 0; 1368 err = register_filesystem(&sel_fs_type); 1369 if (!err) { 1370 selinuxfs_mount = kern_mount(&sel_fs_type); 1371 if (IS_ERR(selinuxfs_mount)) { 1372 printk(KERN_ERR "selinuxfs: could not mount!\n"); 1373 err = PTR_ERR(selinuxfs_mount); 1374 selinuxfs_mount = NULL; 1375 } 1376 } 1377 return err; 1378 } 1379 1380 __initcall(init_sel_fs); 1381 1382 #ifdef CONFIG_SECURITY_SELINUX_DISABLE 1383 void exit_sel_fs(void) 1384 { 1385 unregister_filesystem(&sel_fs_type); 1386 } 1387 #endif 1388