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

Merge tag 'selinux-pr-20220321' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:
"We've got a number of SELinux patches queued up, the highlights are:

- Fixup the security_fs_context_parse_param() LSM hook so it executes
all of the LSM hook implementations unless a serious error occurs.

We also correct the SELinux hook implementation so that it returns
zero on success.

- In addition to a few SELinux mount option parsing fixes, we
simplified the parsing by moving it earlier in the process.

The logic was that it was unlikely an admin/user would use the new
mount API and not have the policy loaded before passing the SELinux
options.

- Properly fixed the LSM/SELinux/SCTP hooks with the addition of the
security_sctp_assoc_established() hook.

This work was done in conjunction with the netdev folks and should
complete the move of the SCTP labeling from the endpoints to the
associations.

- Fixed a variety of sparse warnings caused by changes in the "__rcu"
markings of some core kernel structures.

- Ensure we access the superblock's LSM security blob using the
stacking-safe accessors.

- Added the ability for the kernel to always allow FIOCLEX and
FIONCLEX if the "ioctl_skip_cloexec" policy capability is
specified.

- Various constifications improvements, type casting improvements,
additional return value checks, and dead code/parameter removal.

- Documentation fixes"

* tag 'selinux-pr-20220321' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: (23 commits)
selinux: shorten the policy capability enum names
docs: fix 'make htmldocs' warning in SCTP.rst
selinux: allow FIOCLEX and FIONCLEX with policy capability
selinux: use correct type for context length
selinux: drop return statement at end of void functions
security: implement sctp_assoc_established hook in selinux
security: add sctp_assoc_established hook
selinux: parse contexts for mount options early
selinux: various sparse fixes
selinux: try to use preparsed sid before calling parse_sid()
selinux: Fix selinux_sb_mnt_opts_compat()
LSM: general protection fault in legacy_parse_param
selinux: fix a type cast problem in cred_init_security()
selinux: drop unused macro
selinux: simplify cred_init_security
selinux: do not discard const qualifier in cast
selinux: drop unused parameter of avtab_insert_node
selinux: drop cast to same type
selinux: enclose macro arguments in parenthesis
selinux: declare name parameter of hash_eval const
...

+255 -231
+12 -14
Documentation/security/SCTP.rst
··· 15 15 security_sctp_assoc_request() 16 16 security_sctp_bind_connect() 17 17 security_sctp_sk_clone() 18 - 19 - Also the following security hook has been utilised:: 20 - 21 - security_inet_conn_established() 18 + security_sctp_assoc_established() 22 19 23 20 The usage of these hooks are described below with the SELinux implementation 24 21 described in the `SCTP SELinux Support`_ chapter. ··· 119 122 @newsk - pointer to new sock structure. 120 123 121 124 122 - security_inet_conn_established() 123 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 124 - Called when a COOKIE ACK is received:: 125 + security_sctp_assoc_established() 126 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 + Called when a COOKIE ACK is received, and the peer secid will be 128 + saved into ``@asoc->peer_secid`` for client:: 125 129 126 - @sk - pointer to sock structure. 130 + @asoc - pointer to sctp association structure. 127 131 @skb - pointer to skbuff of the COOKIE ACK packet. 128 132 129 133 ··· 132 134 ------------------------------------------------- 133 135 134 136 The following diagram shows the use of ``security_sctp_bind_connect()``, 135 - ``security_sctp_assoc_request()``, ``security_inet_conn_established()`` when 137 + ``security_sctp_assoc_request()``, ``security_sctp_assoc_established()`` when 136 138 establishing an association. 137 139 :: 138 140 ··· 170 172 <------------------------------------------- COOKIE ACK 171 173 | | 172 174 sctp_sf_do_5_1E_ca | 173 - Call security_inet_conn_established() | 175 + Call security_sctp_assoc_established() | 174 176 to set the peer label. | 175 177 | | 176 178 | If SCTP_SOCKET_TCP or peeled off ··· 196 198 security_sctp_assoc_request() 197 199 security_sctp_bind_connect() 198 200 security_sctp_sk_clone() 199 - security_inet_conn_established() 201 + security_sctp_assoc_established() 200 202 201 203 202 204 security_sctp_assoc_request() ··· 269 271 @newsk - pointer to new sock structure. 270 272 271 273 272 - security_inet_conn_established() 273 - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 274 + security_sctp_assoc_established() 275 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 274 276 Called when a COOKIE ACK is received where it sets the connection's peer sid 275 277 to that in ``@skb``:: 276 278 277 - @sk - pointer to sock structure. 279 + @asoc - pointer to sctp association structure. 278 280 @skb - pointer to skbuff of the COOKIE ACK packet. 279 281 280 282
+2
include/linux/lsm_hook_defs.h
··· 332 332 struct sockaddr *address, int addrlen) 333 333 LSM_HOOK(void, LSM_RET_VOID, sctp_sk_clone, struct sctp_association *asoc, 334 334 struct sock *sk, struct sock *newsk) 335 + LSM_HOOK(int, 0, sctp_assoc_established, struct sctp_association *asoc, 336 + struct sk_buff *skb) 335 337 #endif /* CONFIG_SECURITY_NETWORK */ 336 338 337 339 #ifdef CONFIG_SECURITY_INFINIBAND
+5
include/linux/lsm_hooks.h
··· 1046 1046 * @asoc pointer to current sctp association structure. 1047 1047 * @sk pointer to current sock structure. 1048 1048 * @newsk pointer to new sock structure. 1049 + * @sctp_assoc_established: 1050 + * Passes the @asoc and @chunk->skb of the association COOKIE_ACK packet 1051 + * to the security module. 1052 + * @asoc pointer to sctp association structure. 1053 + * @skb pointer to skbuff of association packet. 1049 1054 * 1050 1055 * Security hooks for Infiniband 1051 1056 *
+8
include/linux/security.h
··· 1422 1422 struct sockaddr *address, int addrlen); 1423 1423 void security_sctp_sk_clone(struct sctp_association *asoc, struct sock *sk, 1424 1424 struct sock *newsk); 1425 + int security_sctp_assoc_established(struct sctp_association *asoc, 1426 + struct sk_buff *skb); 1425 1427 1426 1428 #else /* CONFIG_SECURITY_NETWORK */ 1427 1429 static inline int security_unix_stream_connect(struct sock *sock, ··· 1642 1640 struct sock *sk, 1643 1641 struct sock *newsk) 1644 1642 { 1643 + } 1644 + 1645 + static inline int security_sctp_assoc_established(struct sctp_association *asoc, 1646 + struct sk_buff *skb) 1647 + { 1648 + return 0; 1645 1649 } 1646 1650 #endif /* CONFIG_SECURITY_NETWORK */ 1647 1651
+5 -3
net/sctp/sm_statefuns.c
··· 930 930 if (!sctp_vtag_verify(chunk, asoc)) 931 931 return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); 932 932 933 + /* Set peer label for connection. */ 934 + if (security_sctp_assoc_established((struct sctp_association *)asoc, 935 + chunk->skb)) 936 + return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); 937 + 933 938 /* Verify that the chunk length for the COOKIE-ACK is OK. 934 939 * If we don't do this, any bundled chunks may be junked. 935 940 */ ··· 949 944 * state is performed. 950 945 */ 951 946 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_COUNTER_RESET, SCTP_NULL()); 952 - 953 - /* Set peer label for connection. */ 954 - security_inet_conn_established(ep->base.sk, chunk->skb); 955 947 956 948 /* RFC 2960 5.1 Normal Establishment of an Association 957 949 *
+22 -2
security/security.c
··· 884 884 return call_int_hook(fs_context_dup, 0, fc, src_fc); 885 885 } 886 886 887 - int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param) 887 + int security_fs_context_parse_param(struct fs_context *fc, 888 + struct fs_parameter *param) 888 889 { 889 - return call_int_hook(fs_context_parse_param, -ENOPARAM, fc, param); 890 + struct security_hook_list *hp; 891 + int trc; 892 + int rc = -ENOPARAM; 893 + 894 + hlist_for_each_entry(hp, &security_hook_heads.fs_context_parse_param, 895 + list) { 896 + trc = hp->hook.fs_context_parse_param(fc, param); 897 + if (trc == 0) 898 + rc = 0; 899 + else if (trc != -ENOPARAM) 900 + return trc; 901 + } 902 + return rc; 890 903 } 891 904 892 905 int security_sb_alloc(struct super_block *sb) ··· 2403 2390 call_void_hook(sctp_sk_clone, asoc, sk, newsk); 2404 2391 } 2405 2392 EXPORT_SYMBOL(security_sctp_sk_clone); 2393 + 2394 + int security_sctp_assoc_established(struct sctp_association *asoc, 2395 + struct sk_buff *skb) 2396 + { 2397 + return call_int_hook(sctp_assoc_established, 0, asoc, skb); 2398 + } 2399 + EXPORT_SYMBOL(security_sctp_assoc_established); 2406 2400 2407 2401 #endif /* CONFIG_SECURITY_NETWORK */ 2408 2402
+142 -157
security/selinux/hooks.c
··· 211 211 */ 212 212 static void cred_init_security(void) 213 213 { 214 - struct cred *cred = (struct cred *) current->real_cred; 215 214 struct task_security_struct *tsec; 216 215 217 - tsec = selinux_cred(cred); 216 + tsec = selinux_cred(unrcu_pointer(current->real_cred)); 218 217 tsec->osid = tsec->sid = SECINITSID_KERNEL; 219 218 } 220 219 ··· 340 341 } 341 342 342 343 struct selinux_mnt_opts { 343 - const char *fscontext, *context, *rootcontext, *defcontext; 344 + u32 fscontext_sid; 345 + u32 context_sid; 346 + u32 rootcontext_sid; 347 + u32 defcontext_sid; 344 348 }; 345 349 346 350 static void selinux_free_mnt_opts(void *mnt_opts) 347 351 { 348 - struct selinux_mnt_opts *opts = mnt_opts; 349 - kfree(opts->fscontext); 350 - kfree(opts->context); 351 - kfree(opts->rootcontext); 352 - kfree(opts->defcontext); 353 - kfree(opts); 352 + kfree(mnt_opts); 354 353 } 355 354 356 355 enum { ··· 476 479 477 480 static int sb_check_xattr_support(struct super_block *sb) 478 481 { 479 - struct superblock_security_struct *sbsec = sb->s_security; 482 + struct superblock_security_struct *sbsec = selinux_superblock(sb); 480 483 struct dentry *root = sb->s_root; 481 484 struct inode *root_inode = d_backing_inode(root); 482 485 u32 sid; ··· 595 598 return 0; 596 599 } 597 600 598 - static int parse_sid(struct super_block *sb, const char *s, u32 *sid, 599 - gfp_t gfp) 600 - { 601 - int rc = security_context_str_to_sid(&selinux_state, s, 602 - sid, gfp); 603 - if (rc) 604 - pr_warn("SELinux: security_context_str_to_sid" 605 - "(%s) failed for (dev %s, type %s) errno=%d\n", 606 - s, sb->s_id, sb->s_type->name, rc); 607 - return rc; 608 - } 609 - 610 601 /* 611 602 * Allow filesystems with binary mount data to explicitly set mount point 612 603 * labeling information. ··· 657 672 * than once with different security options. 658 673 */ 659 674 if (opts) { 660 - if (opts->fscontext) { 661 - rc = parse_sid(sb, opts->fscontext, &fscontext_sid, 662 - GFP_KERNEL); 663 - if (rc) 664 - goto out; 675 + if (opts->fscontext_sid) { 676 + fscontext_sid = opts->fscontext_sid; 665 677 if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, 666 678 fscontext_sid)) 667 679 goto out_double_mount; 668 680 sbsec->flags |= FSCONTEXT_MNT; 669 681 } 670 - if (opts->context) { 671 - rc = parse_sid(sb, opts->context, &context_sid, 672 - GFP_KERNEL); 673 - if (rc) 674 - goto out; 682 + if (opts->context_sid) { 683 + context_sid = opts->context_sid; 675 684 if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, 676 685 context_sid)) 677 686 goto out_double_mount; 678 687 sbsec->flags |= CONTEXT_MNT; 679 688 } 680 - if (opts->rootcontext) { 681 - rc = parse_sid(sb, opts->rootcontext, &rootcontext_sid, 682 - GFP_KERNEL); 683 - if (rc) 684 - goto out; 689 + if (opts->rootcontext_sid) { 690 + rootcontext_sid = opts->rootcontext_sid; 685 691 if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, 686 692 rootcontext_sid)) 687 693 goto out_double_mount; 688 694 sbsec->flags |= ROOTCONTEXT_MNT; 689 695 } 690 - if (opts->defcontext) { 691 - rc = parse_sid(sb, opts->defcontext, &defcontext_sid, 692 - GFP_KERNEL); 693 - if (rc) 694 - goto out; 696 + if (opts->defcontext_sid) { 697 + defcontext_sid = opts->defcontext_sid; 695 698 if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, 696 699 defcontext_sid)) 697 700 goto out_double_mount; ··· 949 976 { 950 977 struct selinux_mnt_opts *opts = *mnt_opts; 951 978 bool is_alloc_opts = false; 979 + u32 *dst_sid; 980 + int rc; 952 981 953 982 if (token == Opt_seclabel) 954 983 /* eaten and completely ignored */ 955 984 return 0; 956 985 if (!s) 957 986 return -ENOMEM; 987 + 988 + if (!selinux_initialized(&selinux_state)) { 989 + pr_warn("SELinux: Unable to set superblock options before the security server is initialized\n"); 990 + return -EINVAL; 991 + } 958 992 959 993 if (!opts) { 960 994 opts = kzalloc(sizeof(*opts), GFP_KERNEL); ··· 973 993 974 994 switch (token) { 975 995 case Opt_context: 976 - if (opts->context || opts->defcontext) 996 + if (opts->context_sid || opts->defcontext_sid) 977 997 goto err; 978 - opts->context = s; 998 + dst_sid = &opts->context_sid; 979 999 break; 980 1000 case Opt_fscontext: 981 - if (opts->fscontext) 1001 + if (opts->fscontext_sid) 982 1002 goto err; 983 - opts->fscontext = s; 1003 + dst_sid = &opts->fscontext_sid; 984 1004 break; 985 1005 case Opt_rootcontext: 986 - if (opts->rootcontext) 1006 + if (opts->rootcontext_sid) 987 1007 goto err; 988 - opts->rootcontext = s; 1008 + dst_sid = &opts->rootcontext_sid; 989 1009 break; 990 1010 case Opt_defcontext: 991 - if (opts->context || opts->defcontext) 1011 + if (opts->context_sid || opts->defcontext_sid) 992 1012 goto err; 993 - opts->defcontext = s; 1013 + dst_sid = &opts->defcontext_sid; 994 1014 break; 1015 + default: 1016 + WARN_ON(1); 1017 + return -EINVAL; 995 1018 } 996 - 997 - return 0; 1019 + rc = security_context_str_to_sid(&selinux_state, s, dst_sid, GFP_KERNEL); 1020 + if (rc) 1021 + pr_warn("SELinux: security_context_str_to_sid (%s) failed with errno=%d\n", 1022 + s, rc); 1023 + return rc; 998 1024 999 1025 err: 1000 1026 if (is_alloc_opts) { ··· 2521 2535 if (rc) { 2522 2536 clear_itimer(); 2523 2537 2524 - spin_lock_irq(&current->sighand->siglock); 2538 + spin_lock_irq(&unrcu_pointer(current->sighand)->siglock); 2525 2539 if (!fatal_signal_pending(current)) { 2526 2540 flush_sigqueue(&current->pending); 2527 2541 flush_sigqueue(&current->signal->shared_pending); ··· 2529 2543 sigemptyset(&current->blocked); 2530 2544 recalc_sigpending(); 2531 2545 } 2532 - spin_unlock_irq(&current->sighand->siglock); 2546 + spin_unlock_irq(&unrcu_pointer(current->sighand)->siglock); 2533 2547 } 2534 2548 2535 2549 /* Wake up the parent if it is waiting so that it can recheck 2536 2550 * wait permission to the new task SID. */ 2537 2551 read_lock(&tasklist_lock); 2538 - __wake_up_parent(current, current->real_parent); 2552 + __wake_up_parent(current, unrcu_pointer(current->real_parent)); 2539 2553 read_unlock(&tasklist_lock); 2540 2554 } 2541 2555 ··· 2633 2647 static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts) 2634 2648 { 2635 2649 struct selinux_mnt_opts *opts = mnt_opts; 2636 - struct superblock_security_struct *sbsec = sb->s_security; 2637 - u32 sid; 2638 - int rc; 2650 + struct superblock_security_struct *sbsec = selinux_superblock(sb); 2639 2651 2640 2652 /* 2641 2653 * Superblock not initialized (i.e. no options) - reject if any ··· 2649 2665 if (!opts) 2650 2666 return (sbsec->flags & SE_MNTMASK) ? 1 : 0; 2651 2667 2652 - if (opts->fscontext) { 2653 - rc = parse_sid(sb, opts->fscontext, &sid, GFP_NOWAIT); 2654 - if (rc) 2655 - return 1; 2656 - if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) 2668 + if (opts->fscontext_sid) { 2669 + if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, 2670 + opts->fscontext_sid)) 2657 2671 return 1; 2658 2672 } 2659 - if (opts->context) { 2660 - rc = parse_sid(sb, opts->context, &sid, GFP_NOWAIT); 2661 - if (rc) 2662 - return 1; 2663 - if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) 2673 + if (opts->context_sid) { 2674 + if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, 2675 + opts->context_sid)) 2664 2676 return 1; 2665 2677 } 2666 - if (opts->rootcontext) { 2678 + if (opts->rootcontext_sid) { 2667 2679 struct inode_security_struct *root_isec; 2668 2680 2669 2681 root_isec = backing_inode_security(sb->s_root); 2670 - rc = parse_sid(sb, opts->rootcontext, &sid, GFP_NOWAIT); 2671 - if (rc) 2672 - return 1; 2673 - if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) 2682 + if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, 2683 + opts->rootcontext_sid)) 2674 2684 return 1; 2675 2685 } 2676 - if (opts->defcontext) { 2677 - rc = parse_sid(sb, opts->defcontext, &sid, GFP_NOWAIT); 2678 - if (rc) 2679 - return 1; 2680 - if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) 2686 + if (opts->defcontext_sid) { 2687 + if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, 2688 + opts->defcontext_sid)) 2681 2689 return 1; 2682 2690 } 2683 2691 return 0; ··· 2679 2703 { 2680 2704 struct selinux_mnt_opts *opts = mnt_opts; 2681 2705 struct superblock_security_struct *sbsec = selinux_superblock(sb); 2682 - u32 sid; 2683 - int rc; 2684 2706 2685 2707 if (!(sbsec->flags & SE_SBINITIALIZED)) 2686 2708 return 0; ··· 2686 2712 if (!opts) 2687 2713 return 0; 2688 2714 2689 - if (opts->fscontext) { 2690 - rc = parse_sid(sb, opts->fscontext, &sid, GFP_KERNEL); 2691 - if (rc) 2692 - return rc; 2693 - if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) 2715 + if (opts->fscontext_sid) { 2716 + if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, 2717 + opts->fscontext_sid)) 2694 2718 goto out_bad_option; 2695 2719 } 2696 - if (opts->context) { 2697 - rc = parse_sid(sb, opts->context, &sid, GFP_KERNEL); 2698 - if (rc) 2699 - return rc; 2700 - if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid)) 2720 + if (opts->context_sid) { 2721 + if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, 2722 + opts->context_sid)) 2701 2723 goto out_bad_option; 2702 2724 } 2703 - if (opts->rootcontext) { 2725 + if (opts->rootcontext_sid) { 2704 2726 struct inode_security_struct *root_isec; 2705 2727 root_isec = backing_inode_security(sb->s_root); 2706 - rc = parse_sid(sb, opts->rootcontext, &sid, GFP_KERNEL); 2707 - if (rc) 2708 - return rc; 2709 - if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid)) 2728 + if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, 2729 + opts->rootcontext_sid)) 2710 2730 goto out_bad_option; 2711 2731 } 2712 - if (opts->defcontext) { 2713 - rc = parse_sid(sb, opts->defcontext, &sid, GFP_KERNEL); 2714 - if (rc) 2715 - return rc; 2716 - if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid)) 2732 + if (opts->defcontext_sid) { 2733 + if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, 2734 + opts->defcontext_sid)) 2717 2735 goto out_bad_option; 2718 2736 } 2719 2737 return 0; ··· 2772 2806 struct fs_context *src_fc) 2773 2807 { 2774 2808 const struct selinux_mnt_opts *src = src_fc->security; 2775 - struct selinux_mnt_opts *opts; 2776 2809 2777 2810 if (!src) 2778 2811 return 0; 2779 2812 2780 - fc->security = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); 2781 - if (!fc->security) 2782 - return -ENOMEM; 2783 - 2784 - opts = fc->security; 2785 - 2786 - if (src->fscontext) { 2787 - opts->fscontext = kstrdup(src->fscontext, GFP_KERNEL); 2788 - if (!opts->fscontext) 2789 - return -ENOMEM; 2790 - } 2791 - if (src->context) { 2792 - opts->context = kstrdup(src->context, GFP_KERNEL); 2793 - if (!opts->context) 2794 - return -ENOMEM; 2795 - } 2796 - if (src->rootcontext) { 2797 - opts->rootcontext = kstrdup(src->rootcontext, GFP_KERNEL); 2798 - if (!opts->rootcontext) 2799 - return -ENOMEM; 2800 - } 2801 - if (src->defcontext) { 2802 - opts->defcontext = kstrdup(src->defcontext, GFP_KERNEL); 2803 - if (!opts->defcontext) 2804 - return -ENOMEM; 2805 - } 2806 - return 0; 2813 + fc->security = kmemdup(src, sizeof(*src), GFP_KERNEL); 2814 + return fc->security ? 0 : -ENOMEM; 2807 2815 } 2808 2816 2809 2817 static const struct fs_parameter_spec selinux_fs_parameters[] = { ··· 2800 2860 return opt; 2801 2861 2802 2862 rc = selinux_add_opt(opt, param->string, &fc->security); 2803 - if (!rc) { 2863 + if (!rc) 2804 2864 param->string = NULL; 2805 - rc = 1; 2806 - } 2865 + 2807 2866 return rc; 2808 2867 } 2809 2868 ··· 3284 3345 isec->sid = newsid; 3285 3346 isec->initialized = LABEL_INITIALIZED; 3286 3347 spin_unlock(&isec->lock); 3287 - 3288 - return; 3289 3348 } 3290 3349 3291 3350 static int selinux_inode_getxattr(struct dentry *dentry, const char *name) ··· 3680 3743 case KDSKBSENT: 3681 3744 error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, 3682 3745 CAP_OPT_NONE, true); 3746 + break; 3747 + 3748 + case FIOCLEX: 3749 + case FIONCLEX: 3750 + if (!selinux_policycap_ioctl_skip_cloexec()) 3751 + error = ioctl_has_perm(cred, file, FILE__IOCTL, (u16) cmd); 3683 3752 break; 3684 3753 3685 3754 /* default case assumes that the command will go ··· 5242 5299 sksec->sclass = isec->sclass; 5243 5300 } 5244 5301 5245 - /* Called whenever SCTP receives an INIT chunk. This happens when an incoming 5246 - * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association 5247 - * already present). 5302 + /* 5303 + * Determines peer_secid for the asoc and updates socket's peer label 5304 + * if it's the first association on the socket. 5248 5305 */ 5249 - static int selinux_sctp_assoc_request(struct sctp_association *asoc, 5250 - struct sk_buff *skb) 5306 + static int selinux_sctp_process_new_assoc(struct sctp_association *asoc, 5307 + struct sk_buff *skb) 5251 5308 { 5252 - struct sk_security_struct *sksec = asoc->base.sk->sk_security; 5309 + struct sock *sk = asoc->base.sk; 5310 + u16 family = sk->sk_family; 5311 + struct sk_security_struct *sksec = sk->sk_security; 5253 5312 struct common_audit_data ad; 5254 5313 struct lsm_network_audit net = {0,}; 5255 - u8 peerlbl_active; 5256 - u32 peer_sid = SECINITSID_UNLABELED; 5257 - u32 conn_sid; 5258 - int err = 0; 5314 + int err; 5259 5315 5260 - if (!selinux_policycap_extsockclass()) 5261 - return 0; 5316 + /* handle mapped IPv4 packets arriving via IPv6 sockets */ 5317 + if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) 5318 + family = PF_INET; 5262 5319 5263 - peerlbl_active = selinux_peerlbl_enabled(); 5320 + if (selinux_peerlbl_enabled()) { 5321 + asoc->peer_secid = SECSID_NULL; 5264 5322 5265 - if (peerlbl_active) { 5266 5323 /* This will return peer_sid = SECSID_NULL if there are 5267 5324 * no peer labels, see security_net_peersid_resolve(). 5268 5325 */ 5269 - err = selinux_skb_peerlbl_sid(skb, asoc->base.sk->sk_family, 5270 - &peer_sid); 5326 + err = selinux_skb_peerlbl_sid(skb, family, &asoc->peer_secid); 5271 5327 if (err) 5272 5328 return err; 5273 5329 5274 - if (peer_sid == SECSID_NULL) 5275 - peer_sid = SECINITSID_UNLABELED; 5330 + if (asoc->peer_secid == SECSID_NULL) 5331 + asoc->peer_secid = SECINITSID_UNLABELED; 5332 + } else { 5333 + asoc->peer_secid = SECINITSID_UNLABELED; 5276 5334 } 5277 5335 5278 5336 if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) { ··· 5284 5340 * then it is approved by policy and used as the primary 5285 5341 * peer SID for getpeercon(3). 5286 5342 */ 5287 - sksec->peer_sid = peer_sid; 5288 - } else if (sksec->peer_sid != peer_sid) { 5343 + sksec->peer_sid = asoc->peer_secid; 5344 + } else if (sksec->peer_sid != asoc->peer_secid) { 5289 5345 /* Other association peer SIDs are checked to enforce 5290 5346 * consistency among the peer SIDs. 5291 5347 */ ··· 5293 5349 ad.u.net = &net; 5294 5350 ad.u.net->sk = asoc->base.sk; 5295 5351 err = avc_has_perm(&selinux_state, 5296 - sksec->peer_sid, peer_sid, sksec->sclass, 5297 - SCTP_SOCKET__ASSOCIATION, &ad); 5352 + sksec->peer_sid, asoc->peer_secid, 5353 + sksec->sclass, SCTP_SOCKET__ASSOCIATION, 5354 + &ad); 5298 5355 if (err) 5299 5356 return err; 5300 5357 } 5358 + return 0; 5359 + } 5360 + 5361 + /* Called whenever SCTP receives an INIT or COOKIE ECHO chunk. This 5362 + * happens on an incoming connect(2), sctp_connectx(3) or 5363 + * sctp_sendmsg(3) (with no association already present). 5364 + */ 5365 + static int selinux_sctp_assoc_request(struct sctp_association *asoc, 5366 + struct sk_buff *skb) 5367 + { 5368 + struct sk_security_struct *sksec = asoc->base.sk->sk_security; 5369 + u32 conn_sid; 5370 + int err; 5371 + 5372 + if (!selinux_policycap_extsockclass()) 5373 + return 0; 5374 + 5375 + err = selinux_sctp_process_new_assoc(asoc, skb); 5376 + if (err) 5377 + return err; 5301 5378 5302 5379 /* Compute the MLS component for the connection and store 5303 5380 * the information in asoc. This will be used by SCTP TCP type ··· 5326 5361 * socket to be generated. selinux_sctp_sk_clone() will then 5327 5362 * plug this into the new socket. 5328 5363 */ 5329 - err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid); 5364 + err = selinux_conn_sid(sksec->sid, asoc->peer_secid, &conn_sid); 5330 5365 if (err) 5331 5366 return err; 5332 5367 5333 5368 asoc->secid = conn_sid; 5334 - asoc->peer_secid = peer_sid; 5335 5369 5336 5370 /* Set any NetLabel labels including CIPSO/CALIPSO options. */ 5337 5371 return selinux_netlbl_sctp_assoc_request(asoc, skb); 5372 + } 5373 + 5374 + /* Called when SCTP receives a COOKIE ACK chunk as the final 5375 + * response to an association request (initited by us). 5376 + */ 5377 + static int selinux_sctp_assoc_established(struct sctp_association *asoc, 5378 + struct sk_buff *skb) 5379 + { 5380 + struct sk_security_struct *sksec = asoc->base.sk->sk_security; 5381 + 5382 + if (!selinux_policycap_extsockclass()) 5383 + return 0; 5384 + 5385 + /* Inherit secid from the parent socket - this will be picked up 5386 + * by selinux_sctp_sk_clone() if the association gets peeled off 5387 + * into a new socket. 5388 + */ 5389 + asoc->secid = sksec->sid; 5390 + 5391 + return selinux_sctp_process_new_assoc(asoc, skb); 5338 5392 } 5339 5393 5340 5394 /* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting ··· 7176 7192 LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request), 7177 7193 LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone), 7178 7194 LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect), 7195 + LSM_HOOK_INIT(sctp_assoc_established, selinux_sctp_assoc_established), 7179 7196 LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request), 7180 7197 LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone), 7181 7198 LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established),
+1 -1
security/selinux/ibpkey.c
··· 104 104 105 105 tail = list_entry( 106 106 rcu_dereference_protected( 107 - sel_ib_pkey_hash[idx].list.prev, 107 + list_tail_rcu(&sel_ib_pkey_hash[idx].list), 108 108 lockdep_is_held(&sel_ib_pkey_lock)), 109 109 struct sel_ib_pkey, list); 110 110 list_del_rcu(&tail->list);
+2 -2
security/selinux/ima.c
··· 29 29 buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1; 30 30 31 31 len = strlen(on); 32 - for (i = 0; i < __POLICYDB_CAPABILITY_MAX; i++) 32 + for (i = 0; i < __POLICYDB_CAP_MAX; i++) 33 33 buf_len += strlen(selinux_policycap_names[i]) + len; 34 34 35 35 buf = kzalloc(buf_len, GFP_KERNEL); ··· 54 54 rc = strlcat(buf, checkreqprot_get(state) ? on : off, buf_len); 55 55 WARN_ON(rc >= buf_len); 56 56 57 - for (i = 0; i < __POLICYDB_CAPABILITY_MAX; i++) { 57 + for (i = 0; i < __POLICYDB_CAP_MAX; i++) { 58 58 rc = strlcat(buf, selinux_policycap_names[i], buf_len); 59 59 WARN_ON(rc >= buf_len); 60 60
+11 -10
security/selinux/include/policycap.h
··· 4 4 5 5 /* Policy capabilities */ 6 6 enum { 7 - POLICYDB_CAPABILITY_NETPEER, 8 - POLICYDB_CAPABILITY_OPENPERM, 9 - POLICYDB_CAPABILITY_EXTSOCKCLASS, 10 - POLICYDB_CAPABILITY_ALWAYSNETWORK, 11 - POLICYDB_CAPABILITY_CGROUPSECLABEL, 12 - POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION, 13 - POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS, 14 - __POLICYDB_CAPABILITY_MAX 7 + POLICYDB_CAP_NETPEER, 8 + POLICYDB_CAP_OPENPERM, 9 + POLICYDB_CAP_EXTSOCKCLASS, 10 + POLICYDB_CAP_ALWAYSNETWORK, 11 + POLICYDB_CAP_CGROUPSECLABEL, 12 + POLICYDB_CAP_NNP_NOSUID_TRANSITION, 13 + POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS, 14 + POLICYDB_CAP_IOCTL_SKIP_CLOEXEC, 15 + __POLICYDB_CAP_MAX 15 16 }; 16 - #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 17 + #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) 17 18 18 - extern const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX]; 19 + extern const char *selinux_policycap_names[__POLICYDB_CAP_MAX]; 19 20 20 21 #endif /* _SELINUX_POLICYCAP_H_ */
+3 -2
security/selinux/include/policycap_names.h
··· 5 5 #include "policycap.h" 6 6 7 7 /* Policy capability names */ 8 - const char *selinux_policycap_names[__POLICYDB_CAPABILITY_MAX] = { 8 + const char *selinux_policycap_names[__POLICYDB_CAP_MAX] = { 9 9 "network_peer_controls", 10 10 "open_perms", 11 11 "extended_socket_class", 12 12 "always_check_network", 13 13 "cgroup_seclabel", 14 14 "nnp_nosuid_transition", 15 - "genfs_seclabel_symlinks" 15 + "genfs_seclabel_symlinks", 16 + "ioctl_skip_cloexec" 16 17 }; 17 18 18 19 #endif /* _SELINUX_POLICYCAP_NAMES_H_ */
+19 -12
security/selinux/include/security.h
··· 96 96 #endif 97 97 bool checkreqprot; 98 98 bool initialized; 99 - bool policycap[__POLICYDB_CAPABILITY_MAX]; 99 + bool policycap[__POLICYDB_CAP_MAX]; 100 100 101 101 struct page *status_page; 102 102 struct mutex status_lock; ··· 174 174 { 175 175 struct selinux_state *state = &selinux_state; 176 176 177 - return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NETPEER]); 177 + return READ_ONCE(state->policycap[POLICYDB_CAP_NETPEER]); 178 178 } 179 179 180 180 static inline bool selinux_policycap_openperm(void) 181 181 { 182 182 struct selinux_state *state = &selinux_state; 183 183 184 - return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_OPENPERM]); 184 + return READ_ONCE(state->policycap[POLICYDB_CAP_OPENPERM]); 185 185 } 186 186 187 187 static inline bool selinux_policycap_extsockclass(void) 188 188 { 189 189 struct selinux_state *state = &selinux_state; 190 190 191 - return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_EXTSOCKCLASS]); 191 + return READ_ONCE(state->policycap[POLICYDB_CAP_EXTSOCKCLASS]); 192 192 } 193 193 194 194 static inline bool selinux_policycap_alwaysnetwork(void) 195 195 { 196 196 struct selinux_state *state = &selinux_state; 197 197 198 - return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_ALWAYSNETWORK]); 198 + return READ_ONCE(state->policycap[POLICYDB_CAP_ALWAYSNETWORK]); 199 199 } 200 200 201 201 static inline bool selinux_policycap_cgroupseclabel(void) 202 202 { 203 203 struct selinux_state *state = &selinux_state; 204 204 205 - return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_CGROUPSECLABEL]); 205 + return READ_ONCE(state->policycap[POLICYDB_CAP_CGROUPSECLABEL]); 206 206 } 207 207 208 208 static inline bool selinux_policycap_nnp_nosuid_transition(void) 209 209 { 210 210 struct selinux_state *state = &selinux_state; 211 211 212 - return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION]); 212 + return READ_ONCE(state->policycap[POLICYDB_CAP_NNP_NOSUID_TRANSITION]); 213 213 } 214 214 215 215 static inline bool selinux_policycap_genfs_seclabel_symlinks(void) 216 216 { 217 217 struct selinux_state *state = &selinux_state; 218 218 219 - return READ_ONCE(state->policycap[POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS]); 219 + return READ_ONCE(state->policycap[POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS]); 220 + } 221 + 222 + static inline bool selinux_policycap_ioctl_skip_cloexec(void) 223 + { 224 + struct selinux_state *state = &selinux_state; 225 + 226 + return READ_ONCE(state->policycap[POLICYDB_CAP_IOCTL_SKIP_CLOEXEC]); 220 227 } 221 228 222 229 struct selinux_policy_convert_data; ··· 261 254 #define XPERMS_AUDITALLOW 2 262 255 #define XPERMS_DONTAUDIT 4 263 256 264 - #define security_xperm_set(perms, x) (perms[x >> 5] |= 1 << (x & 0x1f)) 265 - #define security_xperm_test(perms, x) (1 & (perms[x >> 5] >> (x & 0x1f))) 257 + #define security_xperm_set(perms, x) ((perms)[(x) >> 5] |= 1 << ((x) & 0x1f)) 258 + #define security_xperm_test(perms, x) (1 & ((perms)[(x) >> 5] >> ((x) & 0x1f))) 266 259 struct extended_perms_data { 267 260 u32 p[8]; 268 261 }; ··· 393 386 int security_fs_use(struct selinux_state *state, struct super_block *sb); 394 387 395 388 int security_genfs_sid(struct selinux_state *state, 396 - const char *fstype, char *name, u16 sclass, 389 + const char *fstype, const char *path, u16 sclass, 397 390 u32 *sid); 398 391 399 392 int selinux_policy_genfs_sid(struct selinux_policy *policy, 400 - const char *fstype, char *name, u16 sclass, 393 + const char *fstype, const char *path, u16 sclass, 401 394 u32 *sid); 402 395 403 396 #ifdef CONFIG_NETLABEL
+5 -4
security/selinux/netnode.c
··· 107 107 108 108 switch (family) { 109 109 case PF_INET: 110 - idx = sel_netnode_hashfn_ipv4(*(__be32 *)addr); 110 + idx = sel_netnode_hashfn_ipv4(*(const __be32 *)addr); 111 111 break; 112 112 case PF_INET6: 113 113 idx = sel_netnode_hashfn_ipv6(addr); ··· 121 121 if (node->nsec.family == family) 122 122 switch (family) { 123 123 case PF_INET: 124 - if (node->nsec.addr.ipv4 == *(__be32 *)addr) 124 + if (node->nsec.addr.ipv4 == *(const __be32 *)addr) 125 125 return node; 126 126 break; 127 127 case PF_INET6: ··· 164 164 if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { 165 165 struct sel_netnode *tail; 166 166 tail = list_entry( 167 - rcu_dereference_protected(sel_netnode_hash[idx].list.prev, 168 - lockdep_is_held(&sel_netnode_lock)), 167 + rcu_dereference_protected( 168 + list_tail_rcu(&sel_netnode_hash[idx].list), 169 + lockdep_is_held(&sel_netnode_lock)), 169 170 struct sel_netnode, list); 170 171 list_del_rcu(&tail->list); 171 172 kfree_rcu(tail, rcu);
+1 -1
security/selinux/netport.c
··· 113 113 struct sel_netport *tail; 114 114 tail = list_entry( 115 115 rcu_dereference_protected( 116 - sel_netport_hash[idx].list.prev, 116 + list_tail_rcu(&sel_netport_hash[idx].list), 117 117 lockdep_is_held(&sel_netport_lock)), 118 118 struct sel_netport, list); 119 119 list_del_rcu(&tail->list);
+3 -1
security/selinux/selinuxfs.c
··· 1983 1983 struct dentry *dentry = NULL; 1984 1984 struct inode *inode = NULL; 1985 1985 1986 - for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) { 1986 + for (iter = 0; iter <= POLICYDB_CAP_MAX; iter++) { 1987 1987 if (iter < ARRAY_SIZE(selinux_policycap_names)) 1988 1988 dentry = d_alloc_name(fsi->policycap_dir, 1989 1989 selinux_policycap_names[iter]); ··· 2127 2127 } 2128 2128 2129 2129 ret = sel_make_avc_files(dentry); 2130 + if (ret) 2131 + goto err; 2130 2132 2131 2133 dentry = sel_make_dir(sb->s_root, "ss", &fsi->last_ino); 2132 2134 if (IS_ERR(dentry)) {
+3 -3
security/selinux/ss/avtab.c
··· 67 67 68 68 static struct avtab_node* 69 69 avtab_insert_node(struct avtab *h, int hvalue, 70 - struct avtab_node *prev, struct avtab_node *cur, 70 + struct avtab_node *prev, 71 71 const struct avtab_key *key, const struct avtab_datum *datum) 72 72 { 73 73 struct avtab_node *newnode; ··· 137 137 break; 138 138 } 139 139 140 - newnode = avtab_insert_node(h, hvalue, prev, cur, key, datum); 140 + newnode = avtab_insert_node(h, hvalue, prev, key, datum); 141 141 if (!newnode) 142 142 return -ENOMEM; 143 143 ··· 177 177 key->target_class < cur->key.target_class) 178 178 break; 179 179 } 180 - return avtab_insert_node(h, hvalue, prev, cur, key, datum); 180 + return avtab_insert_node(h, hvalue, prev, key, datum); 181 181 } 182 182 183 183 struct avtab_datum *avtab_search(struct avtab *h, const struct avtab_key *key)
-2
security/selinux/ss/conditional.c
··· 567 567 if (node->key.specified & AVTAB_ENABLED) 568 568 services_compute_xperms_decision(xpermd, node); 569 569 } 570 - return; 571 - 572 570 } 573 571 /* Determine whether additional permissions are granted by the conditional 574 572 * av table, and if so, add them to the result
-1
security/selinux/ss/ebitmap.c
··· 359 359 360 360 e->highbit = 0; 361 361 e->node = NULL; 362 - return; 363 362 } 364 363 365 364 int ebitmap_read(struct ebitmap *e, void *fp)
+3 -3
security/selinux/ss/ebitmap.h
··· 118 118 } 119 119 120 120 #define ebitmap_for_each_positive_bit(e, n, bit) \ 121 - for (bit = ebitmap_start_positive(e, &n); \ 122 - bit < ebitmap_length(e); \ 123 - bit = ebitmap_next_positive(e, &n, bit)) \ 121 + for ((bit) = ebitmap_start_positive(e, &(n)); \ 122 + (bit) < ebitmap_length(e); \ 123 + (bit) = ebitmap_next_positive(e, &(n), bit)) \ 124 124 125 125 int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2); 126 126 int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src);
-1
security/selinux/ss/mls.c
··· 156 156 } 157 157 158 158 *scontext = scontextp; 159 - return; 160 159 } 161 160 162 161 int mls_level_isvalid(struct policydb *p, struct mls_level *l)
+1 -3
security/selinux/ss/policydb.c
··· 41 41 #include "mls.h" 42 42 #include "services.h" 43 43 44 - #define _DEBUG_HASHES 45 - 46 44 #ifdef DEBUG_HASHES 47 45 static const char *symtab_name[SYM_NUM] = { 48 46 "common prefixes", ··· 702 704 } 703 705 704 706 #else 705 - static inline void hash_eval(struct hashtab *h, char *hash_name) 707 + static inline void hash_eval(struct hashtab *h, const char *hash_name) 706 708 { 707 709 } 708 710 #endif
+4 -6
security/selinux/ss/services.c
··· 529 529 /* release scontext/tcontext */ 530 530 kfree(tcontext_name); 531 531 kfree(scontext_name); 532 - 533 - return; 534 532 } 535 533 536 534 /* ··· 1450 1452 /* Parse the security context. */ 1451 1453 1452 1454 rc = -EINVAL; 1453 - scontextp = (char *) scontext; 1455 + scontextp = scontext; 1454 1456 1455 1457 /* Extract the user. */ 1456 1458 p = scontextp; ··· 2873 2875 */ 2874 2876 static inline int __security_genfs_sid(struct selinux_policy *policy, 2875 2877 const char *fstype, 2876 - char *path, 2878 + const char *path, 2877 2879 u16 orig_sclass, 2878 2880 u32 *sid) 2879 2881 { ··· 2926 2928 */ 2927 2929 int security_genfs_sid(struct selinux_state *state, 2928 2930 const char *fstype, 2929 - char *path, 2931 + const char *path, 2930 2932 u16 orig_sclass, 2931 2933 u32 *sid) 2932 2934 { ··· 2950 2952 2951 2953 int selinux_policy_genfs_sid(struct selinux_policy *policy, 2952 2954 const char *fstype, 2953 - char *path, 2955 + const char *path, 2954 2956 u16 orig_sclass, 2955 2957 u32 *sid) 2956 2958 {
+2 -2
security/selinux/ss/sidtab.c
··· 27 27 char str[]; 28 28 }; 29 29 30 - #define index_to_sid(index) (index + SECINITSID_NUM + 1) 31 - #define sid_to_index(sid) (sid - (SECINITSID_NUM + 1)) 30 + #define index_to_sid(index) ((index) + SECINITSID_NUM + 1) 31 + #define sid_to_index(sid) ((sid) - (SECINITSID_NUM + 1)) 32 32 33 33 int sidtab_init(struct sidtab *s) 34 34 {
+1 -1
security/selinux/xfrm.c
··· 347 347 int rc; 348 348 struct xfrm_sec_ctx *ctx; 349 349 char *ctx_str = NULL; 350 - int str_len; 350 + u32 str_len; 351 351 352 352 if (!polsec) 353 353 return 0;