aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-25 05:37:07 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-25 05:37:07 -0400
commit0e2f65ee30eee2db054f7fd73f462c5da33ec963 (patch)
tree26c61eb7745da0c0d9135e9d12088f570cb8530d /security/selinux/hooks.c
parentda7878d75b8520c9ae00d27dfbbce546a7bfdfbb (diff)
parentfb2e405fc1fc8b20d9c78eaa1c7fd5a297efde43 (diff)
Merge branch 'linus' into x86/pebs
Conflicts: arch/x86/Kconfig.cpu arch/x86/kernel/cpu/intel.c arch/x86/kernel/setup_64.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c222
1 files changed, 131 insertions, 91 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1c864c0efe2b..63f131fc42e4 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
105static int __init enforcing_setup(char *str) 104static 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
116static int __init selinux_enabled_setup(char *str) 117static 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);
123int selinux_enabled = 1; 126int selinux_enabled = 1;
124#endif 127#endif
125 128
126/* Original (dummy) security module. */
127static 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 */
133static struct security_operations *secondary_ops; 134static 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
@@ -594,7 +595,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
594 */ 595 */
595 if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) 596 if (sbsec->initialized && (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
596 && (num_opts == 0)) 597 && (num_opts == 0))
597 goto out; 598 goto out;
598 599
599 /* 600 /*
600 * parse the mount options, check if they are valid sids. 601 * parse the mount options, check if they are valid sids.
@@ -956,6 +957,57 @@ out_err:
956 return rc; 957 return rc;
957} 958}
958 959
960void selinux_write_opts(struct seq_file *m, struct security_mnt_opts *opts)
961{
962 int i;
963 char *prefix;
964
965 for (i = 0; i < opts->num_mnt_opts; i++) {
966 char *has_comma = strchr(opts->mnt_opts[i], ',');
967
968 switch (opts->mnt_opts_flags[i]) {
969 case CONTEXT_MNT:
970 prefix = CONTEXT_STR;
971 break;
972 case FSCONTEXT_MNT:
973 prefix = FSCONTEXT_STR;
974 break;
975 case ROOTCONTEXT_MNT:
976 prefix = ROOTCONTEXT_STR;
977 break;
978 case DEFCONTEXT_MNT:
979 prefix = DEFCONTEXT_STR;
980 break;
981 default:
982 BUG();
983 };
984 /* we need a comma before each option */
985 seq_putc(m, ',');
986 seq_puts(m, prefix);
987 if (has_comma)
988 seq_putc(m, '\"');
989 seq_puts(m, opts->mnt_opts[i]);
990 if (has_comma)
991 seq_putc(m, '\"');
992 }
993}
994
995static int selinux_sb_show_options(struct seq_file *m, struct super_block *sb)
996{
997 struct security_mnt_opts opts;
998 int rc;
999
1000 rc = selinux_get_mnt_opts(sb, &opts);
1001 if (rc)
1002 return rc;
1003
1004 selinux_write_opts(m, &opts);
1005
1006 security_free_mnt_opts(&opts);
1007
1008 return rc;
1009}
1010
959static inline u16 inode_mode_to_security_class(umode_t mode) 1011static inline u16 inode_mode_to_security_class(umode_t mode)
960{ 1012{
961 switch (mode & S_IFMT) { 1013 switch (mode & S_IFMT) {
@@ -1682,14 +1734,23 @@ static inline u32 file_to_av(struct file *file)
1682 1734
1683/* Hook functions begin here. */ 1735/* Hook functions begin here. */
1684 1736
1685static int selinux_ptrace(struct task_struct *parent, struct task_struct *child) 1737static int selinux_ptrace(struct task_struct *parent,
1738 struct task_struct *child,
1739 unsigned int mode)
1686{ 1740{
1687 int rc; 1741 int rc;
1688 1742
1689 rc = secondary_ops->ptrace(parent, child); 1743 rc = secondary_ops->ptrace(parent, child, mode);
1690 if (rc) 1744 if (rc)
1691 return rc; 1745 return rc;
1692 1746
1747 if (mode == PTRACE_MODE_READ) {
1748 struct task_security_struct *tsec = parent->security;
1749 struct task_security_struct *csec = child->security;
1750 return avc_has_perm(tsec->sid, csec->sid,
1751 SECCLASS_FILE, FILE__READ, NULL);
1752 }
1753
1693 return task_has_perm(parent, child, PROCESS__PTRACE); 1754 return task_has_perm(parent, child, PROCESS__PTRACE);
1694} 1755}
1695 1756
@@ -2495,7 +2556,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
2495 } 2556 }
2496 2557
2497 if (value && len) { 2558 if (value && len) {
2498 rc = security_sid_to_context(newsid, &context, &clen); 2559 rc = security_sid_to_context_force(newsid, &context, &clen);
2499 if (rc) { 2560 if (rc) {
2500 kfree(namep); 2561 kfree(namep);
2501 return rc; 2562 return rc;
@@ -2669,6 +2730,11 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2669 return rc; 2730 return rc;
2670 2731
2671 rc = security_context_to_sid(value, size, &newsid); 2732 rc = security_context_to_sid(value, size, &newsid);
2733 if (rc == -EINVAL) {
2734 if (!capable(CAP_MAC_ADMIN))
2735 return rc;
2736 rc = security_context_to_sid_force(value, size, &newsid);
2737 }
2672 if (rc) 2738 if (rc)
2673 return rc; 2739 return rc;
2674 2740
@@ -2690,7 +2756,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2690} 2756}
2691 2757
2692static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, 2758static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2693 const void *value, size_t size, 2759 const void *value, size_t size,
2694 int flags) 2760 int flags)
2695{ 2761{
2696 struct inode *inode = dentry->d_inode; 2762 struct inode *inode = dentry->d_inode;
@@ -2703,10 +2769,11 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
2703 return; 2769 return;
2704 } 2770 }
2705 2771
2706 rc = security_context_to_sid(value, size, &newsid); 2772 rc = security_context_to_sid_force(value, size, &newsid);
2707 if (rc) { 2773 if (rc) {
2708 printk(KERN_WARNING "%s: unable to obtain SID for context " 2774 printk(KERN_ERR "SELinux: unable to map context to SID"
2709 "%s, rc=%d\n", __func__, (char *)value, -rc); 2775 "for (%s, %lu), rc=%d\n",
2776 inode->i_sb->s_id, inode->i_ino, -rc);
2710 return; 2777 return;
2711 } 2778 }
2712 2779
@@ -2735,9 +2802,7 @@ static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
2735} 2802}
2736 2803
2737/* 2804/*
2738 * Copy the in-core inode security context value to the user. If the 2805 * 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 * 2806 *
2742 * Permission check is handled by selinux_inode_getxattr hook. 2807 * Permission check is handled by selinux_inode_getxattr hook.
2743 */ 2808 */
@@ -2746,12 +2811,33 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
2746 u32 size; 2811 u32 size;
2747 int error; 2812 int error;
2748 char *context = NULL; 2813 char *context = NULL;
2814 struct task_security_struct *tsec = current->security;
2749 struct inode_security_struct *isec = inode->i_security; 2815 struct inode_security_struct *isec = inode->i_security;
2750 2816
2751 if (strcmp(name, XATTR_SELINUX_SUFFIX)) 2817 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2752 return -EOPNOTSUPP; 2818 return -EOPNOTSUPP;
2753 2819
2754 error = security_sid_to_context(isec->sid, &context, &size); 2820 /*
2821 * If the caller has CAP_MAC_ADMIN, then get the raw context
2822 * value even if it is not defined by current policy; otherwise,
2823 * use the in-core value under current policy.
2824 * Use the non-auditing forms of the permission checks since
2825 * getxattr may be called by unprivileged processes commonly
2826 * and lack of permission just means that we fall back to the
2827 * in-core context value, not a denial.
2828 */
2829 error = secondary_ops->capable(current, CAP_MAC_ADMIN);
2830 if (!error)
2831 error = avc_has_perm_noaudit(tsec->sid, tsec->sid,
2832 SECCLASS_CAPABILITY2,
2833 CAPABILITY2__MAC_ADMIN,
2834 0,
2835 NULL);
2836 if (!error)
2837 error = security_sid_to_context_force(isec->sid, &context,
2838 &size);
2839 else
2840 error = security_sid_to_context(isec->sid, &context, &size);
2755 if (error) 2841 if (error)
2756 return error; 2842 return error;
2757 error = size; 2843 error = size;
@@ -2865,46 +2951,16 @@ static void selinux_file_free_security(struct file *file)
2865static int selinux_file_ioctl(struct file *file, unsigned int cmd, 2951static int selinux_file_ioctl(struct file *file, unsigned int cmd,
2866 unsigned long arg) 2952 unsigned long arg)
2867{ 2953{
2868 int error = 0; 2954 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 2955
2896 case KDSKBENT: 2956 if (_IOC_DIR(cmd) & _IOC_WRITE)
2897 case KDSKBSENT: 2957 av |= FILE__WRITE;
2898 error = task_has_capability(current, CAP_SYS_TTY_CONFIG); 2958 if (_IOC_DIR(cmd) & _IOC_READ)
2899 break; 2959 av |= FILE__READ;
2960 if (!av)
2961 av = FILE__IOCTL;
2900 2962
2901 /* default case assumes that the command will go 2963 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} 2964}
2909 2965
2910static int file_map_prot_check(struct file *file, unsigned long prot, int shared) 2966static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
@@ -3663,7 +3719,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3663 struct sockaddr_in6 *addr6 = NULL; 3719 struct sockaddr_in6 *addr6 = NULL;
3664 unsigned short snum; 3720 unsigned short snum;
3665 struct sock *sk = sock->sk; 3721 struct sock *sk = sock->sk;
3666 u32 sid, node_perm, addrlen; 3722 u32 sid, node_perm;
3667 3723
3668 tsec = current->security; 3724 tsec = current->security;
3669 isec = SOCK_INODE(sock)->i_security; 3725 isec = SOCK_INODE(sock)->i_security;
@@ -3671,12 +3727,10 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3671 if (family == PF_INET) { 3727 if (family == PF_INET) {
3672 addr4 = (struct sockaddr_in *)address; 3728 addr4 = (struct sockaddr_in *)address;
3673 snum = ntohs(addr4->sin_port); 3729 snum = ntohs(addr4->sin_port);
3674 addrlen = sizeof(addr4->sin_addr.s_addr);
3675 addrp = (char *)&addr4->sin_addr.s_addr; 3730 addrp = (char *)&addr4->sin_addr.s_addr;
3676 } else { 3731 } else {
3677 addr6 = (struct sockaddr_in6 *)address; 3732 addr6 = (struct sockaddr_in6 *)address;
3678 snum = ntohs(addr6->sin6_port); 3733 snum = ntohs(addr6->sin6_port);
3679 addrlen = sizeof(addr6->sin6_addr.s6_addr);
3680 addrp = (char *)&addr6->sin6_addr.s6_addr; 3734 addrp = (char *)&addr6->sin6_addr.s6_addr;
3681 } 3735 }
3682 3736
@@ -5047,24 +5101,6 @@ static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid)
5047 *secid = isec->sid; 5101 *secid = isec->sid;
5048} 5102}
5049 5103
5050/* module stacking operations */
5051static 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
5068static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode) 5104static void selinux_d_instantiate(struct dentry *dentry, struct inode *inode)
5069{ 5105{
5070 if (inode) 5106 if (inode)
@@ -5153,6 +5189,12 @@ static int selinux_setprocattr(struct task_struct *p,
5153 size--; 5189 size--;
5154 } 5190 }
5155 error = security_context_to_sid(value, size, &sid); 5191 error = security_context_to_sid(value, size, &sid);
5192 if (error == -EINVAL && !strcmp(name, "fscreate")) {
5193 if (!capable(CAP_MAC_ADMIN))
5194 return error;
5195 error = security_context_to_sid_force(value, size,
5196 &sid);
5197 }
5156 if (error) 5198 if (error)
5157 return error; 5199 return error;
5158 } 5200 }
@@ -5186,12 +5228,12 @@ static int selinux_setprocattr(struct task_struct *p,
5186 struct task_struct *g, *t; 5228 struct task_struct *g, *t;
5187 struct mm_struct *mm = p->mm; 5229 struct mm_struct *mm = p->mm;
5188 read_lock(&tasklist_lock); 5230 read_lock(&tasklist_lock);
5189 do_each_thread(g, t) 5231 do_each_thread(g, t) {
5190 if (t->mm == mm && t != p) { 5232 if (t->mm == mm && t != p) {
5191 read_unlock(&tasklist_lock); 5233 read_unlock(&tasklist_lock);
5192 return -EPERM; 5234 return -EPERM;
5193 } 5235 }
5194 while_each_thread(g, t); 5236 } while_each_thread(g, t);
5195 read_unlock(&tasklist_lock); 5237 read_unlock(&tasklist_lock);
5196 } 5238 }
5197 5239
@@ -5343,10 +5385,10 @@ static struct security_operations selinux_ops = {
5343 .sb_free_security = selinux_sb_free_security, 5385 .sb_free_security = selinux_sb_free_security,
5344 .sb_copy_data = selinux_sb_copy_data, 5386 .sb_copy_data = selinux_sb_copy_data,
5345 .sb_kern_mount = selinux_sb_kern_mount, 5387 .sb_kern_mount = selinux_sb_kern_mount,
5388 .sb_show_options = selinux_sb_show_options,
5346 .sb_statfs = selinux_sb_statfs, 5389 .sb_statfs = selinux_sb_statfs,
5347 .sb_mount = selinux_mount, 5390 .sb_mount = selinux_mount,
5348 .sb_umount = selinux_umount, 5391 .sb_umount = selinux_umount,
5349 .sb_get_mnt_opts = selinux_get_mnt_opts,
5350 .sb_set_mnt_opts = selinux_set_mnt_opts, 5392 .sb_set_mnt_opts = selinux_set_mnt_opts,
5351 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts, 5393 .sb_clone_mnt_opts = selinux_sb_clone_mnt_opts,
5352 .sb_parse_opts_str = selinux_parse_opts_str, 5394 .sb_parse_opts_str = selinux_parse_opts_str,
@@ -5378,7 +5420,7 @@ static struct security_operations selinux_ops = {
5378 .inode_listsecurity = selinux_inode_listsecurity, 5420 .inode_listsecurity = selinux_inode_listsecurity,
5379 .inode_need_killpriv = selinux_inode_need_killpriv, 5421 .inode_need_killpriv = selinux_inode_need_killpriv,
5380 .inode_killpriv = selinux_inode_killpriv, 5422 .inode_killpriv = selinux_inode_killpriv,
5381 .inode_getsecid = selinux_inode_getsecid, 5423 .inode_getsecid = selinux_inode_getsecid,
5382 5424
5383 .file_permission = selinux_file_permission, 5425 .file_permission = selinux_file_permission,
5384 .file_alloc_security = selinux_file_alloc_security, 5426 .file_alloc_security = selinux_file_alloc_security,
@@ -5419,7 +5461,7 @@ static struct security_operations selinux_ops = {
5419 .task_to_inode = selinux_task_to_inode, 5461 .task_to_inode = selinux_task_to_inode,
5420 5462
5421 .ipc_permission = selinux_ipc_permission, 5463 .ipc_permission = selinux_ipc_permission,
5422 .ipc_getsecid = selinux_ipc_getsecid, 5464 .ipc_getsecid = selinux_ipc_getsecid,
5423 5465
5424 .msg_msg_alloc_security = selinux_msg_msg_alloc_security, 5466 .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
5425 .msg_msg_free_security = selinux_msg_msg_free_security, 5467 .msg_msg_free_security = selinux_msg_msg_free_security,
@@ -5443,8 +5485,6 @@ static struct security_operations selinux_ops = {
5443 .sem_semctl = selinux_sem_semctl, 5485 .sem_semctl = selinux_sem_semctl,
5444 .sem_semop = selinux_sem_semop, 5486 .sem_semop = selinux_sem_semop,
5445 5487
5446 .register_security = selinux_register_security,
5447
5448 .d_instantiate = selinux_d_instantiate, 5488 .d_instantiate = selinux_d_instantiate,
5449 5489
5450 .getprocattr = selinux_getprocattr, 5490 .getprocattr = selinux_getprocattr,
@@ -5538,7 +5578,7 @@ static __init int selinux_init(void)
5538 0, SLAB_PANIC, NULL); 5578 0, SLAB_PANIC, NULL);
5539 avc_init(); 5579 avc_init();
5540 5580
5541 original_ops = secondary_ops = security_ops; 5581 secondary_ops = security_ops;
5542 if (!secondary_ops) 5582 if (!secondary_ops)
5543 panic("SELinux: No initial security operations\n"); 5583 panic("SELinux: No initial security operations\n");
5544 if (register_security(&selinux_ops)) 5584 if (register_security(&selinux_ops))