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

Merge branch 'next' into for-linus

+1231 -425
+12
Documentation/feature-removal-schedule.txt
··· 315 315 Why: Deprecated by the new (standard) device driver binding model. Use 316 316 i2c_driver->probe() and ->remove() instead. 317 317 Who: Jean Delvare <khali@linux-fr.org> 318 + 319 + --------------------------- 320 + 321 + What: SELinux "compat_net" functionality 322 + When: 2.6.30 at the earliest 323 + Why: In 2.6.18 the Secmark concept was introduced to replace the "compat_net" 324 + network access control functionality of SELinux. Secmark offers both 325 + better performance and greater flexibility than the "compat_net" 326 + mechanism. Now that the major Linux distributions have moved to 327 + Secmark, it is time to deprecate the older mechanism and start the 328 + process of removing the old code. 329 + Who: Paul Moore <paul.moore@hp.com>
+15 -2
include/linux/capability.h
··· 529 529 * 530 530 * Note that this does not set PF_SUPERPRIV on the task. 531 531 */ 532 - #define has_capability(t, cap) (security_capable((t), (cap)) == 0) 533 - #define has_capability_noaudit(t, cap) (security_capable_noaudit((t), (cap)) == 0) 532 + #define has_capability(t, cap) (security_real_capable((t), (cap)) == 0) 533 + 534 + /** 535 + * has_capability_noaudit - Determine if a task has a superior capability available (unaudited) 536 + * @t: The task in question 537 + * @cap: The capability to be tested for 538 + * 539 + * Return true if the specified task has the given superior capability 540 + * currently in effect, false if not, but don't write an audit message for the 541 + * check. 542 + * 543 + * Note that this does not set PF_SUPERPRIV on the task. 544 + */ 545 + #define has_capability_noaudit(t, cap) \ 546 + (security_real_capable_noaudit((t), (cap)) == 0) 534 547 535 548 extern int capable(int cap); 536 549
+32 -9
include/linux/security.h
··· 48 48 * These functions are in security/capability.c and are used 49 49 * as the default capabilities functions 50 50 */ 51 - extern int cap_capable(struct task_struct *tsk, int cap, int audit); 51 + extern int cap_capable(struct task_struct *tsk, const struct cred *cred, 52 + int cap, int audit); 52 53 extern int cap_settime(struct timespec *ts, struct timezone *tz); 53 54 extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); 54 55 extern int cap_ptrace_traceme(struct task_struct *parent); ··· 1252 1251 * @permitted contains the permitted capability set. 1253 1252 * Return 0 and update @new if permission is granted. 1254 1253 * @capable: 1255 - * Check whether the @tsk process has the @cap capability. 1254 + * Check whether the @tsk process has the @cap capability in the indicated 1255 + * credentials. 1256 1256 * @tsk contains the task_struct for the process. 1257 + * @cred contains the credentials to use. 1257 1258 * @cap contains the capability <include/linux/capability.h>. 1259 + * @audit: Whether to write an audit message or not 1258 1260 * Return 0 if the capability is granted for @tsk. 1259 1261 * @acct: 1260 1262 * Check permission before enabling or disabling process accounting. If ··· 1350 1346 const kernel_cap_t *effective, 1351 1347 const kernel_cap_t *inheritable, 1352 1348 const kernel_cap_t *permitted); 1353 - int (*capable) (struct task_struct *tsk, int cap, int audit); 1349 + int (*capable) (struct task_struct *tsk, const struct cred *cred, 1350 + int cap, int audit); 1354 1351 int (*acct) (struct file *file); 1355 1352 int (*sysctl) (struct ctl_table *table, int op); 1356 1353 int (*quotactl) (int cmds, int type, int id, struct super_block *sb); ··· 1633 1628 const kernel_cap_t *effective, 1634 1629 const kernel_cap_t *inheritable, 1635 1630 const kernel_cap_t *permitted); 1636 - int security_capable(struct task_struct *tsk, int cap); 1637 - int security_capable_noaudit(struct task_struct *tsk, int cap); 1631 + int security_capable(int cap); 1632 + int security_real_capable(struct task_struct *tsk, int cap); 1633 + int security_real_capable_noaudit(struct task_struct *tsk, int cap); 1638 1634 int security_acct(struct file *file); 1639 1635 int security_sysctl(struct ctl_table *table, int op); 1640 1636 int security_quotactl(int cmds, int type, int id, struct super_block *sb); ··· 1832 1826 return cap_capset(new, old, effective, inheritable, permitted); 1833 1827 } 1834 1828 1835 - static inline int security_capable(struct task_struct *tsk, int cap) 1829 + static inline int security_capable(int cap) 1836 1830 { 1837 - return cap_capable(tsk, cap, SECURITY_CAP_AUDIT); 1831 + return cap_capable(current, current_cred(), cap, SECURITY_CAP_AUDIT); 1838 1832 } 1839 1833 1840 - static inline int security_capable_noaudit(struct task_struct *tsk, int cap) 1834 + static inline int security_real_capable(struct task_struct *tsk, int cap) 1841 1835 { 1842 - return cap_capable(tsk, cap, SECURITY_CAP_NOAUDIT); 1836 + int ret; 1837 + 1838 + rcu_read_lock(); 1839 + ret = cap_capable(tsk, __task_cred(tsk), cap, SECURITY_CAP_AUDIT); 1840 + rcu_read_unlock(); 1841 + return ret; 1842 + } 1843 + 1844 + static inline 1845 + int security_real_capable_noaudit(struct task_struct *tsk, int cap) 1846 + { 1847 + int ret; 1848 + 1849 + rcu_read_lock(); 1850 + ret = cap_capable(tsk, __task_cred(tsk), cap, 1851 + SECURITY_CAP_NOAUDIT); 1852 + rcu_read_unlock(); 1853 + return ret; 1843 1854 } 1844 1855 1845 1856 static inline int security_acct(struct file *file)
+4 -2
include/net/cipso_ipv4.h
··· 131 131 */ 132 132 133 133 #ifdef CONFIG_NETLABEL 134 - int cipso_v4_doi_add(struct cipso_v4_doi *doi_def); 134 + int cipso_v4_doi_add(struct cipso_v4_doi *doi_def, 135 + struct netlbl_audit *audit_info); 135 136 void cipso_v4_doi_free(struct cipso_v4_doi *doi_def); 136 137 int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info); 137 138 struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi); ··· 141 140 int (*callback) (struct cipso_v4_doi *doi_def, void *arg), 142 141 void *cb_arg); 143 142 #else 144 - static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) 143 + static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def, 144 + struct netlbl_audit *audit_info) 145 145 { 146 146 return -ENOSYS; 147 147 }
+80 -6
include/net/netlabel.h
··· 33 33 #include <linux/types.h> 34 34 #include <linux/net.h> 35 35 #include <linux/skbuff.h> 36 + #include <linux/in.h> 37 + #include <linux/in6.h> 36 38 #include <net/netlink.h> 37 39 #include <asm/atomic.h> 38 40 ··· 355 353 /* 356 354 * LSM configuration operations 357 355 */ 358 - int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info); 359 - int netlbl_cfg_unlbl_add_map(const char *domain, 356 + int netlbl_cfg_map_del(const char *domain, 357 + u16 family, 358 + const void *addr, 359 + const void *mask, 360 + struct netlbl_audit *audit_info); 361 + int netlbl_cfg_unlbl_map_add(const char *domain, 362 + u16 family, 363 + const void *addr, 364 + const void *mask, 360 365 struct netlbl_audit *audit_info); 361 - int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 366 + int netlbl_cfg_unlbl_static_add(struct net *net, 367 + const char *dev_name, 368 + const void *addr, 369 + const void *mask, 370 + u16 family, 371 + u32 secid, 372 + struct netlbl_audit *audit_info); 373 + int netlbl_cfg_unlbl_static_del(struct net *net, 374 + const char *dev_name, 375 + const void *addr, 376 + const void *mask, 377 + u16 family, 378 + struct netlbl_audit *audit_info); 379 + int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 380 + struct netlbl_audit *audit_info); 381 + void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info); 382 + int netlbl_cfg_cipsov4_map_add(u32 doi, 362 383 const char *domain, 384 + const struct in_addr *addr, 385 + const struct in_addr *mask, 363 386 struct netlbl_audit *audit_info); 364 - 365 387 /* 366 388 * LSM security attribute operations 367 389 */ ··· 427 401 void netlbl_cache_invalidate(void); 428 402 int netlbl_cache_add(const struct sk_buff *skb, 429 403 const struct netlbl_lsm_secattr *secattr); 404 + 405 + /* 406 + * Protocol engine operations 407 + */ 408 + struct audit_buffer *netlbl_audit_start(int type, 409 + struct netlbl_audit *audit_info); 430 410 #else 431 411 static inline int netlbl_cfg_map_del(const char *domain, 412 + u16 family, 413 + const void *addr, 414 + const void *mask, 432 415 struct netlbl_audit *audit_info) 433 416 { 434 417 return -ENOSYS; 435 418 } 436 - static inline int netlbl_cfg_unlbl_add_map(const char *domain, 419 + static inline int netlbl_cfg_unlbl_map_add(const char *domain, 420 + u16 family, 421 + void *addr, 422 + void *mask, 437 423 struct netlbl_audit *audit_info) 438 424 { 439 425 return -ENOSYS; 440 426 } 441 - static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 427 + static inline int netlbl_cfg_unlbl_static_add(struct net *net, 428 + const char *dev_name, 429 + const void *addr, 430 + const void *mask, 431 + u16 family, 432 + u32 secid, 433 + struct netlbl_audit *audit_info) 434 + { 435 + return -ENOSYS; 436 + } 437 + static inline int netlbl_cfg_unlbl_static_del(struct net *net, 438 + const char *dev_name, 439 + const void *addr, 440 + const void *mask, 441 + u16 family, 442 + struct netlbl_audit *audit_info) 443 + { 444 + return -ENOSYS; 445 + } 446 + static inline int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 447 + struct netlbl_audit *audit_info) 448 + { 449 + return -ENOSYS; 450 + } 451 + static inline void netlbl_cfg_cipsov4_del(u32 doi, 452 + struct netlbl_audit *audit_info) 453 + { 454 + return; 455 + } 456 + static inline int netlbl_cfg_cipsov4_map_add(u32 doi, 442 457 const char *domain, 458 + const struct in_addr *addr, 459 + const struct in_addr *mask, 443 460 struct netlbl_audit *audit_info) 444 461 { 445 462 return -ENOSYS; ··· 563 494 const struct netlbl_lsm_secattr *secattr) 564 495 { 565 496 return 0; 497 + } 498 + static inline struct audit_buffer *netlbl_audit_start(int type, 499 + struct netlbl_audit *audit_info) 500 + { 501 + return NULL; 566 502 } 567 503 #endif /* CONFIG_NETLABEL */ 568 504
+1 -1
kernel/capability.c
··· 306 306 BUG(); 307 307 } 308 308 309 - if (has_capability(current, cap)) { 309 + if (security_capable(cap) == 0) { 310 310 current->flags |= PF_SUPERPRIV; 311 311 return 1; 312 312 }
+65 -21
net/ipv4/cipso_ipv4.c
··· 38 38 #include <linux/spinlock.h> 39 39 #include <linux/string.h> 40 40 #include <linux/jhash.h> 41 + #include <linux/audit.h> 41 42 #include <net/ip.h> 42 43 #include <net/icmp.h> 43 44 #include <net/tcp.h> ··· 450 449 /** 451 450 * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine 452 451 * @doi_def: the DOI structure 452 + * @audit_info: NetLabel audit information 453 453 * 454 454 * Description: 455 455 * The caller defines a new DOI for use by the CIPSO engine and calls this ··· 460 458 * zero on success and non-zero on failure. 461 459 * 462 460 */ 463 - int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) 461 + int cipso_v4_doi_add(struct cipso_v4_doi *doi_def, 462 + struct netlbl_audit *audit_info) 464 463 { 464 + int ret_val = -EINVAL; 465 465 u32 iter; 466 + u32 doi; 467 + u32 doi_type; 468 + struct audit_buffer *audit_buf; 469 + 470 + doi = doi_def->doi; 471 + doi_type = doi_def->type; 466 472 467 473 if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN) 468 - return -EINVAL; 474 + goto doi_add_return; 469 475 for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) { 470 476 switch (doi_def->tags[iter]) { 471 477 case CIPSO_V4_TAG_RBITMAP: 472 478 break; 473 479 case CIPSO_V4_TAG_RANGE: 474 - if (doi_def->type != CIPSO_V4_MAP_PASS) 475 - return -EINVAL; 476 - break; 477 - case CIPSO_V4_TAG_INVALID: 478 - if (iter == 0) 479 - return -EINVAL; 480 - break; 481 480 case CIPSO_V4_TAG_ENUM: 482 481 if (doi_def->type != CIPSO_V4_MAP_PASS) 483 - return -EINVAL; 482 + goto doi_add_return; 484 483 break; 485 484 case CIPSO_V4_TAG_LOCAL: 486 485 if (doi_def->type != CIPSO_V4_MAP_LOCAL) 487 - return -EINVAL; 486 + goto doi_add_return; 487 + break; 488 + case CIPSO_V4_TAG_INVALID: 489 + if (iter == 0) 490 + goto doi_add_return; 488 491 break; 489 492 default: 490 - return -EINVAL; 493 + goto doi_add_return; 491 494 } 492 495 } 493 496 494 497 atomic_set(&doi_def->refcount, 1); 495 498 496 499 spin_lock(&cipso_v4_doi_list_lock); 497 - if (cipso_v4_doi_search(doi_def->doi) != NULL) 498 - goto doi_add_failure; 500 + if (cipso_v4_doi_search(doi_def->doi) != NULL) { 501 + spin_unlock(&cipso_v4_doi_list_lock); 502 + ret_val = -EEXIST; 503 + goto doi_add_return; 504 + } 499 505 list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); 500 506 spin_unlock(&cipso_v4_doi_list_lock); 507 + ret_val = 0; 501 508 502 - return 0; 509 + doi_add_return: 510 + audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_ADD, audit_info); 511 + if (audit_buf != NULL) { 512 + const char *type_str; 513 + switch (doi_type) { 514 + case CIPSO_V4_MAP_TRANS: 515 + type_str = "trans"; 516 + break; 517 + case CIPSO_V4_MAP_PASS: 518 + type_str = "pass"; 519 + break; 520 + case CIPSO_V4_MAP_LOCAL: 521 + type_str = "local"; 522 + break; 523 + default: 524 + type_str = "(unknown)"; 525 + } 526 + audit_log_format(audit_buf, 527 + " cipso_doi=%u cipso_type=%s res=%u", 528 + doi, type_str, ret_val == 0 ? 1 : 0); 529 + audit_log_end(audit_buf); 530 + } 503 531 504 - doi_add_failure: 505 - spin_unlock(&cipso_v4_doi_list_lock); 506 - return -EEXIST; 532 + return ret_val; 507 533 } 508 534 509 535 /** ··· 589 559 */ 590 560 int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) 591 561 { 562 + int ret_val; 592 563 struct cipso_v4_doi *doi_def; 564 + struct audit_buffer *audit_buf; 593 565 594 566 spin_lock(&cipso_v4_doi_list_lock); 595 567 doi_def = cipso_v4_doi_search(doi); 596 568 if (doi_def == NULL) { 597 569 spin_unlock(&cipso_v4_doi_list_lock); 598 - return -ENOENT; 570 + ret_val = -ENOENT; 571 + goto doi_remove_return; 599 572 } 600 573 if (!atomic_dec_and_test(&doi_def->refcount)) { 601 574 spin_unlock(&cipso_v4_doi_list_lock); 602 - return -EBUSY; 575 + ret_val = -EBUSY; 576 + goto doi_remove_return; 603 577 } 604 578 list_del_rcu(&doi_def->list); 605 579 spin_unlock(&cipso_v4_doi_list_lock); 606 580 607 581 cipso_v4_cache_invalidate(); 608 582 call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); 583 + ret_val = 0; 609 584 610 - return 0; 585 + doi_remove_return: 586 + audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_DEL, audit_info); 587 + if (audit_buf != NULL) { 588 + audit_log_format(audit_buf, 589 + " cipso_doi=%u res=%u", 590 + doi, ret_val == 0 ? 1 : 0); 591 + audit_log_end(audit_buf); 592 + } 593 + 594 + return ret_val; 611 595 } 612 596 613 597 /**
+18 -43
net/netlabel/netlabel_cipso_v4.c
··· 130 130 /** 131 131 * netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition 132 132 * @info: the Generic NETLINK info block 133 + * @audit_info: NetLabel audit information 133 134 * 134 135 * Description: 135 136 * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD ··· 138 137 * non-zero on error. 139 138 * 140 139 */ 141 - static int netlbl_cipsov4_add_std(struct genl_info *info) 140 + static int netlbl_cipsov4_add_std(struct genl_info *info, 141 + struct netlbl_audit *audit_info) 142 142 { 143 143 int ret_val = -EINVAL; 144 144 struct cipso_v4_doi *doi_def = NULL; ··· 318 316 } 319 317 } 320 318 321 - ret_val = cipso_v4_doi_add(doi_def); 319 + ret_val = cipso_v4_doi_add(doi_def, audit_info); 322 320 if (ret_val != 0) 323 321 goto add_std_failure; 324 322 return 0; ··· 332 330 /** 333 331 * netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition 334 332 * @info: the Generic NETLINK info block 333 + * @audit_info: NetLabel audit information 335 334 * 336 335 * Description: 337 336 * Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message ··· 340 337 * error. 341 338 * 342 339 */ 343 - static int netlbl_cipsov4_add_pass(struct genl_info *info) 340 + static int netlbl_cipsov4_add_pass(struct genl_info *info, 341 + struct netlbl_audit *audit_info) 344 342 { 345 343 int ret_val; 346 344 struct cipso_v4_doi *doi_def = NULL; ··· 358 354 if (ret_val != 0) 359 355 goto add_pass_failure; 360 356 361 - ret_val = cipso_v4_doi_add(doi_def); 357 + ret_val = cipso_v4_doi_add(doi_def, audit_info); 362 358 if (ret_val != 0) 363 359 goto add_pass_failure; 364 360 return 0; ··· 371 367 /** 372 368 * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition 373 369 * @info: the Generic NETLINK info block 370 + * @audit_info: NetLabel audit information 374 371 * 375 372 * Description: 376 373 * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD ··· 379 374 * non-zero on error. 380 375 * 381 376 */ 382 - static int netlbl_cipsov4_add_local(struct genl_info *info) 377 + static int netlbl_cipsov4_add_local(struct genl_info *info, 378 + struct netlbl_audit *audit_info) 383 379 { 384 380 int ret_val; 385 381 struct cipso_v4_doi *doi_def = NULL; ··· 397 391 if (ret_val != 0) 398 392 goto add_local_failure; 399 393 400 - ret_val = cipso_v4_doi_add(doi_def); 394 + ret_val = cipso_v4_doi_add(doi_def, audit_info); 401 395 if (ret_val != 0) 402 396 goto add_local_failure; 403 397 return 0; ··· 421 415 422 416 { 423 417 int ret_val = -EINVAL; 424 - u32 type; 425 - u32 doi; 426 418 const char *type_str = "(unknown)"; 427 - struct audit_buffer *audit_buf; 428 419 struct netlbl_audit audit_info; 429 420 430 421 if (!info->attrs[NLBL_CIPSOV4_A_DOI] || 431 422 !info->attrs[NLBL_CIPSOV4_A_MTYPE]) 432 423 return -EINVAL; 433 424 434 - doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); 435 425 netlbl_netlink_auditinfo(skb, &audit_info); 436 - 437 - type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]); 438 - switch (type) { 426 + switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) { 439 427 case CIPSO_V4_MAP_TRANS: 440 428 type_str = "trans"; 441 - ret_val = netlbl_cipsov4_add_std(info); 429 + ret_val = netlbl_cipsov4_add_std(info, &audit_info); 442 430 break; 443 431 case CIPSO_V4_MAP_PASS: 444 432 type_str = "pass"; 445 - ret_val = netlbl_cipsov4_add_pass(info); 433 + ret_val = netlbl_cipsov4_add_pass(info, &audit_info); 446 434 break; 447 435 case CIPSO_V4_MAP_LOCAL: 448 436 type_str = "local"; 449 - ret_val = netlbl_cipsov4_add_local(info); 437 + ret_val = netlbl_cipsov4_add_local(info, &audit_info); 450 438 break; 451 439 } 452 440 if (ret_val == 0) 453 441 atomic_inc(&netlabel_mgmt_protocount); 454 - 455 - audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD, 456 - &audit_info); 457 - if (audit_buf != NULL) { 458 - audit_log_format(audit_buf, 459 - " cipso_doi=%u cipso_type=%s res=%u", 460 - doi, 461 - type_str, 462 - ret_val == 0 ? 1 : 0); 463 - audit_log_end(audit_buf); 464 - } 465 442 466 443 return ret_val; 467 444 } ··· 714 725 static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) 715 726 { 716 727 int ret_val = -EINVAL; 717 - u32 doi = 0; 718 728 struct netlbl_domhsh_walk_arg cb_arg; 719 - struct audit_buffer *audit_buf; 720 729 struct netlbl_audit audit_info; 721 730 u32 skip_bkt = 0; 722 731 u32 skip_chain = 0; ··· 722 735 if (!info->attrs[NLBL_CIPSOV4_A_DOI]) 723 736 return -EINVAL; 724 737 725 - doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); 726 738 netlbl_netlink_auditinfo(skb, &audit_info); 727 - 728 - cb_arg.doi = doi; 739 + cb_arg.doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); 729 740 cb_arg.audit_info = &audit_info; 730 741 ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain, 731 742 netlbl_cipsov4_remove_cb, &cb_arg); 732 743 if (ret_val == 0 || ret_val == -ENOENT) { 733 - ret_val = cipso_v4_doi_remove(doi, &audit_info); 744 + ret_val = cipso_v4_doi_remove(cb_arg.doi, &audit_info); 734 745 if (ret_val == 0) 735 746 atomic_dec(&netlabel_mgmt_protocount); 736 - } 737 - 738 - audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL, 739 - &audit_info); 740 - if (audit_buf != NULL) { 741 - audit_log_format(audit_buf, 742 - " cipso_doi=%u res=%u", 743 - doi, 744 - ret_val == 0 ? 1 : 0); 745 - audit_log_end(audit_buf); 746 747 } 747 748 748 749 return ret_val;
+67
net/netlabel/netlabel_domainhash.c
··· 483 483 } 484 484 485 485 /** 486 + * netlbl_domhsh_remove_af4 - Removes an address selector entry 487 + * @domain: the domain 488 + * @addr: IPv4 address 489 + * @mask: IPv4 address mask 490 + * @audit_info: NetLabel audit information 491 + * 492 + * Description: 493 + * Removes an individual address selector from a domain mapping and potentially 494 + * the entire mapping if it is empty. Returns zero on success, negative values 495 + * on failure. 496 + * 497 + */ 498 + int netlbl_domhsh_remove_af4(const char *domain, 499 + const struct in_addr *addr, 500 + const struct in_addr *mask, 501 + struct netlbl_audit *audit_info) 502 + { 503 + struct netlbl_dom_map *entry_map; 504 + struct netlbl_af4list *entry_addr; 505 + struct netlbl_af4list *iter4; 506 + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 507 + struct netlbl_af6list *iter6; 508 + #endif /* IPv6 */ 509 + struct netlbl_domaddr4_map *entry; 510 + 511 + rcu_read_lock(); 512 + 513 + if (domain) 514 + entry_map = netlbl_domhsh_search(domain); 515 + else 516 + entry_map = netlbl_domhsh_search_def(domain); 517 + if (entry_map == NULL || entry_map->type != NETLBL_NLTYPE_ADDRSELECT) 518 + goto remove_af4_failure; 519 + 520 + spin_lock(&netlbl_domhsh_lock); 521 + entry_addr = netlbl_af4list_remove(addr->s_addr, mask->s_addr, 522 + &entry_map->type_def.addrsel->list4); 523 + spin_unlock(&netlbl_domhsh_lock); 524 + 525 + if (entry_addr == NULL) 526 + goto remove_af4_failure; 527 + netlbl_af4list_foreach_rcu(iter4, &entry_map->type_def.addrsel->list4) 528 + goto remove_af4_single_addr; 529 + #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 530 + netlbl_af6list_foreach_rcu(iter6, &entry_map->type_def.addrsel->list6) 531 + goto remove_af4_single_addr; 532 + #endif /* IPv6 */ 533 + /* the domain mapping is empty so remove it from the mapping table */ 534 + netlbl_domhsh_remove_entry(entry_map, audit_info); 535 + 536 + remove_af4_single_addr: 537 + rcu_read_unlock(); 538 + /* yick, we can't use call_rcu here because we don't have a rcu head 539 + * pointer but hopefully this should be a rare case so the pause 540 + * shouldn't be a problem */ 541 + synchronize_rcu(); 542 + entry = netlbl_domhsh_addr4_entry(entry_addr); 543 + cipso_v4_doi_putdef(entry->type_def.cipsov4); 544 + kfree(entry); 545 + return 0; 546 + 547 + remove_af4_failure: 548 + rcu_read_unlock(); 549 + return -ENOENT; 550 + } 551 + 552 + /** 486 553 * netlbl_domhsh_remove - Removes an entry from the domain hash table 487 554 * @domain: the domain to remove 488 555 * @audit_info: NetLabel audit information
+4
net/netlabel/netlabel_domainhash.h
··· 90 90 struct netlbl_audit *audit_info); 91 91 int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry, 92 92 struct netlbl_audit *audit_info); 93 + int netlbl_domhsh_remove_af4(const char *domain, 94 + const struct in_addr *addr, 95 + const struct in_addr *mask, 96 + struct netlbl_audit *audit_info); 93 97 int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); 94 98 int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); 95 99 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
+288 -61
net/netlabel/netlabel_kapi.c
··· 31 31 #include <linux/init.h> 32 32 #include <linux/types.h> 33 33 #include <linux/audit.h> 34 + #include <linux/in.h> 35 + #include <linux/in6.h> 34 36 #include <net/ip.h> 37 + #include <net/ipv6.h> 35 38 #include <net/netlabel.h> 36 39 #include <net/cipso_ipv4.h> 37 40 #include <asm/bug.h> ··· 45 42 #include "netlabel_cipso_v4.h" 46 43 #include "netlabel_user.h" 47 44 #include "netlabel_mgmt.h" 45 + #include "netlabel_addrlist.h" 48 46 49 47 /* 50 48 * Configuration Functions ··· 54 50 /** 55 51 * netlbl_cfg_map_del - Remove a NetLabel/LSM domain mapping 56 52 * @domain: the domain mapping to remove 53 + * @family: address family 54 + * @addr: IP address 55 + * @mask: IP address mask 57 56 * @audit_info: NetLabel audit information 58 57 * 59 58 * Description: ··· 65 58 * values on failure. 66 59 * 67 60 */ 68 - int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info) 61 + int netlbl_cfg_map_del(const char *domain, 62 + u16 family, 63 + const void *addr, 64 + const void *mask, 65 + struct netlbl_audit *audit_info) 69 66 { 70 - return netlbl_domhsh_remove(domain, audit_info); 67 + if (addr == NULL && mask == NULL) { 68 + return netlbl_domhsh_remove(domain, audit_info); 69 + } else if (addr != NULL && mask != NULL) { 70 + switch (family) { 71 + case AF_INET: 72 + return netlbl_domhsh_remove_af4(domain, addr, mask, 73 + audit_info); 74 + default: 75 + return -EPFNOSUPPORT; 76 + } 77 + } else 78 + return -EINVAL; 71 79 } 72 80 73 81 /** 74 - * netlbl_cfg_unlbl_add_map - Add an unlabeled NetLabel/LSM domain mapping 82 + * netlbl_cfg_unlbl_map_add - Add a new unlabeled mapping 75 83 * @domain: the domain mapping to add 84 + * @family: address family 85 + * @addr: IP address 86 + * @mask: IP address mask 76 87 * @audit_info: NetLabel audit information 77 88 * 78 89 * Description: ··· 99 74 * negative values on failure. 100 75 * 101 76 */ 102 - int netlbl_cfg_unlbl_add_map(const char *domain, 77 + int netlbl_cfg_unlbl_map_add(const char *domain, 78 + u16 family, 79 + const void *addr, 80 + const void *mask, 103 81 struct netlbl_audit *audit_info) 104 82 { 105 83 int ret_val = -ENOMEM; 106 84 struct netlbl_dom_map *entry; 85 + struct netlbl_domaddr_map *addrmap = NULL; 86 + struct netlbl_domaddr4_map *map4 = NULL; 87 + struct netlbl_domaddr6_map *map6 = NULL; 88 + const struct in_addr *addr4, *mask4; 89 + const struct in6_addr *addr6, *mask6; 107 90 108 91 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 109 92 if (entry == NULL) ··· 119 86 if (domain != NULL) { 120 87 entry->domain = kstrdup(domain, GFP_ATOMIC); 121 88 if (entry->domain == NULL) 122 - goto cfg_unlbl_add_map_failure; 89 + goto cfg_unlbl_map_add_failure; 123 90 } 124 - entry->type = NETLBL_NLTYPE_UNLABELED; 91 + 92 + if (addr == NULL && mask == NULL) 93 + entry->type = NETLBL_NLTYPE_UNLABELED; 94 + else if (addr != NULL && mask != NULL) { 95 + addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); 96 + if (addrmap == NULL) 97 + goto cfg_unlbl_map_add_failure; 98 + INIT_LIST_HEAD(&addrmap->list4); 99 + INIT_LIST_HEAD(&addrmap->list6); 100 + 101 + switch (family) { 102 + case AF_INET: 103 + addr4 = addr; 104 + mask4 = mask; 105 + map4 = kzalloc(sizeof(*map4), GFP_ATOMIC); 106 + if (map4 == NULL) 107 + goto cfg_unlbl_map_add_failure; 108 + map4->type = NETLBL_NLTYPE_UNLABELED; 109 + map4->list.addr = addr4->s_addr & mask4->s_addr; 110 + map4->list.mask = mask4->s_addr; 111 + map4->list.valid = 1; 112 + ret_val = netlbl_af4list_add(&map4->list, 113 + &addrmap->list4); 114 + if (ret_val != 0) 115 + goto cfg_unlbl_map_add_failure; 116 + break; 117 + case AF_INET6: 118 + addr6 = addr; 119 + mask6 = mask; 120 + map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); 121 + if (map4 == NULL) 122 + goto cfg_unlbl_map_add_failure; 123 + map6->type = NETLBL_NLTYPE_UNLABELED; 124 + ipv6_addr_copy(&map6->list.addr, addr6); 125 + map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0]; 126 + map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1]; 127 + map6->list.addr.s6_addr32[2] &= mask6->s6_addr32[2]; 128 + map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3]; 129 + ipv6_addr_copy(&map6->list.mask, mask6); 130 + map6->list.valid = 1; 131 + ret_val = netlbl_af4list_add(&map4->list, 132 + &addrmap->list4); 133 + if (ret_val != 0) 134 + goto cfg_unlbl_map_add_failure; 135 + break; 136 + default: 137 + goto cfg_unlbl_map_add_failure; 138 + break; 139 + } 140 + 141 + entry->type_def.addrsel = addrmap; 142 + entry->type = NETLBL_NLTYPE_ADDRSELECT; 143 + } else { 144 + ret_val = -EINVAL; 145 + goto cfg_unlbl_map_add_failure; 146 + } 125 147 126 148 ret_val = netlbl_domhsh_add(entry, audit_info); 127 149 if (ret_val != 0) 128 - goto cfg_unlbl_add_map_failure; 150 + goto cfg_unlbl_map_add_failure; 129 151 130 152 return 0; 131 153 132 - cfg_unlbl_add_map_failure: 154 + cfg_unlbl_map_add_failure: 133 155 if (entry != NULL) 134 156 kfree(entry->domain); 135 157 kfree(entry); 158 + kfree(addrmap); 159 + kfree(map4); 160 + kfree(map6); 136 161 return ret_val; 137 162 } 138 163 164 + 139 165 /** 140 - * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping 141 - * @doi_def: the DOI definition 142 - * @domain: the domain mapping to add 166 + * netlbl_cfg_unlbl_static_add - Adds a new static label 167 + * @net: network namespace 168 + * @dev_name: interface name 169 + * @addr: IP address in network byte order (struct in[6]_addr) 170 + * @mask: address mask in network byte order (struct in[6]_addr) 171 + * @family: address family 172 + * @secid: LSM secid value for the entry 143 173 * @audit_info: NetLabel audit information 144 174 * 145 175 * Description: 146 - * Add a new CIPSOv4 DOI definition and NetLabel/LSM domain mapping for this 147 - * new DOI definition to the NetLabel subsystem. A @domain value of NULL adds 148 - * a new default domain mapping. Returns zero on success, negative values on 149 - * failure. 176 + * Adds a new NetLabel static label to be used when protocol provided labels 177 + * are not present on incoming traffic. If @dev_name is NULL then the default 178 + * interface will be used. Returns zero on success, negative values on failure. 150 179 * 151 180 */ 152 - int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, 181 + int netlbl_cfg_unlbl_static_add(struct net *net, 182 + const char *dev_name, 183 + const void *addr, 184 + const void *mask, 185 + u16 family, 186 + u32 secid, 187 + struct netlbl_audit *audit_info) 188 + { 189 + u32 addr_len; 190 + 191 + switch (family) { 192 + case AF_INET: 193 + addr_len = sizeof(struct in_addr); 194 + break; 195 + case AF_INET6: 196 + addr_len = sizeof(struct in6_addr); 197 + break; 198 + default: 199 + return -EPFNOSUPPORT; 200 + } 201 + 202 + return netlbl_unlhsh_add(net, 203 + dev_name, addr, mask, addr_len, 204 + secid, audit_info); 205 + } 206 + 207 + /** 208 + * netlbl_cfg_unlbl_static_del - Removes an existing static label 209 + * @net: network namespace 210 + * @dev_name: interface name 211 + * @addr: IP address in network byte order (struct in[6]_addr) 212 + * @mask: address mask in network byte order (struct in[6]_addr) 213 + * @family: address family 214 + * @secid: LSM secid value for the entry 215 + * @audit_info: NetLabel audit information 216 + * 217 + * Description: 218 + * Removes an existing NetLabel static label used when protocol provided labels 219 + * are not present on incoming traffic. If @dev_name is NULL then the default 220 + * interface will be used. Returns zero on success, negative values on failure. 221 + * 222 + */ 223 + int netlbl_cfg_unlbl_static_del(struct net *net, 224 + const char *dev_name, 225 + const void *addr, 226 + const void *mask, 227 + u16 family, 228 + struct netlbl_audit *audit_info) 229 + { 230 + u32 addr_len; 231 + 232 + switch (family) { 233 + case AF_INET: 234 + addr_len = sizeof(struct in_addr); 235 + break; 236 + case AF_INET6: 237 + addr_len = sizeof(struct in6_addr); 238 + break; 239 + default: 240 + return -EPFNOSUPPORT; 241 + } 242 + 243 + return netlbl_unlhsh_remove(net, 244 + dev_name, addr, mask, addr_len, 245 + audit_info); 246 + } 247 + 248 + /** 249 + * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition 250 + * @doi_def: CIPSO DOI definition 251 + * @audit_info: NetLabel audit information 252 + * 253 + * Description: 254 + * Add a new CIPSO DOI definition as defined by @doi_def. Returns zero on 255 + * success and negative values on failure. 256 + * 257 + */ 258 + int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def, 259 + struct netlbl_audit *audit_info) 260 + { 261 + return cipso_v4_doi_add(doi_def, audit_info); 262 + } 263 + 264 + /** 265 + * netlbl_cfg_cipsov4_del - Remove an existing CIPSOv4 DOI definition 266 + * @doi: CIPSO DOI 267 + * @audit_info: NetLabel audit information 268 + * 269 + * Description: 270 + * Remove an existing CIPSO DOI definition matching @doi. Returns zero on 271 + * success and negative values on failure. 272 + * 273 + */ 274 + void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info) 275 + { 276 + cipso_v4_doi_remove(doi, audit_info); 277 + } 278 + 279 + /** 280 + * netlbl_cfg_cipsov4_map_add - Add a new CIPSOv4 DOI mapping 281 + * @doi: the CIPSO DOI 282 + * @domain: the domain mapping to add 283 + * @addr: IP address 284 + * @mask: IP address mask 285 + * @audit_info: NetLabel audit information 286 + * 287 + * Description: 288 + * Add a new NetLabel/LSM domain mapping for the given CIPSO DOI to the NetLabel 289 + * subsystem. A @domain value of NULL adds a new default domain mapping. 290 + * Returns zero on success, negative values on failure. 291 + * 292 + */ 293 + int netlbl_cfg_cipsov4_map_add(u32 doi, 153 294 const char *domain, 295 + const struct in_addr *addr, 296 + const struct in_addr *mask, 154 297 struct netlbl_audit *audit_info) 155 298 { 156 299 int ret_val = -ENOMEM; 157 - u32 doi; 158 - u32 doi_type; 300 + struct cipso_v4_doi *doi_def; 159 301 struct netlbl_dom_map *entry; 160 - const char *type_str; 161 - struct audit_buffer *audit_buf; 302 + struct netlbl_domaddr_map *addrmap = NULL; 303 + struct netlbl_domaddr4_map *addrinfo = NULL; 162 304 163 - doi = doi_def->doi; 164 - doi_type = doi_def->type; 305 + doi_def = cipso_v4_doi_getdef(doi); 306 + if (doi_def == NULL) 307 + return -ENOENT; 165 308 166 309 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 167 310 if (entry == NULL) ··· 345 136 if (domain != NULL) { 346 137 entry->domain = kstrdup(domain, GFP_ATOMIC); 347 138 if (entry->domain == NULL) 348 - goto cfg_cipsov4_add_map_failure; 139 + goto cfg_cipsov4_map_add_failure; 349 140 } 350 141 351 - ret_val = cipso_v4_doi_add(doi_def); 352 - if (ret_val != 0) 353 - goto cfg_cipsov4_add_map_failure_remove_doi; 354 - entry->type = NETLBL_NLTYPE_CIPSOV4; 355 - entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi); 356 - if (entry->type_def.cipsov4 == NULL) { 357 - ret_val = -ENOENT; 358 - goto cfg_cipsov4_add_map_failure_remove_doi; 142 + if (addr == NULL && mask == NULL) { 143 + entry->type_def.cipsov4 = doi_def; 144 + entry->type = NETLBL_NLTYPE_CIPSOV4; 145 + } else if (addr != NULL && mask != NULL) { 146 + addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); 147 + if (addrmap == NULL) 148 + goto cfg_cipsov4_map_add_failure; 149 + INIT_LIST_HEAD(&addrmap->list4); 150 + INIT_LIST_HEAD(&addrmap->list6); 151 + 152 + addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); 153 + if (addrinfo == NULL) 154 + goto cfg_cipsov4_map_add_failure; 155 + addrinfo->type_def.cipsov4 = doi_def; 156 + addrinfo->type = NETLBL_NLTYPE_CIPSOV4; 157 + addrinfo->list.addr = addr->s_addr & mask->s_addr; 158 + addrinfo->list.mask = mask->s_addr; 159 + addrinfo->list.valid = 1; 160 + ret_val = netlbl_af4list_add(&addrinfo->list, &addrmap->list4); 161 + if (ret_val != 0) 162 + goto cfg_cipsov4_map_add_failure; 163 + 164 + entry->type_def.addrsel = addrmap; 165 + entry->type = NETLBL_NLTYPE_ADDRSELECT; 166 + } else { 167 + ret_val = -EINVAL; 168 + goto cfg_cipsov4_map_add_failure; 359 169 } 170 + 360 171 ret_val = netlbl_domhsh_add(entry, audit_info); 361 172 if (ret_val != 0) 362 - goto cfg_cipsov4_add_map_failure_release_doi; 173 + goto cfg_cipsov4_map_add_failure; 363 174 364 - cfg_cipsov4_add_map_return: 365 - audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD, 366 - audit_info); 367 - if (audit_buf != NULL) { 368 - switch (doi_type) { 369 - case CIPSO_V4_MAP_TRANS: 370 - type_str = "trans"; 371 - break; 372 - case CIPSO_V4_MAP_PASS: 373 - type_str = "pass"; 374 - break; 375 - case CIPSO_V4_MAP_LOCAL: 376 - type_str = "local"; 377 - break; 378 - default: 379 - type_str = "(unknown)"; 380 - } 381 - audit_log_format(audit_buf, 382 - " cipso_doi=%u cipso_type=%s res=%u", 383 - doi, type_str, ret_val == 0 ? 1 : 0); 384 - audit_log_end(audit_buf); 385 - } 175 + return 0; 386 176 387 - return ret_val; 388 - 389 - cfg_cipsov4_add_map_failure_release_doi: 177 + cfg_cipsov4_map_add_failure: 390 178 cipso_v4_doi_putdef(doi_def); 391 - cfg_cipsov4_add_map_failure_remove_doi: 392 - cipso_v4_doi_remove(doi, audit_info); 393 - cfg_cipsov4_add_map_failure: 394 179 if (entry != NULL) 395 180 kfree(entry->domain); 396 181 kfree(entry); 397 - goto cfg_cipsov4_add_map_return; 182 + kfree(addrmap); 183 + kfree(addrinfo); 184 + return ret_val; 398 185 } 399 186 400 187 /* ··· 893 688 return cipso_v4_cache_add(skb, secattr); 894 689 895 690 return -ENOMSG; 691 + } 692 + 693 + /* 694 + * Protocol Engine Functions 695 + */ 696 + 697 + /** 698 + * netlbl_audit_start - Start an audit message 699 + * @type: audit message type 700 + * @audit_info: NetLabel audit information 701 + * 702 + * Description: 703 + * Start an audit message using the type specified in @type and fill the audit 704 + * message with some fields common to all NetLabel audit messages. This 705 + * function should only be used by protocol engines, not LSMs. Returns a 706 + * pointer to the audit buffer on success, NULL on failure. 707 + * 708 + */ 709 + struct audit_buffer *netlbl_audit_start(int type, 710 + struct netlbl_audit *audit_info) 711 + { 712 + return netlbl_audit_start_common(type, audit_info); 896 713 } 897 714 898 715 /*
+13 -13
net/netlabel/netlabel_unlabeled.c
··· 450 450 * success, negative values on failure. 451 451 * 452 452 */ 453 - static int netlbl_unlhsh_add(struct net *net, 454 - const char *dev_name, 455 - const void *addr, 456 - const void *mask, 457 - u32 addr_len, 458 - u32 secid, 459 - struct netlbl_audit *audit_info) 453 + int netlbl_unlhsh_add(struct net *net, 454 + const char *dev_name, 455 + const void *addr, 456 + const void *mask, 457 + u32 addr_len, 458 + u32 secid, 459 + struct netlbl_audit *audit_info) 460 460 { 461 461 int ret_val; 462 462 int ifindex; ··· 720 720 * Returns zero on success, negative values on failure. 721 721 * 722 722 */ 723 - static int netlbl_unlhsh_remove(struct net *net, 724 - const char *dev_name, 725 - const void *addr, 726 - const void *mask, 727 - u32 addr_len, 728 - struct netlbl_audit *audit_info) 723 + int netlbl_unlhsh_remove(struct net *net, 724 + const char *dev_name, 725 + const void *addr, 726 + const void *mask, 727 + u32 addr_len, 728 + struct netlbl_audit *audit_info) 729 729 { 730 730 int ret_val; 731 731 struct net_device *dev;
+15
net/netlabel/netlabel_unlabeled.h
··· 221 221 /* General Unlabeled init function */ 222 222 int netlbl_unlabel_init(u32 size); 223 223 224 + /* Static/Fallback label management functions */ 225 + int netlbl_unlhsh_add(struct net *net, 226 + const char *dev_name, 227 + const void *addr, 228 + const void *mask, 229 + u32 addr_len, 230 + u32 secid, 231 + struct netlbl_audit *audit_info); 232 + int netlbl_unlhsh_remove(struct net *net, 233 + const char *dev_name, 234 + const void *addr, 235 + const void *mask, 236 + u32 addr_len, 237 + struct netlbl_audit *audit_info); 238 + 224 239 /* Process Unlabeled incoming network packets */ 225 240 int netlbl_unlabel_getattr(const struct sk_buff *skb, 226 241 u16 family,
+14 -15
security/commoncap.c
··· 45 45 /** 46 46 * cap_capable - Determine whether a task has a particular effective capability 47 47 * @tsk: The task to query 48 + * @cred: The credentials to use 48 49 * @cap: The capability to check for 49 50 * @audit: Whether to write an audit message or not 50 51 * 51 52 * Determine whether the nominated task has the specified capability amongst 52 53 * its effective set, returning 0 if it does, -ve if it does not. 53 54 * 54 - * NOTE WELL: cap_capable() cannot be used like the kernel's capable() 55 - * function. That is, it has the reverse semantics: cap_capable() returns 0 56 - * when a task has a capability, but the kernel's capable() returns 1 for this 57 - * case. 55 + * NOTE WELL: cap_has_capability() cannot be used like the kernel's capable() 56 + * and has_capability() functions. That is, it has the reverse semantics: 57 + * cap_has_capability() returns 0 when a task has a capability, but the 58 + * kernel's capable() and has_capability() returns 1 for this case. 58 59 */ 59 - int cap_capable(struct task_struct *tsk, int cap, int audit) 60 + int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap, 61 + int audit) 60 62 { 61 - __u32 cap_raised; 62 - 63 - /* Derived from include/linux/sched.h:capable. */ 64 - rcu_read_lock(); 65 - cap_raised = cap_raised(__task_cred(tsk)->cap_effective, cap); 66 - rcu_read_unlock(); 67 - return cap_raised ? 0 : -EPERM; 63 + return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; 68 64 } 69 65 70 66 /** ··· 156 160 /* they are so limited unless the current task has the CAP_SETPCAP 157 161 * capability 158 162 */ 159 - if (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0) 163 + if (cap_capable(current, current_cred(), CAP_SETPCAP, 164 + SECURITY_CAP_AUDIT) == 0) 160 165 return 0; 161 166 #endif 162 167 return 1; ··· 866 869 & (new->securebits ^ arg2)) /*[1]*/ 867 870 || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ 868 871 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ 869 - || (cap_capable(current, CAP_SETPCAP, SECURITY_CAP_AUDIT) != 0) /*[4]*/ 872 + || (cap_capable(current, current_cred(), CAP_SETPCAP, 873 + SECURITY_CAP_AUDIT) != 0) /*[4]*/ 870 874 /* 871 875 * [1] no changing of bits that are locked 872 876 * [2] no unlocking of locks ··· 948 950 { 949 951 int cap_sys_admin = 0; 950 952 951 - if (cap_capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT) == 0) 953 + if (cap_capable(current, current_cred(), CAP_SYS_ADMIN, 954 + SECURITY_CAP_NOAUDIT) == 0) 952 955 cap_sys_admin = 1; 953 956 return __vm_enough_memory(mm, pages, cap_sys_admin); 954 957 }
+1 -1
security/keys/keyctl.c
··· 1294 1294 1295 1295 case KEYCTL_GET_SECURITY: 1296 1296 return keyctl_get_security((key_serial_t) arg2, 1297 - (char *) arg3, 1297 + (char __user *) arg3, 1298 1298 (size_t) arg4); 1299 1299 1300 1300 default:
+22 -4
security/security.c
··· 154 154 effective, inheritable, permitted); 155 155 } 156 156 157 - int security_capable(struct task_struct *tsk, int cap) 157 + int security_capable(int cap) 158 158 { 159 - return security_ops->capable(tsk, cap, SECURITY_CAP_AUDIT); 159 + return security_ops->capable(current, current_cred(), cap, 160 + SECURITY_CAP_AUDIT); 160 161 } 161 162 162 - int security_capable_noaudit(struct task_struct *tsk, int cap) 163 + int security_real_capable(struct task_struct *tsk, int cap) 163 164 { 164 - return security_ops->capable(tsk, cap, SECURITY_CAP_NOAUDIT); 165 + const struct cred *cred; 166 + int ret; 167 + 168 + cred = get_task_cred(tsk); 169 + ret = security_ops->capable(tsk, cred, cap, SECURITY_CAP_AUDIT); 170 + put_cred(cred); 171 + return ret; 172 + } 173 + 174 + int security_real_capable_noaudit(struct task_struct *tsk, int cap) 175 + { 176 + const struct cred *cred; 177 + int ret; 178 + 179 + cred = get_task_cred(tsk); 180 + ret = security_ops->capable(tsk, cred, cap, SECURITY_CAP_NOAUDIT); 181 + put_cred(cred); 182 + return ret; 165 183 } 166 184 167 185 int security_acct(struct file *file)
-27
security/selinux/Kconfig
··· 94 94 95 95 If you are unsure how to answer this question, answer 1. 96 96 97 - config SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT 98 - bool "NSA SELinux enable new secmark network controls by default" 99 - depends on SECURITY_SELINUX 100 - default n 101 - help 102 - This option determines whether the new secmark-based network 103 - controls will be enabled by default. If not, the old internal 104 - per-packet controls will be enabled by default, preserving 105 - old behavior. 106 - 107 - If you enable the new controls, you will need updated 108 - SELinux userspace libraries, tools and policy. Typically, 109 - your distribution will provide these and enable the new controls 110 - in the kernel they also distribute. 111 - 112 - Note that this option can be overridden at boot with the 113 - selinux_compat_net parameter, and after boot via 114 - /selinux/compat_net. See Documentation/kernel-parameters.txt 115 - for details on this parameter. 116 - 117 - If you enable the new network controls, you will likely 118 - also require the SECMARK and CONNSECMARK targets, as 119 - well as any conntrack helpers for protocols which you 120 - wish to control. 121 - 122 - If you are unsure what to do here, select N. 123 - 124 97 config SECURITY_SELINUX_POLICYDB_VERSION_MAX 125 98 bool "NSA SELinux maximum supported policy format version" 126 99 depends on SECURITY_SELINUX
+9 -7
security/selinux/avc.c
··· 53 53 #undef S_ 54 54 55 55 static const struct av_inherit av_inherit[] = { 56 - #define S_(c, i, b) { c, common_##i##_perm_to_string, b }, 56 + #define S_(c, i, b) { .tclass = c,\ 57 + .common_pts = common_##i##_perm_to_string,\ 58 + .common_base = b }, 57 59 #include "av_inherit.h" 58 60 #undef S_ 59 61 }; 60 62 61 63 const struct selinux_class_perm selinux_class_perm = { 62 - av_perm_to_string, 63 - ARRAY_SIZE(av_perm_to_string), 64 - class_to_string, 65 - ARRAY_SIZE(class_to_string), 66 - av_inherit, 67 - ARRAY_SIZE(av_inherit) 64 + .av_perm_to_string = av_perm_to_string, 65 + .av_pts_len = ARRAY_SIZE(av_perm_to_string), 66 + .class_to_string = class_to_string, 67 + .cts_len = ARRAY_SIZE(class_to_string), 68 + .av_inherit = av_inherit, 69 + .av_inherit_len = ARRAY_SIZE(av_inherit) 68 70 }; 69 71 70 72 #define AVC_CACHE_SLOTS 512
+13 -9
security/selinux/hooks.c
··· 1433 1433 1434 1434 /* Check whether a task is allowed to use a capability. */ 1435 1435 static int task_has_capability(struct task_struct *tsk, 1436 + const struct cred *cred, 1436 1437 int cap, int audit) 1437 1438 { 1438 1439 struct avc_audit_data ad; 1439 1440 struct av_decision avd; 1440 1441 u16 sclass; 1441 - u32 sid = task_sid(tsk); 1442 + u32 sid = cred_sid(cred); 1442 1443 u32 av = CAP_TO_MASK(cap); 1443 1444 int rc; 1444 1445 ··· 1866 1865 return cred_has_perm(old, new, PROCESS__SETCAP); 1867 1866 } 1868 1867 1869 - static int selinux_capable(struct task_struct *tsk, int cap, int audit) 1868 + static int selinux_capable(struct task_struct *tsk, const struct cred *cred, 1869 + int cap, int audit) 1870 1870 { 1871 1871 int rc; 1872 1872 1873 - rc = secondary_ops->capable(tsk, cap, audit); 1873 + rc = secondary_ops->capable(tsk, cred, cap, audit); 1874 1874 if (rc) 1875 1875 return rc; 1876 1876 1877 - return task_has_capability(tsk, cap, audit); 1877 + return task_has_capability(tsk, cred, cap, audit); 1878 1878 } 1879 1879 1880 1880 static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) ··· 2039 2037 { 2040 2038 int rc, cap_sys_admin = 0; 2041 2039 2042 - rc = selinux_capable(current, CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT); 2040 + rc = selinux_capable(current, current_cred(), CAP_SYS_ADMIN, 2041 + SECURITY_CAP_NOAUDIT); 2043 2042 if (rc == 0) 2044 2043 cap_sys_admin = 1; 2045 2044 ··· 2883 2880 * and lack of permission just means that we fall back to the 2884 2881 * in-core context value, not a denial. 2885 2882 */ 2886 - error = selinux_capable(current, CAP_MAC_ADMIN, SECURITY_CAP_NOAUDIT); 2883 + error = selinux_capable(current, current_cred(), CAP_MAC_ADMIN, 2884 + SECURITY_CAP_NOAUDIT); 2887 2885 if (!error) 2888 2886 error = security_sid_to_context_force(isec->sid, &context, 2889 2887 &size); ··· 4189 4185 static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, 4190 4186 u16 family) 4191 4187 { 4192 - int err; 4188 + int err = 0; 4193 4189 struct sk_security_struct *sksec = sk->sk_security; 4194 4190 u32 peer_sid; 4195 4191 u32 sk_sid = sksec->sid; ··· 4206 4202 if (selinux_compat_net) 4207 4203 err = selinux_sock_rcv_skb_iptables_compat(sk, skb, &ad, 4208 4204 family, addrp); 4209 - else 4205 + else if (selinux_secmark_enabled()) 4210 4206 err = avc_has_perm(sk_sid, skb->secmark, SECCLASS_PACKET, 4211 4207 PACKET__RECV, &ad); 4212 4208 if (err) ··· 4709 4705 if (selinux_ip_postroute_iptables_compat(skb->sk, ifindex, 4710 4706 &ad, family, addrp)) 4711 4707 return NF_DROP; 4712 - } else { 4708 + } else if (selinux_secmark_enabled()) { 4713 4709 if (avc_has_perm(sksec->sid, skb->secmark, 4714 4710 SECCLASS_PACKET, PACKET__SEND, &ad)) 4715 4711 return NF_DROP;
+2 -2
security/selinux/include/avc_ss.h
··· 17 17 }; 18 18 19 19 struct av_inherit { 20 - u16 tclass; 21 20 const char **common_pts; 22 21 u32 common_base; 22 + u16 tclass; 23 23 }; 24 24 25 25 struct selinux_class_perm { 26 26 const struct av_perm_to_string *av_perm_to_string; 27 27 u32 av_pts_len; 28 - const char **class_to_string; 29 28 u32 cts_len; 29 + const char **class_to_string; 30 30 const struct av_inherit *av_inherit; 31 31 u32 av_inherit_len; 32 32 };
+8 -8
security/selinux/selinuxfs.c
··· 47 47 48 48 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 49 49 50 - #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT 51 - #define SELINUX_COMPAT_NET_VALUE 0 52 - #else 53 - #define SELINUX_COMPAT_NET_VALUE 1 54 - #endif 55 - 56 - int selinux_compat_net = SELINUX_COMPAT_NET_VALUE; 50 + int selinux_compat_net = 0; 57 51 58 52 static int __init checkreqprot_setup(char *str) 59 53 { ··· 488 494 if (sscanf(page, "%d", &new_value) != 1) 489 495 goto out; 490 496 491 - selinux_compat_net = new_value ? 1 : 0; 497 + if (new_value) { 498 + printk(KERN_NOTICE 499 + "SELinux: compat_net is deprecated, please use secmark" 500 + " instead\n"); 501 + selinux_compat_net = 1; 502 + } else 503 + selinux_compat_net = 0; 492 504 length = count; 493 505 out: 494 506 free_page((unsigned long) page);
+1 -1
security/selinux/ss/context.h
··· 27 27 u32 user; 28 28 u32 role; 29 29 u32 type; 30 + u32 len; /* length of string in bytes */ 30 31 struct mls_range range; 31 32 char *str; /* string representation if context cannot be mapped. */ 32 - u32 len; /* length of string in bytes */ 33 33 }; 34 34 35 35 static inline void mls_context_init(struct context *c)
+29 -2
security/smack/smack.h
··· 16 16 #include <linux/capability.h> 17 17 #include <linux/spinlock.h> 18 18 #include <linux/security.h> 19 + #include <linux/in.h> 19 20 #include <net/netlabel.h> 20 21 21 22 /* ··· 40 39 struct socket_smack { 41 40 char *smk_out; /* outbound label */ 42 41 char *smk_in; /* inbound label */ 42 + int smk_labeled; /* label scheme */ 43 43 char smk_packet[SMK_LABELLEN]; /* TCP peer label */ 44 44 }; 45 45 ··· 79 77 struct smack_cipso { 80 78 int smk_level; 81 79 char smk_catset[SMK_LABELLEN]; 80 + }; 81 + 82 + /* 83 + * An entry in the table identifying hosts. 84 + */ 85 + struct smk_netlbladdr { 86 + struct smk_netlbladdr *smk_next; 87 + struct sockaddr_in smk_host; /* network address */ 88 + struct in_addr smk_mask; /* network mask */ 89 + char *smk_label; /* label */ 82 90 }; 83 91 84 92 /* ··· 139 127 #define XATTR_NAME_SMACKIPOUT XATTR_SECURITY_PREFIX XATTR_SMACK_IPOUT 140 128 141 129 /* 130 + * How communications on this socket are treated. 131 + * Usually it's determined by the underlying netlabel code 132 + * but there are certain cases, including single label hosts 133 + * and potentially single label interfaces for which the 134 + * treatment can not be known in advance. 135 + * 136 + * The possibility of additional labeling schemes being 137 + * introduced in the future exists as well. 138 + */ 139 + #define SMACK_UNLABELED_SOCKET 0 140 + #define SMACK_CIPSO_SOCKET 1 141 + 142 + /* 143 + * smackfs magic number 142 144 * smackfs macic number 143 145 */ 144 146 #define SMACK_MAGIC 0x43415d53 /* "SMAC" */ ··· 167 141 * CIPSO defaults. 168 142 */ 169 143 #define SMACK_CIPSO_DOI_DEFAULT 3 /* Historical */ 144 + #define SMACK_CIPSO_DOI_INVALID -1 /* Not a DOI */ 170 145 #define SMACK_CIPSO_DIRECT_DEFAULT 250 /* Arbitrary */ 171 146 #define SMACK_CIPSO_MAXCATVAL 63 /* Bigger gets harder */ 172 147 #define SMACK_CIPSO_MAXLEVEL 255 /* CIPSO 2.2 standard */ ··· 203 176 * Shared data. 204 177 */ 205 178 extern int smack_cipso_direct; 206 - extern int smack_net_nltype; 207 179 extern char *smack_net_ambient; 208 180 extern char *smack_onlycap; 209 181 ··· 212 186 extern struct smack_known smack_known_huh; 213 187 extern struct smack_known smack_known_invalid; 214 188 extern struct smack_known smack_known_star; 215 - extern struct smack_known smack_known_unset; 189 + extern struct smack_known smack_known_web; 216 190 217 191 extern struct smk_list_entry *smack_list; 192 + extern struct smk_netlbladdr *smack_netlbladdrs; 218 193 extern struct security_operations smack_ops; 219 194 220 195 /*
+19 -9
security/smack/smack_access.c
··· 15 15 #include <linux/sched.h> 16 16 #include "smack.h" 17 17 18 - struct smack_known smack_known_unset = { 19 - .smk_next = NULL, 20 - .smk_known = "UNSET", 21 - .smk_secid = 1, 22 - .smk_cipso = NULL, 23 - }; 24 - 25 18 struct smack_known smack_known_huh = { 26 - .smk_next = &smack_known_unset, 19 + .smk_next = NULL, 27 20 .smk_known = "?", 28 21 .smk_secid = 2, 29 22 .smk_cipso = NULL, ··· 50 57 .smk_cipso = NULL, 51 58 }; 52 59 53 - struct smack_known *smack_known = &smack_known_invalid; 60 + struct smack_known smack_known_web = { 61 + .smk_next = &smack_known_invalid, 62 + .smk_known = "@", 63 + .smk_secid = 7, 64 + .smk_cipso = NULL, 65 + }; 66 + 67 + struct smack_known *smack_known = &smack_known_web; 54 68 55 69 /* 56 70 * The initial value needs to be bigger than any of the ··· 98 98 if (subject_label == smack_known_star.smk_known || 99 99 strcmp(subject_label, smack_known_star.smk_known) == 0) 100 100 return -EACCES; 101 + /* 102 + * An internet object can be accessed by any subject. 103 + * Tasks cannot be assigned the internet label. 104 + * An internet subject can access any object. 105 + */ 106 + if (object_label == smack_known_web.smk_known || 107 + subject_label == smack_known_web.smk_known || 108 + strcmp(object_label, smack_known_web.smk_known) == 0 || 109 + strcmp(subject_label, smack_known_web.smk_known) == 0) 110 + return 0; 101 111 /* 102 112 * A star object can be accessed by any subject. 103 113 */
+256 -56
security/smack/smack_lsm.c
··· 1277 1277 1278 1278 ssp->smk_in = csp; 1279 1279 ssp->smk_out = csp; 1280 + ssp->smk_labeled = SMACK_CIPSO_SOCKET; 1280 1281 ssp->smk_packet[0] = '\0'; 1281 1282 1282 1283 sk->sk_security = ssp; ··· 1342 1341 struct smack_cipso cipso; 1343 1342 int rc; 1344 1343 1345 - switch (smack_net_nltype) { 1346 - case NETLBL_NLTYPE_CIPSOV4: 1347 - nlsp->domain = smack; 1348 - nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; 1344 + nlsp->domain = smack; 1345 + nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; 1349 1346 1350 - rc = smack_to_cipso(smack, &cipso); 1351 - if (rc == 0) { 1352 - nlsp->attr.mls.lvl = cipso.smk_level; 1353 - smack_set_catset(cipso.smk_catset, nlsp); 1354 - } else { 1355 - nlsp->attr.mls.lvl = smack_cipso_direct; 1356 - smack_set_catset(smack, nlsp); 1357 - } 1358 - break; 1359 - default: 1360 - break; 1347 + rc = smack_to_cipso(smack, &cipso); 1348 + if (rc == 0) { 1349 + nlsp->attr.mls.lvl = cipso.smk_level; 1350 + smack_set_catset(cipso.smk_catset, nlsp); 1351 + } else { 1352 + nlsp->attr.mls.lvl = smack_cipso_direct; 1353 + smack_set_catset(smack, nlsp); 1361 1354 } 1362 1355 } 1363 1356 1364 1357 /** 1365 1358 * smack_netlabel - Set the secattr on a socket 1366 1359 * @sk: the socket 1360 + * @labeled: socket label scheme 1367 1361 * 1368 1362 * Convert the outbound smack value (smk_out) to a 1369 1363 * secattr and attach it to the socket. 1370 1364 * 1371 1365 * Returns 0 on success or an error code 1372 1366 */ 1373 - static int smack_netlabel(struct sock *sk) 1367 + static int smack_netlabel(struct sock *sk, int labeled) 1374 1368 { 1375 1369 struct socket_smack *ssp; 1376 1370 struct netlbl_lsm_secattr secattr; 1377 - int rc; 1371 + int rc = 0; 1378 1372 1379 1373 ssp = sk->sk_security; 1380 - netlbl_secattr_init(&secattr); 1381 - smack_to_secattr(ssp->smk_out, &secattr); 1382 - rc = netlbl_sock_setattr(sk, &secattr); 1383 - netlbl_secattr_destroy(&secattr); 1374 + /* 1375 + * Usually the netlabel code will handle changing the 1376 + * packet labeling based on the label. 1377 + * The case of a single label host is different, because 1378 + * a single label host should never get a labeled packet 1379 + * even though the label is usually associated with a packet 1380 + * label. 1381 + */ 1382 + local_bh_disable(); 1383 + bh_lock_sock_nested(sk); 1384 + 1385 + if (ssp->smk_out == smack_net_ambient || 1386 + labeled == SMACK_UNLABELED_SOCKET) 1387 + netlbl_sock_delattr(sk); 1388 + else { 1389 + netlbl_secattr_init(&secattr); 1390 + smack_to_secattr(ssp->smk_out, &secattr); 1391 + rc = netlbl_sock_setattr(sk, &secattr); 1392 + netlbl_secattr_destroy(&secattr); 1393 + } 1394 + 1395 + bh_unlock_sock(sk); 1396 + local_bh_enable(); 1397 + /* 1398 + * Remember the label scheme used so that it is not 1399 + * necessary to do the netlabel setting if it has not 1400 + * changed the next time through. 1401 + * 1402 + * The -EDESTADDRREQ case is an indication that there's 1403 + * a single level host involved. 1404 + */ 1405 + if (rc == 0) 1406 + ssp->smk_labeled = labeled; 1384 1407 1385 1408 return rc; 1386 1409 } ··· 1457 1432 ssp->smk_in = sp; 1458 1433 else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { 1459 1434 ssp->smk_out = sp; 1460 - rc = smack_netlabel(sock->sk); 1435 + rc = smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 1461 1436 if (rc != 0) 1462 1437 printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", 1463 1438 __func__, -rc); ··· 1487 1462 /* 1488 1463 * Set the outbound netlbl. 1489 1464 */ 1490 - return smack_netlabel(sock->sk); 1465 + return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 1466 + } 1467 + 1468 + 1469 + /** 1470 + * smack_host_label - check host based restrictions 1471 + * @sip: the object end 1472 + * 1473 + * looks for host based access restrictions 1474 + * 1475 + * This version will only be appropriate for really small 1476 + * sets of single label hosts. Because of the masking 1477 + * it cannot shortcut out on the first match. There are 1478 + * numerious ways to address the problem, but none of them 1479 + * have been applied here. 1480 + * 1481 + * Returns the label of the far end or NULL if it's not special. 1482 + */ 1483 + static char *smack_host_label(struct sockaddr_in *sip) 1484 + { 1485 + struct smk_netlbladdr *snp; 1486 + char *bestlabel = NULL; 1487 + struct in_addr *siap = &sip->sin_addr; 1488 + struct in_addr *liap; 1489 + struct in_addr *miap; 1490 + struct in_addr bestmask; 1491 + 1492 + if (siap->s_addr == 0) 1493 + return NULL; 1494 + 1495 + bestmask.s_addr = 0; 1496 + 1497 + for (snp = smack_netlbladdrs; snp != NULL; snp = snp->smk_next) { 1498 + liap = &snp->smk_host.sin_addr; 1499 + miap = &snp->smk_mask; 1500 + /* 1501 + * If the addresses match after applying the list entry mask 1502 + * the entry matches the address. If it doesn't move along to 1503 + * the next entry. 1504 + */ 1505 + if ((liap->s_addr & miap->s_addr) != 1506 + (siap->s_addr & miap->s_addr)) 1507 + continue; 1508 + /* 1509 + * If the list entry mask identifies a single address 1510 + * it can't get any more specific. 1511 + */ 1512 + if (miap->s_addr == 0xffffffff) 1513 + return snp->smk_label; 1514 + /* 1515 + * If the list entry mask is less specific than the best 1516 + * already found this entry is uninteresting. 1517 + */ 1518 + if ((miap->s_addr | bestmask.s_addr) == bestmask.s_addr) 1519 + continue; 1520 + /* 1521 + * This is better than any entry found so far. 1522 + */ 1523 + bestmask.s_addr = miap->s_addr; 1524 + bestlabel = snp->smk_label; 1525 + } 1526 + 1527 + return bestlabel; 1528 + } 1529 + 1530 + /** 1531 + * smack_socket_connect - connect access check 1532 + * @sock: the socket 1533 + * @sap: the other end 1534 + * @addrlen: size of sap 1535 + * 1536 + * Verifies that a connection may be possible 1537 + * 1538 + * Returns 0 on success, and error code otherwise 1539 + */ 1540 + static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, 1541 + int addrlen) 1542 + { 1543 + struct socket_smack *ssp = sock->sk->sk_security; 1544 + char *hostsp; 1545 + int rc; 1546 + 1547 + if (sock->sk == NULL || sock->sk->sk_family != PF_INET) 1548 + return 0; 1549 + 1550 + if (addrlen < sizeof(struct sockaddr_in)) 1551 + return -EINVAL; 1552 + 1553 + hostsp = smack_host_label((struct sockaddr_in *)sap); 1554 + if (hostsp == NULL) { 1555 + if (ssp->smk_labeled != SMACK_CIPSO_SOCKET) 1556 + return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 1557 + return 0; 1558 + } 1559 + 1560 + rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE); 1561 + if (rc != 0) 1562 + return rc; 1563 + 1564 + if (ssp->smk_labeled != SMACK_UNLABELED_SOCKET) 1565 + return smack_netlabel(sock->sk, SMACK_UNLABELED_SOCKET); 1566 + return 0; 1491 1567 } 1492 1568 1493 1569 /** ··· 2227 2101 if (newsmack == NULL) 2228 2102 return -EINVAL; 2229 2103 2104 + /* 2105 + * No process is ever allowed the web ("@") label. 2106 + */ 2107 + if (newsmack == smack_known_web.smk_known) 2108 + return -EPERM; 2109 + 2230 2110 new = prepare_creds(); 2231 - if (!new) 2111 + if (new == NULL) 2232 2112 return -ENOMEM; 2233 2113 new->security = newsmack; 2234 2114 commit_creds(new); ··· 2276 2144 } 2277 2145 2278 2146 /** 2147 + * smack_socket_sendmsg - Smack check based on destination host 2148 + * @sock: the socket 2149 + * @msghdr: the message 2150 + * @size: the size of the message 2151 + * 2152 + * Return 0 if the current subject can write to the destination 2153 + * host. This is only a question if the destination is a single 2154 + * label host. 2155 + */ 2156 + static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, 2157 + int size) 2158 + { 2159 + struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; 2160 + struct socket_smack *ssp = sock->sk->sk_security; 2161 + char *hostsp; 2162 + int rc; 2163 + 2164 + /* 2165 + * Perfectly reasonable for this to be NULL 2166 + */ 2167 + if (sip == NULL || sip->sin_family != PF_INET) 2168 + return 0; 2169 + 2170 + hostsp = smack_host_label(sip); 2171 + if (hostsp == NULL) { 2172 + if (ssp->smk_labeled != SMACK_CIPSO_SOCKET) 2173 + return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); 2174 + return 0; 2175 + } 2176 + 2177 + rc = smk_access(ssp->smk_out, hostsp, MAY_WRITE); 2178 + if (rc != 0) 2179 + return rc; 2180 + 2181 + if (ssp->smk_labeled != SMACK_UNLABELED_SOCKET) 2182 + return smack_netlabel(sock->sk, SMACK_UNLABELED_SOCKET); 2183 + 2184 + return 0; 2185 + 2186 + } 2187 + 2188 + 2189 + /** 2279 2190 * smack_from_secattr - Convert a netlabel attr.mls.lvl/attr.mls.cat 2280 2191 * pair to smack 2281 2192 * @sap: netlabel secattr ··· 2329 2154 static void smack_from_secattr(struct netlbl_lsm_secattr *sap, char *sip) 2330 2155 { 2331 2156 char smack[SMK_LABELLEN]; 2157 + char *sp; 2332 2158 int pcat; 2333 2159 2334 - if ((sap->flags & NETLBL_SECATTR_MLS_LVL) == 0) { 2160 + if ((sap->flags & NETLBL_SECATTR_MLS_LVL) != 0) { 2335 2161 /* 2162 + * Looks like a CIPSO packet. 2336 2163 * If there are flags but no level netlabel isn't 2337 2164 * behaving the way we expect it to. 2338 2165 * 2166 + * Get the categories, if any 2339 2167 * Without guidance regarding the smack value 2340 2168 * for the packet fall back on the network 2341 2169 * ambient value. 2342 2170 */ 2343 - strncpy(sip, smack_net_ambient, SMK_MAXLEN); 2344 - return; 2345 - } 2346 - /* 2347 - * Get the categories, if any 2348 - */ 2349 - memset(smack, '\0', SMK_LABELLEN); 2350 - if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0) 2351 - for (pcat = -1;;) { 2352 - pcat = netlbl_secattr_catmap_walk(sap->attr.mls.cat, 2353 - pcat + 1); 2354 - if (pcat < 0) 2355 - break; 2356 - smack_catset_bit(pcat, smack); 2171 + memset(smack, '\0', SMK_LABELLEN); 2172 + if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0) 2173 + for (pcat = -1;;) { 2174 + pcat = netlbl_secattr_catmap_walk( 2175 + sap->attr.mls.cat, pcat + 1); 2176 + if (pcat < 0) 2177 + break; 2178 + smack_catset_bit(pcat, smack); 2179 + } 2180 + /* 2181 + * If it is CIPSO using smack direct mapping 2182 + * we are already done. WeeHee. 2183 + */ 2184 + if (sap->attr.mls.lvl == smack_cipso_direct) { 2185 + memcpy(sip, smack, SMK_MAXLEN); 2186 + return; 2357 2187 } 2358 - /* 2359 - * If it is CIPSO using smack direct mapping 2360 - * we are already done. WeeHee. 2361 - */ 2362 - if (sap->attr.mls.lvl == smack_cipso_direct) { 2363 - memcpy(sip, smack, SMK_MAXLEN); 2188 + /* 2189 + * Look it up in the supplied table if it is not 2190 + * a direct mapping. 2191 + */ 2192 + smack_from_cipso(sap->attr.mls.lvl, smack, sip); 2193 + return; 2194 + } 2195 + if ((sap->flags & NETLBL_SECATTR_SECID) != 0) { 2196 + /* 2197 + * Looks like a fallback, which gives us a secid. 2198 + */ 2199 + sp = smack_from_secid(sap->attr.secid); 2200 + /* 2201 + * This has got to be a bug because it is 2202 + * impossible to specify a fallback without 2203 + * specifying the label, which will ensure 2204 + * it has a secid, and the only way to get a 2205 + * secid is from a fallback. 2206 + */ 2207 + BUG_ON(sp == NULL); 2208 + strncpy(sip, sp, SMK_MAXLEN); 2364 2209 return; 2365 2210 } 2366 2211 /* 2367 - * Look it up in the supplied table if it is not a direct mapping. 2212 + * Without guidance regarding the smack value 2213 + * for the packet fall back on the network 2214 + * ambient value. 2368 2215 */ 2369 - smack_from_cipso(sap->attr.mls.lvl, smack, sip); 2216 + strncpy(sip, smack_net_ambient, SMK_MAXLEN); 2370 2217 return; 2371 2218 } 2372 2219 ··· 2404 2207 struct netlbl_lsm_secattr secattr; 2405 2208 struct socket_smack *ssp = sk->sk_security; 2406 2209 char smack[SMK_LABELLEN]; 2210 + char *csp; 2407 2211 int rc; 2408 2212 2409 2213 if (sk->sk_family != PF_INET && sk->sk_family != PF_INET6) ··· 2413 2215 /* 2414 2216 * Translate what netlabel gave us. 2415 2217 */ 2416 - memset(smack, '\0', SMK_LABELLEN); 2417 2218 netlbl_secattr_init(&secattr); 2219 + 2418 2220 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &secattr); 2419 - if (rc == 0) 2221 + if (rc == 0) { 2420 2222 smack_from_secattr(&secattr, smack); 2421 - else 2422 - strncpy(smack, smack_net_ambient, SMK_MAXLEN); 2223 + csp = smack; 2224 + } else 2225 + csp = smack_net_ambient; 2226 + 2423 2227 netlbl_secattr_destroy(&secattr); 2228 + 2424 2229 /* 2425 2230 * Receiving a packet requires that the other end 2426 2231 * be able to write here. Read access is not required. 2427 2232 * This is the simplist possible security model 2428 2233 * for networking. 2429 2234 */ 2430 - rc = smk_access(smack, ssp->smk_in, MAY_WRITE); 2235 + rc = smk_access(csp, ssp->smk_in, MAY_WRITE); 2431 2236 if (rc != 0) 2432 2237 netlbl_skbuff_err(skb, rc, 0); 2433 2238 return rc; ··· 2499 2298 /* 2500 2299 * Translate what netlabel gave us. 2501 2300 */ 2502 - memset(smack, '\0', SMK_LABELLEN); 2503 2301 netlbl_secattr_init(&secattr); 2504 2302 rc = netlbl_skbuff_getattr(skb, family, &secattr); 2505 2303 if (rc == 0) ··· 2541 2341 ssp->smk_in = ssp->smk_out = current_security(); 2542 2342 ssp->smk_packet[0] = '\0'; 2543 2343 2544 - rc = smack_netlabel(sk); 2344 + rc = smack_netlabel(sk, SMACK_CIPSO_SOCKET); 2545 2345 if (rc != 0) 2546 2346 printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", 2547 2347 __func__, -rc); ··· 2567 2367 if (skb == NULL) 2568 2368 return -EACCES; 2569 2369 2570 - memset(smack, '\0', SMK_LABELLEN); 2571 2370 netlbl_secattr_init(&skb_secattr); 2572 2371 rc = netlbl_skbuff_getattr(skb, sk->sk_family, &skb_secattr); 2573 2372 if (rc == 0) ··· 2931 2732 .unix_may_send = smack_unix_may_send, 2932 2733 2933 2734 .socket_post_create = smack_socket_post_create, 2735 + .socket_connect = smack_socket_connect, 2736 + .socket_sendmsg = smack_socket_sendmsg, 2934 2737 .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, 2935 2738 .socket_getpeersec_stream = smack_socket_getpeersec_stream, 2936 2739 .socket_getpeersec_dgram = smack_socket_getpeersec_dgram, ··· 2984 2783 /* 2985 2784 * Initialize locks 2986 2785 */ 2987 - spin_lock_init(&smack_known_unset.smk_cipsolock); 2988 2786 spin_lock_init(&smack_known_huh.smk_cipsolock); 2989 2787 spin_lock_init(&smack_known_hat.smk_cipsolock); 2990 2788 spin_lock_init(&smack_known_star.smk_cipsolock);
+243 -126
security/smack/smackfs.c
··· 20 20 #include <linux/vmalloc.h> 21 21 #include <linux/security.h> 22 22 #include <linux/mutex.h> 23 + #include <net/net_namespace.h> 23 24 #include <net/netlabel.h> 24 25 #include <net/cipso_ipv4.h> 25 26 #include <linux/seq_file.h> ··· 39 38 SMK_DOI = 5, /* CIPSO DOI */ 40 39 SMK_DIRECT = 6, /* CIPSO level indicating direct label */ 41 40 SMK_AMBIENT = 7, /* internet ambient label */ 42 - SMK_NLTYPE = 8, /* label scheme to use by default */ 41 + SMK_NETLBLADDR = 8, /* single label hosts */ 43 42 SMK_ONLYCAP = 9, /* the only "capable" label */ 44 43 }; 45 44 ··· 49 48 static DEFINE_MUTEX(smack_list_lock); 50 49 static DEFINE_MUTEX(smack_cipso_lock); 51 50 static DEFINE_MUTEX(smack_ambient_lock); 51 + static DEFINE_MUTEX(smk_netlbladdr_lock); 52 52 53 53 /* 54 54 * This is the "ambient" label for network traffic. ··· 57 55 * It can be reset via smackfs/ambient 58 56 */ 59 57 char *smack_net_ambient = smack_known_floor.smk_known; 60 - 61 - /* 62 - * This is the default packet marking scheme for network traffic. 63 - * It can be reset via smackfs/nltype 64 - */ 65 - int smack_net_nltype = NETLBL_NLTYPE_CIPSOV4; 66 58 67 59 /* 68 60 * This is the level in a CIPSO header that indicates a ··· 74 78 * will be used if any label is used. 75 79 */ 76 80 char *smack_onlycap; 81 + 82 + /* 83 + * Certain IP addresses may be designated as single label hosts. 84 + * Packets are sent there unlabeled, but only from tasks that 85 + * can write to the specified label. 86 + */ 87 + struct smk_netlbladdr *smack_netlbladdrs; 77 88 78 89 static int smk_cipso_doi_value = SMACK_CIPSO_DOI_DEFAULT; 79 90 struct smk_list_entry *smack_list; ··· 107 104 #define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1) 108 105 #define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN) 109 106 107 + /** 108 + * smk_netlabel_audit_set - fill a netlbl_audit struct 109 + * @nap: structure to fill 110 + */ 111 + static void smk_netlabel_audit_set(struct netlbl_audit *nap) 112 + { 113 + nap->loginuid = audit_get_loginuid(current); 114 + nap->sessionid = audit_get_sessionid(current); 115 + nap->secid = smack_to_secid(current_security()); 116 + } 117 + 118 + /* 119 + * Values for parsing single label host rules 120 + * "1.2.3.4 X" 121 + * "192.168.138.129/32 abcdefghijklmnopqrstuvw" 122 + */ 123 + #define SMK_NETLBLADDRMIN 9 124 + #define SMK_NETLBLADDRMAX 42 110 125 111 126 /* 112 127 * Seq_file read operations for /smack/load ··· 365 344 { 366 345 int rc; 367 346 struct cipso_v4_doi *doip; 368 - struct netlbl_audit audit_info; 347 + struct netlbl_audit nai; 369 348 370 - audit_info.loginuid = audit_get_loginuid(current); 371 - audit_info.sessionid = audit_get_sessionid(current); 372 - audit_info.secid = smack_to_secid(current_security()); 349 + smk_netlabel_audit_set(&nai); 373 350 374 - rc = netlbl_cfg_map_del(NULL, &audit_info); 351 + rc = netlbl_cfg_map_del(NULL, PF_INET, NULL, NULL, &nai); 375 352 if (rc != 0) 376 353 printk(KERN_WARNING "%s:%d remove rc = %d\n", 377 354 __func__, __LINE__, rc); ··· 384 365 for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++) 385 366 doip->tags[rc] = CIPSO_V4_TAG_INVALID; 386 367 387 - rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info); 368 + rc = netlbl_cfg_cipsov4_add(doip, &nai); 388 369 if (rc != 0) { 389 - printk(KERN_WARNING "%s:%d add rc = %d\n", 370 + printk(KERN_WARNING "%s:%d cipso add rc = %d\n", 390 371 __func__, __LINE__, rc); 391 372 kfree(doip); 373 + return; 374 + } 375 + rc = netlbl_cfg_cipsov4_map_add(doip->doi, NULL, NULL, NULL, &nai); 376 + if (rc != 0) { 377 + printk(KERN_WARNING "%s:%d map add rc = %d\n", 378 + __func__, __LINE__, rc); 379 + kfree(doip); 380 + return; 392 381 } 393 382 } 394 383 ··· 406 379 static void smk_unlbl_ambient(char *oldambient) 407 380 { 408 381 int rc; 409 - struct netlbl_audit audit_info; 382 + struct netlbl_audit nai; 410 383 411 - audit_info.loginuid = audit_get_loginuid(current); 412 - audit_info.sessionid = audit_get_sessionid(current); 413 - audit_info.secid = smack_to_secid(current_security()); 384 + smk_netlabel_audit_set(&nai); 414 385 415 386 if (oldambient != NULL) { 416 - rc = netlbl_cfg_map_del(oldambient, &audit_info); 387 + rc = netlbl_cfg_map_del(oldambient, PF_INET, NULL, NULL, &nai); 417 388 if (rc != 0) 418 389 printk(KERN_WARNING "%s:%d remove rc = %d\n", 419 390 __func__, __LINE__, rc); 420 391 } 421 392 422 - rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info); 393 + rc = netlbl_cfg_unlbl_map_add(smack_net_ambient, PF_INET, 394 + NULL, NULL, &nai); 423 395 if (rc != 0) 424 396 printk(KERN_WARNING "%s:%d add rc = %d\n", 425 397 __func__, __LINE__, rc); ··· 626 600 .read = seq_read, 627 601 .llseek = seq_lseek, 628 602 .write = smk_write_cipso, 603 + .release = seq_release, 604 + }; 605 + 606 + /* 607 + * Seq_file read operations for /smack/netlabel 608 + */ 609 + 610 + static void *netlbladdr_seq_start(struct seq_file *s, loff_t *pos) 611 + { 612 + if (*pos == SEQ_READ_FINISHED) 613 + return NULL; 614 + 615 + return smack_netlbladdrs; 616 + } 617 + 618 + static void *netlbladdr_seq_next(struct seq_file *s, void *v, loff_t *pos) 619 + { 620 + struct smk_netlbladdr *skp = ((struct smk_netlbladdr *) v)->smk_next; 621 + 622 + if (skp == NULL) 623 + *pos = SEQ_READ_FINISHED; 624 + 625 + return skp; 626 + } 627 + /* 628 + #define BEMASK 0x80000000 629 + */ 630 + #define BEMASK 0x00000001 631 + #define BEBITS (sizeof(__be32) * 8) 632 + 633 + /* 634 + * Print host/label pairs 635 + */ 636 + static int netlbladdr_seq_show(struct seq_file *s, void *v) 637 + { 638 + struct smk_netlbladdr *skp = (struct smk_netlbladdr *) v; 639 + unsigned char *hp = (char *) &skp->smk_host.sin_addr.s_addr; 640 + __be32 bebits; 641 + int maskn = 0; 642 + 643 + for (bebits = BEMASK; bebits != 0; maskn++, bebits <<= 1) 644 + if ((skp->smk_mask.s_addr & bebits) == 0) 645 + break; 646 + 647 + seq_printf(s, "%u.%u.%u.%u/%d %s\n", 648 + hp[0], hp[1], hp[2], hp[3], maskn, skp->smk_label); 649 + 650 + return 0; 651 + } 652 + 653 + static void netlbladdr_seq_stop(struct seq_file *s, void *v) 654 + { 655 + /* No-op */ 656 + } 657 + 658 + static struct seq_operations netlbladdr_seq_ops = { 659 + .start = netlbladdr_seq_start, 660 + .stop = netlbladdr_seq_stop, 661 + .next = netlbladdr_seq_next, 662 + .show = netlbladdr_seq_show, 663 + }; 664 + 665 + /** 666 + * smk_open_netlbladdr - open() for /smack/netlabel 667 + * @inode: inode structure representing file 668 + * @file: "netlabel" file pointer 669 + * 670 + * Connect our netlbladdr_seq_* operations with /smack/netlabel 671 + * file_operations 672 + */ 673 + static int smk_open_netlbladdr(struct inode *inode, struct file *file) 674 + { 675 + return seq_open(file, &netlbladdr_seq_ops); 676 + } 677 + 678 + /** 679 + * smk_write_netlbladdr - write() for /smack/netlabel 680 + * @filp: file pointer, not actually used 681 + * @buf: where to get the data from 682 + * @count: bytes sent 683 + * @ppos: where to start 684 + * 685 + * Accepts only one netlbladdr per write call. 686 + * Returns number of bytes written or error code, as appropriate 687 + */ 688 + static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, 689 + size_t count, loff_t *ppos) 690 + { 691 + struct smk_netlbladdr *skp; 692 + struct sockaddr_in newname; 693 + char smack[SMK_LABELLEN]; 694 + char *sp; 695 + char data[SMK_NETLBLADDRMAX]; 696 + char *host = (char *)&newname.sin_addr.s_addr; 697 + int rc; 698 + struct netlbl_audit audit_info; 699 + struct in_addr mask; 700 + unsigned int m; 701 + __be32 bebits = BEMASK; 702 + __be32 nsa; 703 + 704 + /* 705 + * Must have privilege. 706 + * No partial writes. 707 + * Enough data must be present. 708 + * "<addr/mask, as a.b.c.d/e><space><label>" 709 + * "<addr, as a.b.c.d><space><label>" 710 + */ 711 + if (!capable(CAP_MAC_ADMIN)) 712 + return -EPERM; 713 + if (*ppos != 0) 714 + return -EINVAL; 715 + if (count < SMK_NETLBLADDRMIN || count > SMK_NETLBLADDRMAX) 716 + return -EINVAL; 717 + if (copy_from_user(data, buf, count) != 0) 718 + return -EFAULT; 719 + 720 + data[count] = '\0'; 721 + 722 + rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%d %s", 723 + &host[0], &host[1], &host[2], &host[3], &m, smack); 724 + if (rc != 6) { 725 + rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd %s", 726 + &host[0], &host[1], &host[2], &host[3], smack); 727 + if (rc != 5) 728 + return -EINVAL; 729 + m = BEBITS; 730 + } 731 + if (m > BEBITS) 732 + return -EINVAL; 733 + 734 + sp = smk_import(smack, 0); 735 + if (sp == NULL) 736 + return -EINVAL; 737 + 738 + for (mask.s_addr = 0; m > 0; m--) { 739 + mask.s_addr |= bebits; 740 + bebits <<= 1; 741 + } 742 + /* 743 + * Only allow one writer at a time. Writes should be 744 + * quite rare and small in any case. 745 + */ 746 + mutex_lock(&smk_netlbladdr_lock); 747 + 748 + nsa = newname.sin_addr.s_addr; 749 + for (skp = smack_netlbladdrs; skp != NULL; skp = skp->smk_next) 750 + if (skp->smk_host.sin_addr.s_addr == nsa && 751 + skp->smk_mask.s_addr == mask.s_addr) 752 + break; 753 + 754 + smk_netlabel_audit_set(&audit_info); 755 + 756 + if (skp == NULL) { 757 + skp = kzalloc(sizeof(*skp), GFP_KERNEL); 758 + if (skp == NULL) 759 + rc = -ENOMEM; 760 + else { 761 + rc = 0; 762 + skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; 763 + skp->smk_mask.s_addr = mask.s_addr; 764 + skp->smk_next = smack_netlbladdrs; 765 + skp->smk_label = sp; 766 + smack_netlbladdrs = skp; 767 + } 768 + } else { 769 + rc = netlbl_cfg_unlbl_static_del(&init_net, NULL, 770 + &skp->smk_host.sin_addr, &skp->smk_mask, 771 + PF_INET, &audit_info); 772 + skp->smk_label = sp; 773 + } 774 + 775 + /* 776 + * Now tell netlabel about the single label nature of 777 + * this host so that incoming packets get labeled. 778 + */ 779 + 780 + if (rc == 0) 781 + rc = netlbl_cfg_unlbl_static_add(&init_net, NULL, 782 + &skp->smk_host.sin_addr, &skp->smk_mask, PF_INET, 783 + smack_to_secid(skp->smk_label), &audit_info); 784 + 785 + if (rc == 0) 786 + rc = count; 787 + 788 + mutex_unlock(&smk_netlbladdr_lock); 789 + 790 + return rc; 791 + } 792 + 793 + static const struct file_operations smk_netlbladdr_ops = { 794 + .open = smk_open_netlbladdr, 795 + .read = seq_read, 796 + .llseek = seq_lseek, 797 + .write = smk_write_netlbladdr, 629 798 .release = seq_release, 630 799 }; 631 800 ··· 1112 891 .write = smk_write_onlycap, 1113 892 }; 1114 893 1115 - struct option_names { 1116 - int o_number; 1117 - char *o_name; 1118 - char *o_alias; 1119 - }; 1120 - 1121 - static struct option_names netlbl_choices[] = { 1122 - { NETLBL_NLTYPE_RIPSO, 1123 - NETLBL_NLTYPE_RIPSO_NAME, "ripso" }, 1124 - { NETLBL_NLTYPE_CIPSOV4, 1125 - NETLBL_NLTYPE_CIPSOV4_NAME, "cipsov4" }, 1126 - { NETLBL_NLTYPE_CIPSOV4, 1127 - NETLBL_NLTYPE_CIPSOV4_NAME, "cipso" }, 1128 - { NETLBL_NLTYPE_CIPSOV6, 1129 - NETLBL_NLTYPE_CIPSOV6_NAME, "cipsov6" }, 1130 - { NETLBL_NLTYPE_UNLABELED, 1131 - NETLBL_NLTYPE_UNLABELED_NAME, "unlabeled" }, 1132 - }; 1133 - 1134 - /** 1135 - * smk_read_nltype - read() for /smack/nltype 1136 - * @filp: file pointer, not actually used 1137 - * @buf: where to put the result 1138 - * @count: maximum to send along 1139 - * @ppos: where to start 1140 - * 1141 - * Returns number of bytes read or error code, as appropriate 1142 - */ 1143 - static ssize_t smk_read_nltype(struct file *filp, char __user *buf, 1144 - size_t count, loff_t *ppos) 1145 - { 1146 - char bound[40]; 1147 - ssize_t rc; 1148 - int i; 1149 - 1150 - if (count < SMK_LABELLEN) 1151 - return -EINVAL; 1152 - 1153 - if (*ppos != 0) 1154 - return 0; 1155 - 1156 - sprintf(bound, "unknown"); 1157 - 1158 - for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) 1159 - if (smack_net_nltype == netlbl_choices[i].o_number) { 1160 - sprintf(bound, "%s", netlbl_choices[i].o_name); 1161 - break; 1162 - } 1163 - 1164 - rc = simple_read_from_buffer(buf, count, ppos, bound, strlen(bound)); 1165 - 1166 - return rc; 1167 - } 1168 - 1169 - /** 1170 - * smk_write_nltype - write() for /smack/nltype 1171 - * @filp: file pointer, not actually used 1172 - * @buf: where to get the data from 1173 - * @count: bytes sent 1174 - * @ppos: where to start 1175 - * 1176 - * Returns number of bytes written or error code, as appropriate 1177 - */ 1178 - static ssize_t smk_write_nltype(struct file *file, const char __user *buf, 1179 - size_t count, loff_t *ppos) 1180 - { 1181 - char bound[40]; 1182 - char *cp; 1183 - int i; 1184 - 1185 - if (!capable(CAP_MAC_ADMIN)) 1186 - return -EPERM; 1187 - 1188 - if (count >= 40) 1189 - return -EINVAL; 1190 - 1191 - if (copy_from_user(bound, buf, count) != 0) 1192 - return -EFAULT; 1193 - 1194 - bound[count] = '\0'; 1195 - cp = strchr(bound, ' '); 1196 - if (cp != NULL) 1197 - *cp = '\0'; 1198 - cp = strchr(bound, '\n'); 1199 - if (cp != NULL) 1200 - *cp = '\0'; 1201 - 1202 - for (i = 0; i < ARRAY_SIZE(netlbl_choices); i++) 1203 - if (strcmp(bound, netlbl_choices[i].o_name) == 0 || 1204 - strcmp(bound, netlbl_choices[i].o_alias) == 0) { 1205 - smack_net_nltype = netlbl_choices[i].o_number; 1206 - return count; 1207 - } 1208 - /* 1209 - * Not a valid choice. 1210 - */ 1211 - return -EINVAL; 1212 - } 1213 - 1214 - static const struct file_operations smk_nltype_ops = { 1215 - .read = smk_read_nltype, 1216 - .write = smk_write_nltype, 1217 - }; 1218 - 1219 894 /** 1220 895 * smk_fill_super - fill the /smackfs superblock 1221 896 * @sb: the empty superblock ··· 1138 1021 {"direct", &smk_direct_ops, S_IRUGO|S_IWUSR}, 1139 1022 [SMK_AMBIENT] = 1140 1023 {"ambient", &smk_ambient_ops, S_IRUGO|S_IWUSR}, 1141 - [SMK_NLTYPE] = 1142 - {"nltype", &smk_nltype_ops, S_IRUGO|S_IWUSR}, 1024 + [SMK_NETLBLADDR] = 1025 + {"netlabel", &smk_netlbladdr_ops, S_IRUGO|S_IWUSR}, 1143 1026 [SMK_ONLYCAP] = 1144 1027 {"onlycap", &smk_onlycap_ops, S_IRUGO|S_IWUSR}, 1145 1028 /* last one */ {""}