aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c199
1 files changed, 127 insertions, 72 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0753b20e23fe..24e1b1885de7 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -14,13 +14,14 @@
14 * <dgoeddel@trustedcs.com> 14 * <dgoeddel@trustedcs.com>
15 * Copyright (C) 2006 Hewlett-Packard Development Company, L.P. 15 * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
16 * Paul Moore, <paul.moore@hp.com> 16 * Paul Moore, <paul.moore@hp.com>
17 * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
18 * Yuichi Nakamura <ynakam@hitachisoft.jp>
17 * 19 *
18 * This program is free software; you can redistribute it and/or modify 20 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License version 2, 21 * it under the terms of the GNU General Public License version 2,
20 * as published by the Free Software Foundation. 22 * as published by the Free Software Foundation.
21 */ 23 */
22 24
23#include <linux/module.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <linux/kernel.h> 26#include <linux/kernel.h>
26#include <linux/ptrace.h> 27#include <linux/ptrace.h>
@@ -47,7 +48,7 @@
47#include <linux/netfilter_ipv6.h> 48#include <linux/netfilter_ipv6.h>
48#include <linux/tty.h> 49#include <linux/tty.h>
49#include <net/icmp.h> 50#include <net/icmp.h>
50#include <net/ip.h> /* for sysctl_local_port_range[] */ 51#include <net/ip.h> /* for local_port_range[] */
51#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 */
52#include <asm/uaccess.h> 53#include <asm/uaccess.h>
53#include <asm/ioctls.h> 54#include <asm/ioctls.h>
@@ -84,6 +85,7 @@
84extern unsigned int policydb_loaded_version; 85extern unsigned int policydb_loaded_version;
85extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); 86extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm);
86extern int selinux_compat_net; 87extern int selinux_compat_net;
88extern struct security_operations *security_ops;
87 89
88#ifdef CONFIG_SECURITY_SELINUX_DEVELOP 90#ifdef CONFIG_SECURITY_SELINUX_DEVELOP
89int selinux_enforcing = 0; 91int selinux_enforcing = 0;
@@ -2295,6 +2297,25 @@ static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2295 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); 2297 return dentry_has_perm(current, mnt, dentry, FILE__GETATTR);
2296} 2298}
2297 2299
2300static int selinux_inode_setotherxattr(struct dentry *dentry, char *name)
2301{
2302 if (!strncmp(name, XATTR_SECURITY_PREFIX,
2303 sizeof XATTR_SECURITY_PREFIX - 1)) {
2304 if (!strcmp(name, XATTR_NAME_CAPS)) {
2305 if (!capable(CAP_SETFCAP))
2306 return -EPERM;
2307 } else if (!capable(CAP_SYS_ADMIN)) {
2308 /* A different attribute in the security namespace.
2309 Restrict to administrator. */
2310 return -EPERM;
2311 }
2312 }
2313
2314 /* Not an attribute we recognize, so just check the
2315 ordinary setattr permission. */
2316 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2317}
2318
2298static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) 2319static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags)
2299{ 2320{
2300 struct task_security_struct *tsec = current->security; 2321 struct task_security_struct *tsec = current->security;
@@ -2305,19 +2326,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value
2305 u32 newsid; 2326 u32 newsid;
2306 int rc = 0; 2327 int rc = 0;
2307 2328
2308 if (strcmp(name, XATTR_NAME_SELINUX)) { 2329 if (strcmp(name, XATTR_NAME_SELINUX))
2309 if (!strncmp(name, XATTR_SECURITY_PREFIX, 2330 return selinux_inode_setotherxattr(dentry, name);
2310 sizeof XATTR_SECURITY_PREFIX - 1) &&
2311 !capable(CAP_SYS_ADMIN)) {
2312 /* A different attribute in the security namespace.
2313 Restrict to administrator. */
2314 return -EPERM;
2315 }
2316
2317 /* Not an attribute we recognize, so just check the
2318 ordinary setattr permission. */
2319 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2320 }
2321 2331
2322 sbsec = inode->i_sb->s_security; 2332 sbsec = inode->i_sb->s_security;
2323 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) 2333 if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)
@@ -2391,31 +2401,14 @@ static int selinux_inode_listxattr (struct dentry *dentry)
2391 2401
2392static int selinux_inode_removexattr (struct dentry *dentry, char *name) 2402static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2393{ 2403{
2394 if (strcmp(name, XATTR_NAME_SELINUX)) { 2404 if (strcmp(name, XATTR_NAME_SELINUX))
2395 if (!strncmp(name, XATTR_SECURITY_PREFIX, 2405 return selinux_inode_setotherxattr(dentry, name);
2396 sizeof XATTR_SECURITY_PREFIX - 1) &&
2397 !capable(CAP_SYS_ADMIN)) {
2398 /* A different attribute in the security namespace.
2399 Restrict to administrator. */
2400 return -EPERM;
2401 }
2402
2403 /* Not an attribute we recognize, so just check the
2404 ordinary setattr permission. Might want a separate
2405 permission for removexattr. */
2406 return dentry_has_perm(current, NULL, dentry, FILE__SETATTR);
2407 }
2408 2406
2409 /* No one is allowed to remove a SELinux security label. 2407 /* No one is allowed to remove a SELinux security label.
2410 You can change the label, but all data must be labeled. */ 2408 You can change the label, but all data must be labeled. */
2411 return -EACCES; 2409 return -EACCES;
2412} 2410}
2413 2411
2414static const char *selinux_inode_xattr_getsuffix(void)
2415{
2416 return XATTR_SELINUX_SUFFIX;
2417}
2418
2419/* 2412/*
2420 * Copy the in-core inode security context value to the user. If the 2413 * Copy the in-core inode security context value to the user. If the
2421 * getxattr() prior to this succeeded, check to see if we need to 2414 * getxattr() prior to this succeeded, check to see if we need to
@@ -2462,9 +2455,19 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
2462 return len; 2455 return len;
2463} 2456}
2464 2457
2458static int selinux_inode_need_killpriv(struct dentry *dentry)
2459{
2460 return secondary_ops->inode_need_killpriv(dentry);
2461}
2462
2463static int selinux_inode_killpriv(struct dentry *dentry)
2464{
2465 return secondary_ops->inode_killpriv(dentry);
2466}
2467
2465/* file security operations */ 2468/* file security operations */
2466 2469
2467static int selinux_file_permission(struct file *file, int mask) 2470static int selinux_revalidate_file_permission(struct file *file, int mask)
2468{ 2471{
2469 int rc; 2472 int rc;
2470 struct inode *inode = file->f_path.dentry->d_inode; 2473 struct inode *inode = file->f_path.dentry->d_inode;
@@ -2486,6 +2489,25 @@ static int selinux_file_permission(struct file *file, int mask)
2486 return selinux_netlbl_inode_permission(inode, mask); 2489 return selinux_netlbl_inode_permission(inode, mask);
2487} 2490}
2488 2491
2492static int selinux_file_permission(struct file *file, int mask)
2493{
2494 struct inode *inode = file->f_path.dentry->d_inode;
2495 struct task_security_struct *tsec = current->security;
2496 struct file_security_struct *fsec = file->f_security;
2497 struct inode_security_struct *isec = inode->i_security;
2498
2499 if (!mask) {
2500 /* No permission to check. Existence test. */
2501 return 0;
2502 }
2503
2504 if (tsec->sid == fsec->sid && fsec->isid == isec->sid
2505 && fsec->pseqno == avc_policy_seqno())
2506 return selinux_netlbl_inode_permission(inode, mask);
2507
2508 return selinux_revalidate_file_permission(file, mask);
2509}
2510
2489static int selinux_file_alloc_security(struct file *file) 2511static int selinux_file_alloc_security(struct file *file)
2490{ 2512{
2491 return file_alloc_security(file); 2513 return file_alloc_security(file);
@@ -2725,6 +2747,34 @@ static int selinux_file_receive(struct file *file)
2725 return file_has_perm(current, file, file_to_av(file)); 2747 return file_has_perm(current, file, file_to_av(file));
2726} 2748}
2727 2749
2750static int selinux_dentry_open(struct file *file)
2751{
2752 struct file_security_struct *fsec;
2753 struct inode *inode;
2754 struct inode_security_struct *isec;
2755 inode = file->f_path.dentry->d_inode;
2756 fsec = file->f_security;
2757 isec = inode->i_security;
2758 /*
2759 * Save inode label and policy sequence number
2760 * at open-time so that selinux_file_permission
2761 * can determine whether revalidation is necessary.
2762 * Task label is already saved in the file security
2763 * struct as its SID.
2764 */
2765 fsec->isid = isec->sid;
2766 fsec->pseqno = avc_policy_seqno();
2767 /*
2768 * Since the inode label or policy seqno may have changed
2769 * between the selinux_inode_permission check and the saving
2770 * of state above, recheck that access is still permitted.
2771 * Otherwise, access might never be revalidated against the
2772 * new inode label or new policy.
2773 * This check is not redundant - do not remove.
2774 */
2775 return inode_has_perm(current, inode, file_to_av(file), NULL);
2776}
2777
2728/* task security operations */ 2778/* task security operations */
2729 2779
2730static int selinux_task_create(unsigned long clone_flags) 2780static int selinux_task_create(unsigned long clone_flags)
@@ -2833,6 +2883,12 @@ static int selinux_task_setnice(struct task_struct *p, int nice)
2833 2883
2834static int selinux_task_setioprio(struct task_struct *p, int ioprio) 2884static int selinux_task_setioprio(struct task_struct *p, int ioprio)
2835{ 2885{
2886 int rc;
2887
2888 rc = secondary_ops->task_setioprio(p, ioprio);
2889 if (rc)
2890 return rc;
2891
2836 return task_has_perm(current, p, PROCESS__SETSCHED); 2892 return task_has_perm(current, p, PROCESS__SETSCHED);
2837} 2893}
2838 2894
@@ -2862,6 +2918,12 @@ static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim
2862 2918
2863static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) 2919static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp)
2864{ 2920{
2921 int rc;
2922
2923 rc = secondary_ops->task_setscheduler(p, policy, lp);
2924 if (rc)
2925 return rc;
2926
2865 return task_has_perm(current, p, PROCESS__SETSCHED); 2927 return task_has_perm(current, p, PROCESS__SETSCHED);
2866} 2928}
2867 2929
@@ -3232,8 +3294,6 @@ static int selinux_socket_post_create(struct socket *sock, int family,
3232/* Range of port numbers used to automatically bind. 3294/* Range of port numbers used to automatically bind.
3233 Need to determine whether we should perform a name_bind 3295 Need to determine whether we should perform a name_bind
3234 permission check between the socket and the port number. */ 3296 permission check between the socket and the port number. */
3235#define ip_local_port_range_0 sysctl_local_port_range[0]
3236#define ip_local_port_range_1 sysctl_local_port_range[1]
3237 3297
3238static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) 3298static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen)
3239{ 3299{
@@ -3276,20 +3336,27 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
3276 addrp = (char *)&addr6->sin6_addr.s6_addr; 3336 addrp = (char *)&addr6->sin6_addr.s6_addr;
3277 } 3337 }
3278 3338
3279 if (snum&&(snum < max(PROT_SOCK,ip_local_port_range_0) || 3339 if (snum) {
3280 snum > ip_local_port_range_1)) { 3340 int low, high;
3281 err = security_port_sid(sk->sk_family, sk->sk_type, 3341
3282 sk->sk_protocol, snum, &sid); 3342 inet_get_local_port_range(&low, &high);
3283 if (err) 3343
3284 goto out; 3344 if (snum < max(PROT_SOCK, low) || snum > high) {
3285 AVC_AUDIT_DATA_INIT(&ad,NET); 3345 err = security_port_sid(sk->sk_family,
3286 ad.u.net.sport = htons(snum); 3346 sk->sk_type,
3287 ad.u.net.family = family; 3347 sk->sk_protocol, snum,
3288 err = avc_has_perm(isec->sid, sid, 3348 &sid);
3289 isec->sclass, 3349 if (err)
3290 SOCKET__NAME_BIND, &ad); 3350 goto out;
3291 if (err) 3351 AVC_AUDIT_DATA_INIT(&ad,NET);
3292 goto out; 3352 ad.u.net.sport = htons(snum);
3353 ad.u.net.family = family;
3354 err = avc_has_perm(isec->sid, sid,
3355 isec->sclass,
3356 SOCKET__NAME_BIND, &ad);
3357 if (err)
3358 goto out;
3359 }
3293 } 3360 }
3294 3361
3295 switch(isec->sclass) { 3362 switch(isec->sclass) {
@@ -3927,7 +3994,7 @@ out:
3927} 3994}
3928 3995
3929static unsigned int selinux_ip_postroute_last(unsigned int hooknum, 3996static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3930 struct sk_buff **pskb, 3997 struct sk_buff *skb,
3931 const struct net_device *in, 3998 const struct net_device *in,
3932 const struct net_device *out, 3999 const struct net_device *out,
3933 int (*okfn)(struct sk_buff *), 4000 int (*okfn)(struct sk_buff *),
@@ -3936,7 +4003,6 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3936 char *addrp; 4003 char *addrp;
3937 int len, err = 0; 4004 int len, err = 0;
3938 struct sock *sk; 4005 struct sock *sk;
3939 struct sk_buff *skb = *pskb;
3940 struct avc_audit_data ad; 4006 struct avc_audit_data ad;
3941 struct net_device *dev = (struct net_device *)out; 4007 struct net_device *dev = (struct net_device *)out;
3942 struct sk_security_struct *sksec; 4008 struct sk_security_struct *sksec;
@@ -3972,23 +4038,23 @@ out:
3972} 4038}
3973 4039
3974static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum, 4040static unsigned int selinux_ipv4_postroute_last(unsigned int hooknum,
3975 struct sk_buff **pskb, 4041 struct sk_buff *skb,
3976 const struct net_device *in, 4042 const struct net_device *in,
3977 const struct net_device *out, 4043 const struct net_device *out,
3978 int (*okfn)(struct sk_buff *)) 4044 int (*okfn)(struct sk_buff *))
3979{ 4045{
3980 return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET); 4046 return selinux_ip_postroute_last(hooknum, skb, in, out, okfn, PF_INET);
3981} 4047}
3982 4048
3983#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 4049#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
3984 4050
3985static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum, 4051static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum,
3986 struct sk_buff **pskb, 4052 struct sk_buff *skb,
3987 const struct net_device *in, 4053 const struct net_device *in,
3988 const struct net_device *out, 4054 const struct net_device *out,
3989 int (*okfn)(struct sk_buff *)) 4055 int (*okfn)(struct sk_buff *))
3990{ 4056{
3991 return selinux_ip_postroute_last(hooknum, pskb, in, out, okfn, PF_INET6); 4057 return selinux_ip_postroute_last(hooknum, skb, in, out, okfn, PF_INET6);
3992} 4058}
3993 4059
3994#endif /* IPV6 */ 4060#endif /* IPV6 */
@@ -4483,19 +4549,6 @@ static int selinux_register_security (const char *name, struct security_operatio
4483 return 0; 4549 return 0;
4484} 4550}
4485 4551
4486static int selinux_unregister_security (const char *name, struct security_operations *ops)
4487{
4488 if (ops != secondary_ops) {
4489 printk(KERN_ERR "%s: trying to unregister a security module "
4490 "that is not registered.\n", __FUNCTION__);
4491 return -EINVAL;
4492 }
4493
4494 secondary_ops = original_ops;
4495
4496 return 0;
4497}
4498
4499static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) 4552static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode)
4500{ 4553{
4501 if (inode) 4554 if (inode)
@@ -4773,10 +4826,11 @@ static struct security_operations selinux_ops = {
4773 .inode_getxattr = selinux_inode_getxattr, 4826 .inode_getxattr = selinux_inode_getxattr,
4774 .inode_listxattr = selinux_inode_listxattr, 4827 .inode_listxattr = selinux_inode_listxattr,
4775 .inode_removexattr = selinux_inode_removexattr, 4828 .inode_removexattr = selinux_inode_removexattr,
4776 .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
4777 .inode_getsecurity = selinux_inode_getsecurity, 4829 .inode_getsecurity = selinux_inode_getsecurity,
4778 .inode_setsecurity = selinux_inode_setsecurity, 4830 .inode_setsecurity = selinux_inode_setsecurity,
4779 .inode_listsecurity = selinux_inode_listsecurity, 4831 .inode_listsecurity = selinux_inode_listsecurity,
4832 .inode_need_killpriv = selinux_inode_need_killpriv,
4833 .inode_killpriv = selinux_inode_killpriv,
4780 4834
4781 .file_permission = selinux_file_permission, 4835 .file_permission = selinux_file_permission,
4782 .file_alloc_security = selinux_file_alloc_security, 4836 .file_alloc_security = selinux_file_alloc_security,
@@ -4790,6 +4844,8 @@ static struct security_operations selinux_ops = {
4790 .file_send_sigiotask = selinux_file_send_sigiotask, 4844 .file_send_sigiotask = selinux_file_send_sigiotask,
4791 .file_receive = selinux_file_receive, 4845 .file_receive = selinux_file_receive,
4792 4846
4847 .dentry_open = selinux_dentry_open,
4848
4793 .task_create = selinux_task_create, 4849 .task_create = selinux_task_create,
4794 .task_alloc_security = selinux_task_alloc_security, 4850 .task_alloc_security = selinux_task_alloc_security,
4795 .task_free_security = selinux_task_free_security, 4851 .task_free_security = selinux_task_free_security,
@@ -4839,7 +4895,6 @@ static struct security_operations selinux_ops = {
4839 .sem_semop = selinux_sem_semop, 4895 .sem_semop = selinux_sem_semop,
4840 4896
4841 .register_security = selinux_register_security, 4897 .register_security = selinux_register_security,
4842 .unregister_security = selinux_unregister_security,
4843 4898
4844 .d_instantiate = selinux_d_instantiate, 4899 .d_instantiate = selinux_d_instantiate,
4845 4900