diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 01:44:51 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-07-15 01:44:51 -0400 |
commit | 43d2548bb2ef7e6d753f91468a746784041e522d (patch) | |
tree | 77d13fcd48fd998393abb825ec36e2b732684a73 /security/selinux/hooks.c | |
parent | 585583d95c5660973bc0cf64add517b040acd8a4 (diff) | |
parent | 85082fd7cbe3173198aac0eb5e85ab1edcc6352c (diff) |
Merge commit '85082fd7cbe3173198aac0eb5e85ab1edcc6352c' into test-build
Manual fixup of:
arch/powerpc/Kconfig
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 244 |
1 files changed, 148 insertions, 96 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1c864c0efe2b..91200feb3f9c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -9,7 +9,8 @@ | |||
9 | * James Morris <jmorris@redhat.com> | 9 | * James Morris <jmorris@redhat.com> |
10 | * | 10 | * |
11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. | 11 | * Copyright (C) 2001,2002 Networks Associates Technology, Inc. |
12 | * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> | 12 | * Copyright (C) 2003-2008 Red Hat, Inc., James Morris <jmorris@redhat.com> |
13 | * Eric Paris <eparis@redhat.com> | ||
13 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. | 14 | * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. |
14 | * <dgoeddel@trustedcs.com> | 15 | * <dgoeddel@trustedcs.com> |
15 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. | 16 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. |
@@ -42,9 +43,7 @@ | |||
42 | #include <linux/fdtable.h> | 43 | #include <linux/fdtable.h> |
43 | #include <linux/namei.h> | 44 | #include <linux/namei.h> |
44 | #include <linux/mount.h> | 45 | #include <linux/mount.h> |
45 | #include <linux/ext2_fs.h> | ||
46 | #include <linux/proc_fs.h> | 46 | #include <linux/proc_fs.h> |
47 | #include <linux/kd.h> | ||
48 | #include <linux/netfilter_ipv4.h> | 47 | #include <linux/netfilter_ipv4.h> |
49 | #include <linux/netfilter_ipv6.h> | 48 | #include <linux/netfilter_ipv6.h> |
50 | #include <linux/tty.h> | 49 | #include <linux/tty.h> |
@@ -53,7 +52,7 @@ | |||
53 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ | 52 | #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ |
54 | #include <net/net_namespace.h> | 53 | #include <net/net_namespace.h> |
55 | #include <net/netlabel.h> | 54 | #include <net/netlabel.h> |
56 | #include <asm/uaccess.h> | 55 | #include <linux/uaccess.h> |
57 | #include <asm/ioctls.h> | 56 | #include <asm/ioctls.h> |
58 | #include <asm/atomic.h> | 57 | #include <asm/atomic.h> |
59 | #include <linux/bitops.h> | 58 | #include <linux/bitops.h> |
@@ -104,7 +103,9 @@ int selinux_enforcing; | |||
104 | 103 | ||
105 | static int __init enforcing_setup(char *str) | 104 | static int __init enforcing_setup(char *str) |
106 | { | 105 | { |
107 | selinux_enforcing = simple_strtol(str, NULL, 0); | 106 | unsigned long enforcing; |
107 | if (!strict_strtoul(str, 0, &enforcing)) | ||
108 | selinux_enforcing = enforcing ? 1 : 0; | ||
108 | return 1; | 109 | return 1; |
109 | } | 110 | } |
110 | __setup("enforcing=", enforcing_setup); | 111 | __setup("enforcing=", enforcing_setup); |
@@ -115,7 +116,9 @@ int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE; | |||
115 | 116 | ||
116 | static int __init selinux_enabled_setup(char *str) | 117 | static int __init selinux_enabled_setup(char *str) |
117 | { | 118 | { |
118 | selinux_enabled = simple_strtol(str, NULL, 0); | 119 | unsigned long enabled; |
120 | if (!strict_strtoul(str, 0, &enabled)) | ||
121 | selinux_enabled = enabled ? 1 : 0; | ||
119 | return 1; | 122 | return 1; |
120 | } | 123 | } |
121 | __setup("selinux=", selinux_enabled_setup); | 124 | __setup("selinux=", selinux_enabled_setup); |
@@ -123,13 +126,11 @@ __setup("selinux=", selinux_enabled_setup); | |||
123 | int selinux_enabled = 1; | 126 | int selinux_enabled = 1; |
124 | #endif | 127 | #endif |
125 | 128 | ||
126 | /* Original (dummy) security module. */ | ||
127 | static struct security_operations *original_ops; | ||
128 | 129 | ||
129 | /* Minimal support for a secondary security module, | 130 | /* |
130 | just to allow the use of the dummy or capability modules. | 131 | * Minimal support for a secondary security module, |
131 | The owlsm module can alternatively be used as a secondary | 132 | * just to allow the use of the capability module. |
132 | module as long as CONFIG_OWLSM_FD is not enabled. */ | 133 | */ |
133 | static struct security_operations *secondary_ops; | 134 | static struct security_operations *secondary_ops; |
134 | 135 | ||
135 | /* Lists of inode and superblock security structures initialized | 136 | /* Lists of inode and superblock security structures initialized |
@@ -554,13 +555,15 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
554 | struct task_security_struct *tsec = current->security; | 555 | struct task_security_struct *tsec = current->security; |
555 | struct superblock_security_struct *sbsec = sb->s_security; | 556 | struct superblock_security_struct *sbsec = sb->s_security; |
556 | const char *name = sb->s_type->name; | 557 | const char *name = sb->s_type->name; |
557 | struct inode *inode = sbsec->sb->s_root->d_inode; | 558 | struct dentry *root = sb->s_root; |
558 | struct inode_security_struct *root_isec = inode->i_security; | 559 | struct inode *root_inode = root->d_inode; |
560 | struct inode_security_struct *root_isec = root_inode->i_security; | ||
559 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 561 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
560 | u32 defcontext_sid = 0; | 562 | u32 defcontext_sid = 0; |
561 | char **mount_options = opts->mnt_opts; | 563 | char **mount_options = opts->mnt_opts; |
562 | int *flags = opts->mnt_opts_flags; | 564 | int *flags = opts->mnt_opts_flags; |
563 | int num_opts = opts->num_mnt_opts; | 565 | int num_opts = opts->num_mnt_opts; |
566 | bool can_xattr = false; | ||
564 | 567 | ||
565 | mutex_lock(&sbsec->lock); | 568 | mutex_lock(&sbsec->lock); |
566 | 569 | ||
@@ -594,7 +597,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
594 | */ | 597 | */ |
595 | if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | 598 | if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) |
596 | && (num_opts == 0)) | 599 | && (num_opts == 0)) |
597 | goto out; | 600 | goto out; |
598 | 601 | ||
599 | /* | 602 | /* |
600 | * parse the mount options, check if they are valid sids. | 603 | * parse the mount options, check if they are valid sids. |
@@ -664,14 +667,24 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
664 | goto out; | 667 | goto out; |
665 | } | 668 | } |
666 | 669 | ||
667 | if (strcmp(sb->s_type->name, "proc") == 0) | 670 | if (strcmp(name, "proc") == 0) |
668 | sbsec->proc = 1; | 671 | sbsec->proc = 1; |
669 | 672 | ||
673 | /* | ||
674 | * test if the fs supports xattrs, fs_use might make use of this if the | ||
675 | * fs has no definition in policy. | ||
676 | */ | ||
677 | if (root_inode->i_op->getxattr) { | ||
678 | rc = root_inode->i_op->getxattr(root, XATTR_NAME_SELINUX, NULL, 0); | ||
679 | if (rc >= 0 || rc == -ENODATA) | ||
680 | can_xattr = true; | ||
681 | } | ||
682 | |||
670 | /* Determine the labeling behavior to use for this filesystem type. */ | 683 | /* Determine the labeling behavior to use for this filesystem type. */ |
671 | rc = security_fs_use(sb->s_type->name, &sbsec->behavior, &sbsec->sid); | 684 | rc = security_fs_use(name, &sbsec->behavior, &sbsec->sid, can_xattr); |
672 | if (rc) { | 685 | if (rc) { |
673 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", | 686 | printk(KERN_WARNING "%s: security_fs_use(%s) returned %d\n", |
674 | __func__, sb->s_type->name, rc); | 687 | __func__, name, rc); |
675 | goto out; | 688 | goto out; |
676 | } | 689 | } |
677 | 690 | ||
@@ -956,6 +969,57 @@ out_err: | |||
956 | return rc; | 969 | return rc; |
957 | } | 970 | } |
958 | 971 | ||
972 | void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts) | ||
973 | { | ||
974 | int i; | ||
975 | char *prefix; | ||
976 | |||
977 | for (i = 0; i < opts->num_mnt_opts; i++) { | ||
978 | char *has_comma = strchr(opts->mnt_opts[i], ','); | ||
979 | |||
980 | switch (opts->mnt_opts_flags[i]) { | ||
981 | case CONTEXT_MNT: | ||
982 | prefix = CONTEXT_STR; | ||
983 | break; | ||
984 | case FSCONTEXT_MNT: | ||
985 | prefix = FSCONTEXT_STR; | ||
986 | break; | ||
987 | case ROOTCONTEXT_MNT: | ||
988 | prefix = ROOTCONTEXT_STR; | ||
989 | break; | ||
990 | case DEFCONTEXT_MNT: | ||
991 | prefix = DEFCONTEXT_STR; | ||
992 | break; | ||
993 | default: | ||
994 | BUG(); | ||
995 | }; | ||
996 | /* we need a comma before each option */ | ||
997 | seq_putc(m, ','); | ||
998 | seq_puts(m, prefix); | ||
999 | if (has_comma) | ||
1000 | seq_putc(m, '\"'); | ||
1001 | seq_puts(m, opts->mnt_opts[i]); | ||
1002 | if (has_comma) | ||
1003 | seq_putc(m, '\"'); | ||
1004 | } | ||
1005 | } | ||
1006 | |||
1007 | static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb) | ||
1008 | { | ||
1009 | struct security_mnt_opts opts; | ||
1010 | int rc; | ||
1011 | |||
1012 | rc = selinux_get_mnt_opts(sb, &opts); | ||
1013 | if (rc) | ||
1014 | return rc; | ||
1015 | |||
1016 | selinux_write_opts(m, &opts); | ||
1017 | |||
1018 | security_free_mnt_opts(&opts); | ||
1019 | |||
1020 | return rc; | ||
1021 | } | ||
1022 | |||
959 | static inline u16 inode_mode_to_security_class(umode_t mode) | 1023 | static inline u16 inode_mode_to_security_class(umode_t mode) |
960 | { | 1024 | { |
961 | switch (mode & S_IFMT) { | 1025 | switch (mode & S_IFMT) { |
@@ -1682,14 +1746,23 @@ static inline u32 file_to_av(struct file *file) | |||
1682 | 1746 | ||
1683 | /* Hook functions begin here. */ | 1747 | /* Hook functions begin here. */ |
1684 | 1748 | ||
1685 | static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) | 1749 | static int selinux_ptrace(struct task_struct *parent, |
1750 | struct task_struct *child, | ||
1751 | unsigned int mode) | ||
1686 | { | 1752 | { |
1687 | int rc; | 1753 | int rc; |
1688 | 1754 | ||
1689 | rc = secondary_ops->ptrace(parent, child); | 1755 | rc = secondary_ops->ptrace(parent, child, mode); |
1690 | if (rc) | 1756 | if (rc) |
1691 | return rc; | 1757 | return rc; |
1692 | 1758 | ||
1759 | if (mode == PTRACE_MODE_READ) { | ||
1760 | struct task_security_struct *tsec = parent->security; | ||
1761 | struct task_security_struct *csec = child->security; | ||
1762 | return avc_has_perm(tsec->sid, csec->sid, | ||
1763 | SECCLASS_FILE, FILE__READ, NULL); | ||
1764 | } | ||
1765 | |||
1693 | return task_has_perm(parent, child, PROCESS__PTRACE); | 1766 | return task_has_perm(parent, child, PROCESS__PTRACE); |
1694 | } | 1767 | } |
1695 | 1768 | ||
@@ -2495,7 +2568,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
2495 | } | 2568 | } |
2496 | 2569 | ||
2497 | if (value && len) { | 2570 | if (value && len) { |
2498 | rc = security_sid_to_context(newsid, &context, &clen); | 2571 | rc = security_sid_to_context_force(newsid, &context, &clen); |
2499 | if (rc) { | 2572 | if (rc) { |
2500 | kfree(namep); | 2573 | kfree(namep); |
2501 | return rc; | 2574 | return rc; |
@@ -2669,6 +2742,11 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2669 | return rc; | 2742 | return rc; |
2670 | 2743 | ||
2671 | rc = security_context_to_sid(value, size, &newsid); | 2744 | rc = security_context_to_sid(value, size, &newsid); |
2745 | if (rc == -EINVAL) { | ||
2746 | if (!capable(CAP_MAC_ADMIN)) | ||
2747 | return rc; | ||
2748 | rc = security_context_to_sid_force(value, size, &newsid); | ||
2749 | } | ||
2672 | if (rc) | 2750 | if (rc) |
2673 | return rc; | 2751 | return rc; |
2674 | 2752 | ||
@@ -2690,7 +2768,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2690 | } | 2768 | } |
2691 | 2769 | ||
2692 | static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | 2770 | static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, |
2693 | const void *value, size_t size, | 2771 | const void *value, size_t size, |
2694 | int flags) | 2772 | int flags) |
2695 | { | 2773 | { |
2696 | struct inode *inode = dentry->d_inode; | 2774 | struct inode *inode = dentry->d_inode; |
@@ -2703,10 +2781,11 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
2703 | return; | 2781 | return; |
2704 | } | 2782 | } |
2705 | 2783 | ||
2706 | rc = security_context_to_sid(value, size, &newsid); | 2784 | rc = security_context_to_sid_force(value, size, &newsid); |
2707 | if (rc) { | 2785 | if (rc) { |
2708 | printk(KERN_WARNING "%s: unable to obtain SID for context " | 2786 | printk(KERN_ERR "SELinux: unable to map context to SID" |
2709 | "%s, rc=%d\n", __func__, (char *)value, -rc); | 2787 | "for (%s, %lu), rc=%d\n", |
2788 | inode->i_sb->s_id, inode->i_ino, -rc); | ||
2710 | return; | 2789 | return; |
2711 | } | 2790 | } |
2712 | 2791 | ||
@@ -2735,9 +2814,7 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name) | |||
2735 | } | 2814 | } |
2736 | 2815 | ||
2737 | /* | 2816 | /* |
2738 | * Copy the in-core inode security context value to the user. If the | 2817 | * Copy the inode security context value to the user. |
2739 | * getxattr() prior to this succeeded, check to see if we need to | ||
2740 | * canonicalize the value to be finally returned to the user. | ||
2741 | * | 2818 | * |
2742 | * Permission check is handled by selinux_inode_getxattr hook. | 2819 | * Permission check is handled by selinux_inode_getxattr hook. |
2743 | */ | 2820 | */ |
@@ -2746,12 +2823,33 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name | |||
2746 | u32 size; | 2823 | u32 size; |
2747 | int error; | 2824 | int error; |
2748 | char *context = NULL; | 2825 | char *context = NULL; |
2826 | struct task_security_struct *tsec = current->security; | ||
2749 | struct inode_security_struct *isec = inode->i_security; | 2827 | struct inode_security_struct *isec = inode->i_security; |
2750 | 2828 | ||
2751 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 2829 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) |
2752 | return -EOPNOTSUPP; | 2830 | return -EOPNOTSUPP; |
2753 | 2831 | ||
2754 | error = security_sid_to_context(isec->sid, &context, &size); | 2832 | /* |
2833 | * If the caller has CAP_MAC_ADMIN, then get the raw context | ||
2834 | * value even if it is not defined by current policy; otherwise, | ||
2835 | * use the in-core value under current policy. | ||
2836 | * Use the non-auditing forms of the permission checks since | ||
2837 | * getxattr may be called by unprivileged processes commonly | ||
2838 | * and lack of permission just means that we fall back to the | ||
2839 | * in-core context value, not a denial. | ||
2840 | */ | ||
2841 | error = secondary_ops->capable(current, CAP_MAC_ADMIN); | ||
2842 | if (!error) | ||
2843 | error = avc_has_perm_noaudit(tsec->sid, tsec->sid, | ||
2844 | SECCLASS_CAPABILITY2, | ||
2845 | CAPABILITY2__MAC_ADMIN, | ||
2846 | 0, | ||
2847 | NULL); | ||
2848 | if (!error) | ||
2849 | error = security_sid_to_context_force(isec->sid, &context, | ||
2850 | &size); | ||
2851 | else | ||
2852 | error = security_sid_to_context(isec->sid, &context, &size); | ||
2755 | if (error) | 2853 | if (error) |
2756 | return error; | 2854 | return error; |
2757 | error = size; | 2855 | error = size; |
@@ -2865,46 +2963,16 @@ static void selinux_file_free_security(struct file *file) | |||
2865 | static int selinux_file_ioctl(struct file *file, unsigned int cmd, | 2963 | static int selinux_file_ioctl(struct file *file, unsigned int cmd, |
2866 | unsigned long arg) | 2964 | unsigned long arg) |
2867 | { | 2965 | { |
2868 | int error = 0; | 2966 | u32 av = 0; |
2869 | |||
2870 | switch (cmd) { | ||
2871 | case FIONREAD: | ||
2872 | /* fall through */ | ||
2873 | case FIBMAP: | ||
2874 | /* fall through */ | ||
2875 | case FIGETBSZ: | ||
2876 | /* fall through */ | ||
2877 | case EXT2_IOC_GETFLAGS: | ||
2878 | /* fall through */ | ||
2879 | case EXT2_IOC_GETVERSION: | ||
2880 | error = file_has_perm(current, file, FILE__GETATTR); | ||
2881 | break; | ||
2882 | |||
2883 | case EXT2_IOC_SETFLAGS: | ||
2884 | /* fall through */ | ||
2885 | case EXT2_IOC_SETVERSION: | ||
2886 | error = file_has_perm(current, file, FILE__SETATTR); | ||
2887 | break; | ||
2888 | |||
2889 | /* sys_ioctl() checks */ | ||
2890 | case FIONBIO: | ||
2891 | /* fall through */ | ||
2892 | case FIOASYNC: | ||
2893 | error = file_has_perm(current, file, 0); | ||
2894 | break; | ||
2895 | 2967 | ||
2896 | case KDSKBENT: | 2968 | if (_IOC_DIR(cmd) & _IOC_WRITE) |
2897 | case KDSKBSENT: | 2969 | av |= FILE__WRITE; |
2898 | error = task_has_capability(current, CAP_SYS_TTY_CONFIG); | 2970 | if (_IOC_DIR(cmd) & _IOC_READ) |
2899 | break; | 2971 | av |= FILE__READ; |
2972 | if (!av) | ||
2973 | av = FILE__IOCTL; | ||
2900 | 2974 | ||
2901 | /* default case assumes that the command will go | 2975 | return file_has_perm(current, file, av); |
2902 | * to the file's ioctl() function. | ||
2903 | */ | ||
2904 | default: | ||
2905 | error = file_has_perm(current, file, FILE__IOCTL); | ||
2906 | } | ||
2907 | return error; | ||
2908 | } | 2976 | } |
2909 | 2977 | ||
2910 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) | 2978 | static int file_map_prot_check(struct file *file, unsigned long prot, int shared) |
@@ -3663,7 +3731,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3663 | struct sockaddr_in6 *addr6 = NULL; | 3731 | struct sockaddr_in6 *addr6 = NULL; |
3664 | unsigned short snum; | 3732 | unsigned short snum; |
3665 | struct sock *sk = sock->sk; | 3733 | struct sock *sk = sock->sk; |
3666 | u32 sid, node_perm, addrlen; | 3734 | u32 sid, node_perm; |
3667 | 3735 | ||
3668 | tsec = current->security; | 3736 | tsec = current->security; |
3669 | isec = SOCK_INODE(sock)->i_security; | 3737 | isec = SOCK_INODE(sock)->i_security; |
@@ -3671,12 +3739,10 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3671 | if (family == PF_INET) { | 3739 | if (family == PF_INET) { |
3672 | addr4 = (struct sockaddr_in *)address; | 3740 | addr4 = (struct sockaddr_in *)address; |
3673 | snum = ntohs(addr4->sin_port); | 3741 | snum = ntohs(addr4->sin_port); |
3674 | addrlen = sizeof(addr4->sin_addr.s_addr); | ||
3675 | addrp = (char *)&addr4->sin_addr.s_addr; | 3742 | addrp = (char *)&addr4->sin_addr.s_addr; |
3676 | } else { | 3743 | } else { |
3677 | addr6 = (struct sockaddr_in6 *)address; | 3744 | addr6 = (struct sockaddr_in6 *)address; |
3678 | snum = ntohs(addr6->sin6_port); | 3745 | snum = ntohs(addr6->sin6_port); |
3679 | addrlen = sizeof(addr6->sin6_addr.s6_addr); | ||
3680 | addrp = (char *)&addr6->sin6_addr.s6_addr; | 3746 | addrp = (char *)&addr6->sin6_addr.s6_addr; |
3681 | } | 3747 | } |
3682 | 3748 | ||
@@ -5047,24 +5113,6 @@ static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | |||
5047 | *secid = isec->sid; | 5113 | *secid = isec->sid; |
5048 | } | 5114 | } |
5049 | 5115 | ||
5050 | /* module stacking operations */ | ||
5051 | static int selinux_register_security(const char *name, struct security_operations *ops) | ||
5052 | { | ||
5053 | if (secondary_ops != original_ops) { | ||
5054 | printk(KERN_ERR "%s: There is already a secondary security " | ||
5055 | "module registered.\n", __func__); | ||
5056 | return -EINVAL; | ||
5057 | } | ||
5058 | |||
5059 | secondary_ops = ops; | ||
5060 | |||
5061 | printk(KERN_INFO "%s: Registering secondary module %s\n", | ||
5062 | __func__, | ||
5063 | name); | ||
5064 | |||
5065 | return 0; | ||
5066 | } | ||
5067 | |||
5068 | static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) | 5116 | static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) |
5069 | { | 5117 | { |
5070 | if (inode) | 5118 | if (inode) |
@@ -5153,6 +5201,12 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5153 | size--; | 5201 | size--; |
5154 | } | 5202 | } |
5155 | error = security_context_to_sid(value, size, &sid); | 5203 | error = security_context_to_sid(value, size, &sid); |
5204 | if (error == -EINVAL && !strcmp(name, "fscreate")) { | ||
5205 | if (!capable(CAP_MAC_ADMIN)) | ||
5206 | return error; | ||
5207 | error = security_context_to_sid_force(value, size, | ||
5208 | &sid); | ||
5209 | } | ||
5156 | if (error) | 5210 | if (error) |
5157 | return error; | 5211 | return error; |
5158 | } | 5212 | } |
@@ -5186,12 +5240,12 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5186 | struct task_struct *g, *t; | 5240 | struct task_struct *g, *t; |
5187 | struct mm_struct *mm = p->mm; | 5241 | struct mm_struct *mm = p->mm; |
5188 | read_lock(&tasklist_lock); | 5242 | read_lock(&tasklist_lock); |
5189 | do_each_thread(g, t) | 5243 | do_each_thread(g, t) { |
5190 | if (t->mm == mm && t != p) { | 5244 | if (t->mm == mm && t != p) { |
5191 | read_unlock(&tasklist_lock); | 5245 | read_unlock(&tasklist_lock); |
5192 | return -EPERM; | 5246 | return -EPERM; |
5193 | } | 5247 | } |
5194 | while_each_thread(g, t); | 5248 | } while_each_thread(g, t); |
5195 | read_unlock(&tasklist_lock); | 5249 | read_unlock(&tasklist_lock); |
5196 | } | 5250 | } |
5197 | 5251 | ||
@@ -5343,10 +5397,10 @@ static struct security_operations selinux_ops = { | |||
5343 | .sb_free_security = selinux_sb_free_security, | 5397 | .sb_free_security = selinux_sb_free_security, |
5344 | .sb_copy_data = selinux_sb_copy_data, | 5398 | .sb_copy_data = selinux_sb_copy_data, |
5345 | .sb_kern_mount = selinux_sb_kern_mount, | 5399 | .sb_kern_mount = selinux_sb_kern_mount, |
5400 | .sb_show_options = selinux_sb_show_options, | ||
5346 | .sb_statfs = selinux_sb_statfs, | 5401 | .sb_statfs = selinux_sb_statfs, |
5347 | .sb_mount = selinux_mount, | 5402 | .sb_mount = selinux_mount, |
5348 | .sb_umount = selinux_umount, | 5403 | .sb_umount = selinux_umount, |
5349 | .sb_get_mnt_opts = selinux_get_mnt_opts, | ||
5350 | .sb_set_mnt_opts = selinux_set_mnt_opts, | 5404 | .sb_set_mnt_opts = selinux_set_mnt_opts, |
5351 | .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, | 5405 | .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, |
5352 | .sb_parse_opts_str = selinux_parse_opts_str, | 5406 | .sb_parse_opts_str = selinux_parse_opts_str, |
@@ -5378,7 +5432,7 @@ static struct security_operations selinux_ops = { | |||
5378 | .inode_listsecurity = selinux_inode_listsecurity, | 5432 | .inode_listsecurity = selinux_inode_listsecurity, |
5379 | .inode_need_killpriv = selinux_inode_need_killpriv, | 5433 | .inode_need_killpriv = selinux_inode_need_killpriv, |
5380 | .inode_killpriv = selinux_inode_killpriv, | 5434 | .inode_killpriv = selinux_inode_killpriv, |
5381 | .inode_getsecid = selinux_inode_getsecid, | 5435 | .inode_getsecid = selinux_inode_getsecid, |
5382 | 5436 | ||
5383 | .file_permission = selinux_file_permission, | 5437 | .file_permission = selinux_file_permission, |
5384 | .file_alloc_security = selinux_file_alloc_security, | 5438 | .file_alloc_security = selinux_file_alloc_security, |
@@ -5419,7 +5473,7 @@ static struct security_operations selinux_ops = { | |||
5419 | .task_to_inode = selinux_task_to_inode, | 5473 | .task_to_inode = selinux_task_to_inode, |
5420 | 5474 | ||
5421 | .ipc_permission = selinux_ipc_permission, | 5475 | .ipc_permission = selinux_ipc_permission, |
5422 | .ipc_getsecid = selinux_ipc_getsecid, | 5476 | .ipc_getsecid = selinux_ipc_getsecid, |
5423 | 5477 | ||
5424 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, | 5478 | .msg_msg_alloc_security = selinux_msg_msg_alloc_security, |
5425 | .msg_msg_free_security = selinux_msg_msg_free_security, | 5479 | .msg_msg_free_security = selinux_msg_msg_free_security, |
@@ -5443,8 +5497,6 @@ static struct security_operations selinux_ops = { | |||
5443 | .sem_semctl = selinux_sem_semctl, | 5497 | .sem_semctl = selinux_sem_semctl, |
5444 | .sem_semop = selinux_sem_semop, | 5498 | .sem_semop = selinux_sem_semop, |
5445 | 5499 | ||
5446 | .register_security = selinux_register_security, | ||
5447 | |||
5448 | .d_instantiate = selinux_d_instantiate, | 5500 | .d_instantiate = selinux_d_instantiate, |
5449 | 5501 | ||
5450 | .getprocattr = selinux_getprocattr, | 5502 | .getprocattr = selinux_getprocattr, |
@@ -5538,7 +5590,7 @@ static __init int selinux_init(void) | |||
5538 | 0, SLAB_PANIC, NULL); | 5590 | 0, SLAB_PANIC, NULL); |
5539 | avc_init(); | 5591 | avc_init(); |
5540 | 5592 | ||
5541 | original_ops = secondary_ops = security_ops; | 5593 | secondary_ops = security_ops; |
5542 | if (!secondary_ops) | 5594 | if (!secondary_ops) |
5543 | panic("SELinux: No initial security operations\n"); | 5595 | panic("SELinux: No initial security operations\n"); |
5544 | if (register_security(&selinux_ops)) | 5596 | if (register_security(&selinux_ops)) |