Skip to content

Commit 2be4d74

Browse files
pebenitoeparis
authored andcommitted
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 <[email protected]> Signed-off-by: Eric Paris <[email protected]>
1 parent b04eea8 commit 2be4d74

File tree

4 files changed

+30
-6
lines changed

4 files changed

+30
-6
lines changed

security/selinux/hooks.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,28 @@ static struct kmem_cache *sel_inode_cache;
136136
* This function checks the SECMARK reference counter to see if any SECMARK
137137
* targets are currently configured, if the reference counter is greater than
138138
* 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.
140141
*
141142
*/
142143
static int selinux_secmark_enabled(void)
143144
{
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+
*/
158+
static int selinux_peerlbl_enabled(void)
159+
{
160+
return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
145161
}
146162

147163
/*
@@ -4197,7 +4213,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
41974213
return selinux_sock_rcv_skb_compat(sk, skb, family);
41984214

41994215
secmark_active = selinux_secmark_enabled();
4200-
peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
4216+
peerlbl_active = selinux_peerlbl_enabled();
42014217
if (!secmark_active && !peerlbl_active)
42024218
return 0;
42034219

@@ -4579,7 +4595,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
45794595

45804596
secmark_active = selinux_secmark_enabled();
45814597
netlbl_active = netlbl_enabled();
4582-
peerlbl_active = netlbl_active || selinux_xfrm_enabled();
4598+
peerlbl_active = selinux_peerlbl_enabled();
45834599
if (!secmark_active && !peerlbl_active)
45844600
return NF_ACCEPT;
45854601

@@ -4731,7 +4747,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
47314747
return NF_ACCEPT;
47324748
#endif
47334749
secmark_active = selinux_secmark_enabled();
4734-
peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
4750+
peerlbl_active = selinux_peerlbl_enabled();
47354751
if (!secmark_active && !peerlbl_active)
47364752
return NF_ACCEPT;
47374753

security/selinux/include/security.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,15 @@ extern int selinux_enabled;
6969
enum {
7070
POLICYDB_CAPABILITY_NETPEER,
7171
POLICYDB_CAPABILITY_OPENPERM,
72+
POLICYDB_CAPABILITY_REDHAT1,
73+
POLICYDB_CAPABILITY_ALWAYSNETWORK,
7274
__POLICYDB_CAPABILITY_MAX
7375
};
7476
#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
7577

7678
extern int selinux_policycap_netpeer;
7779
extern int selinux_policycap_openperm;
80+
extern int selinux_policycap_alwaysnetwork;
7881

7982
/*
8083
* type_datum properties

security/selinux/selinuxfs.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@
4444
/* Policy capability filenames */
4545
static char *policycap_names[] = {
4646
"network_peer_controls",
47-
"open_perms"
47+
"open_perms",
48+
"redhat1",
49+
"always_check_network"
4850
};
4951

5052
unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;

security/selinux/ss/services.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272

7373
int selinux_policycap_netpeer;
7474
int selinux_policycap_openperm;
75+
int selinux_policycap_alwaysnetwork;
7576

7677
static DEFINE_RWLOCK(policy_rwlock);
7778

@@ -1812,6 +1813,8 @@ static void security_load_policycaps(void)
18121813
POLICYDB_CAPABILITY_NETPEER);
18131814
selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps,
18141815
POLICYDB_CAPABILITY_OPENPERM);
1816+
selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps,
1817+
POLICYDB_CAPABILITY_ALWAYSNETWORK);
18151818
}
18161819

18171820
static int security_preserve_bools(struct policydb *p);

0 commit comments

Comments
 (0)