aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorChris PeBenito <cpebenito@tresys.com>2013-05-03 09:05:39 -0400
committerEric Paris <eparis@redhat.com>2013-07-25 13:03:38 -0400
commit2be4d74f2fd45460d70d4fe65cc1972ef45bf849 (patch)
tree5dd4b74ae295dc6ba58f974a3b748fe7a2f06d3c /security/selinux
parentb04eea886409de7460b5727b5931fb0bd417275f (diff)
Add SELinux policy capability for always checking packet and peer classes.
Currently the packet class in SELinux is not checked if there are no SECMARK rules in the security or mangle netfilter tables. Some systems prefer that packets are always checked, for example, to protect the system should the netfilter rules fail to load or if the nefilter rules were maliciously flushed. Add the always_check_network policy capability which, when enabled, treats SECMARK as enabled, even if there are no netfilter SECMARK rules and treats peer labeling as enabled, even if there is no Netlabel or labeled IPSEC configuration. Includes definition of "redhat1" SELinux policy capability, which exists in the SELinux userpace library, to keep ordering correct. The SELinux userpace portion of this was merged last year, but this kernel change fell on the floor. Signed-off-by: Chris PeBenito <cpebenito@tresys.com> Signed-off-by: Eric Paris <eparis@redhat.com>
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c26
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/services.c3
4 files changed, 30 insertions, 6 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b222e966babe..4fbf2c5f26ce 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -136,12 +136,28 @@ static struct kmem_cache *sel_inode_cache;
136 * This function checks the SECMARK reference counter to see if any SECMARK 136 * This function checks the SECMARK reference counter to see if any SECMARK
137 * targets are currently configured, if the reference counter is greater than 137 * targets are currently configured, if the reference counter is greater than
138 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is 138 * zero SECMARK is considered to be enabled. Returns true (1) if SECMARK is
139 * enabled, false (0) if SECMARK is disabled. 139 * enabled, false (0) if SECMARK is disabled. If the always_check_network
140 * policy capability is enabled, SECMARK is always considered enabled.
140 * 141 *
141 */ 142 */
142static int selinux_secmark_enabled(void) 143static int selinux_secmark_enabled(void)
143{ 144{
144 return (atomic_read(&selinux_secmark_refcount) > 0); 145 return (selinux_policycap_alwaysnetwork || atomic_read(&selinux_secmark_refcount));
146}
147
148/**
149 * selinux_peerlbl_enabled - Check to see if peer labeling is currently enabled
150 *
151 * Description:
152 * This function checks if NetLabel or labeled IPSEC is enabled. Returns true
153 * (1) if any are enabled or false (0) if neither are enabled. If the
154 * always_check_network policy capability is enabled, peer labeling
155 * is always considered enabled.
156 *
157 */
158static int selinux_peerlbl_enabled(void)
159{
160 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
145} 161}
146 162
147/* 163/*
@@ -4197,7 +4213,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
4197 return selinux_sock_rcv_skb_compat(sk, skb, family); 4213 return selinux_sock_rcv_skb_compat(sk, skb, family);
4198 4214
4199 secmark_active = selinux_secmark_enabled(); 4215 secmark_active = selinux_secmark_enabled();
4200 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4216 peerlbl_active = selinux_peerlbl_enabled();
4201 if (!secmark_active && !peerlbl_active) 4217 if (!secmark_active && !peerlbl_active)
4202 return 0; 4218 return 0;
4203 4219
@@ -4579,7 +4595,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
4579 4595
4580 secmark_active = selinux_secmark_enabled(); 4596 secmark_active = selinux_secmark_enabled();
4581 netlbl_active = netlbl_enabled(); 4597 netlbl_active = netlbl_enabled();
4582 peerlbl_active = netlbl_active || selinux_xfrm_enabled(); 4598 peerlbl_active = selinux_peerlbl_enabled();
4583 if (!secmark_active && !peerlbl_active) 4599 if (!secmark_active && !peerlbl_active)
4584 return NF_ACCEPT; 4600 return NF_ACCEPT;
4585 4601
@@ -4731,7 +4747,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
4731 return NF_ACCEPT; 4747 return NF_ACCEPT;
4732#endif 4748#endif
4733 secmark_active = selinux_secmark_enabled(); 4749 secmark_active = selinux_secmark_enabled();
4734 peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled(); 4750 peerlbl_active = selinux_peerlbl_enabled();
4735 if (!secmark_active && !peerlbl_active) 4751 if (!secmark_active && !peerlbl_active)
4736 return NF_ACCEPT; 4752 return NF_ACCEPT;
4737 4753
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 01a0382c43ca..004a2479880f 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -69,12 +69,15 @@ extern int selinux_enabled;
69enum { 69enum {
70 POLICYDB_CAPABILITY_NETPEER, 70 POLICYDB_CAPABILITY_NETPEER,
71 POLICYDB_CAPABILITY_OPENPERM, 71 POLICYDB_CAPABILITY_OPENPERM,
72 POLICYDB_CAPABILITY_REDHAT1,
73 POLICYDB_CAPABILITY_ALWAYSNETWORK,
72 __POLICYDB_CAPABILITY_MAX 74 __POLICYDB_CAPABILITY_MAX
73}; 75};
74#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) 76#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
75 77
76extern int selinux_policycap_netpeer; 78extern int selinux_policycap_netpeer;
77extern int selinux_policycap_openperm; 79extern int selinux_policycap_openperm;
80extern int selinux_policycap_alwaysnetwork;
78 81
79/* 82/*
80 * type_datum properties 83 * type_datum properties
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index ff427733c290..5122affe06a8 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -44,7 +44,9 @@
44/* Policy capability filenames */ 44/* Policy capability filenames */
45static char *policycap_names[] = { 45static char *policycap_names[] = {
46 "network_peer_controls", 46 "network_peer_controls",
47 "open_perms" 47 "open_perms",
48 "redhat1",
49 "always_check_network"
48}; 50};
49 51
50unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; 52unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index a90721771615..d106733ad987 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -72,6 +72,7 @@
72 72
73int selinux_policycap_netpeer; 73int selinux_policycap_netpeer;
74int selinux_policycap_openperm; 74int selinux_policycap_openperm;
75int selinux_policycap_alwaysnetwork;
75 76
76static DEFINE_RWLOCK(policy_rwlock); 77static DEFINE_RWLOCK(policy_rwlock);
77 78
@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
1812 POLICYDB_CAPABILITY_NETPEER); 1813 POLICYDB_CAPABILITY_NETPEER);
1813 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, 1814 selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
1814 POLICYDB_CAPABILITY_OPENPERM); 1815 POLICYDB_CAPABILITY_OPENPERM);
1816 selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
1817 POLICYDB_CAPABILITY_ALWAYSNETWORK);
1815} 1818}
1816 1819
1817static int security_preserve_bools(struct policydb *p); 1820static int security_preserve_bools(struct policydb *p);