selinux: reduce the number of calls to synchronize_net() when flushing caches
When flushing the AVC, such as during a policy load, the various network caches are also flushed, with each making a call to synchronize_net() which has shown to be expensive in some cases. This patch consolidates the network cache flushes into a single AVC callback which only calls synchronize_net() once for each AVC cache flush. Reported-by: Jaejyn Shin <flagon22bass@gmail.com> Signed-off-by: Paul Moore <pmoore@redhat.com>
This commit is contained in:
parent
f31e799459
commit
615e51fdda
|
@ -161,6 +161,17 @@ static int selinux_peerlbl_enabled(void)
|
||||||
return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
|
return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int selinux_netcache_avc_callback(u32 event)
|
||||||
|
{
|
||||||
|
if (event == AVC_CALLBACK_RESET) {
|
||||||
|
sel_netif_flush();
|
||||||
|
sel_netnode_flush();
|
||||||
|
sel_netport_flush();
|
||||||
|
synchronize_net();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialise the security for the init task
|
* initialise the security for the init task
|
||||||
*/
|
*/
|
||||||
|
@ -5993,6 +6004,9 @@ static __init int selinux_init(void)
|
||||||
if (register_security(&selinux_ops))
|
if (register_security(&selinux_ops))
|
||||||
panic("SELinux: Unable to register with kernel.\n");
|
panic("SELinux: Unable to register with kernel.\n");
|
||||||
|
|
||||||
|
if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
|
||||||
|
panic("SELinux: Unable to register AVC netcache callback\n");
|
||||||
|
|
||||||
if (selinux_enforcing)
|
if (selinux_enforcing)
|
||||||
printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
|
printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#ifndef _SELINUX_NETIF_H_
|
#ifndef _SELINUX_NETIF_H_
|
||||||
#define _SELINUX_NETIF_H_
|
#define _SELINUX_NETIF_H_
|
||||||
|
|
||||||
|
void sel_netif_flush(void);
|
||||||
|
|
||||||
int sel_netif_sid(int ifindex, u32 *sid);
|
int sel_netif_sid(int ifindex, u32 *sid);
|
||||||
|
|
||||||
#endif /* _SELINUX_NETIF_H_ */
|
#endif /* _SELINUX_NETIF_H_ */
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#ifndef _SELINUX_NETNODE_H
|
#ifndef _SELINUX_NETNODE_H
|
||||||
#define _SELINUX_NETNODE_H
|
#define _SELINUX_NETNODE_H
|
||||||
|
|
||||||
|
void sel_netnode_flush(void);
|
||||||
|
|
||||||
int sel_netnode_sid(void *addr, u16 family, u32 *sid);
|
int sel_netnode_sid(void *addr, u16 family, u32 *sid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#ifndef _SELINUX_NETPORT_H
|
#ifndef _SELINUX_NETPORT_H
|
||||||
#define _SELINUX_NETPORT_H
|
#define _SELINUX_NETPORT_H
|
||||||
|
|
||||||
|
void sel_netport_flush(void);
|
||||||
|
|
||||||
int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
|
int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -240,7 +240,7 @@ static void sel_netif_kill(int ifindex)
|
||||||
* Remove all entries from the network interface table.
|
* Remove all entries from the network interface table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void sel_netif_flush(void)
|
void sel_netif_flush(void)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
struct sel_netif *netif;
|
struct sel_netif *netif;
|
||||||
|
@ -252,15 +252,6 @@ static void sel_netif_flush(void)
|
||||||
spin_unlock_bh(&sel_netif_lock);
|
spin_unlock_bh(&sel_netif_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sel_netif_avc_callback(u32 event)
|
|
||||||
{
|
|
||||||
if (event == AVC_CALLBACK_RESET) {
|
|
||||||
sel_netif_flush();
|
|
||||||
synchronize_net();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
|
static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
|
||||||
unsigned long event, void *ptr)
|
unsigned long event, void *ptr)
|
||||||
{
|
{
|
||||||
|
@ -291,10 +282,6 @@ static __init int sel_netif_init(void)
|
||||||
|
|
||||||
register_netdevice_notifier(&sel_netif_netdev_notifier);
|
register_netdevice_notifier(&sel_netif_netdev_notifier);
|
||||||
|
|
||||||
err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET);
|
|
||||||
if (err)
|
|
||||||
panic("avc_add_callback() failed, error %d\n", err);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
|
||||||
* Remove all entries from the network address table.
|
* Remove all entries from the network address table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void sel_netnode_flush(void)
|
void sel_netnode_flush(void)
|
||||||
{
|
{
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
struct sel_netnode *node, *node_tmp;
|
struct sel_netnode *node, *node_tmp;
|
||||||
|
@ -300,15 +300,6 @@ static void sel_netnode_flush(void)
|
||||||
spin_unlock_bh(&sel_netnode_lock);
|
spin_unlock_bh(&sel_netnode_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sel_netnode_avc_callback(u32 event)
|
|
||||||
{
|
|
||||||
if (event == AVC_CALLBACK_RESET) {
|
|
||||||
sel_netnode_flush();
|
|
||||||
synchronize_net();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init int sel_netnode_init(void)
|
static __init int sel_netnode_init(void)
|
||||||
{
|
{
|
||||||
int iter;
|
int iter;
|
||||||
|
@ -322,10 +313,6 @@ static __init int sel_netnode_init(void)
|
||||||
sel_netnode_hash[iter].size = 0;
|
sel_netnode_hash[iter].size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET);
|
|
||||||
if (ret != 0)
|
|
||||||
panic("avc_add_callback() failed, error %d\n", ret);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,7 +217,7 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
|
||||||
* Remove all entries from the network address table.
|
* Remove all entries from the network address table.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void sel_netport_flush(void)
|
void sel_netport_flush(void)
|
||||||
{
|
{
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
struct sel_netport *port, *port_tmp;
|
struct sel_netport *port, *port_tmp;
|
||||||
|
@ -234,15 +234,6 @@ static void sel_netport_flush(void)
|
||||||
spin_unlock_bh(&sel_netport_lock);
|
spin_unlock_bh(&sel_netport_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sel_netport_avc_callback(u32 event)
|
|
||||||
{
|
|
||||||
if (event == AVC_CALLBACK_RESET) {
|
|
||||||
sel_netport_flush();
|
|
||||||
synchronize_net();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __init int sel_netport_init(void)
|
static __init int sel_netport_init(void)
|
||||||
{
|
{
|
||||||
int iter;
|
int iter;
|
||||||
|
@ -256,10 +247,6 @@ static __init int sel_netport_init(void)
|
||||||
sel_netport_hash[iter].size = 0;
|
sel_netport_hash[iter].size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET);
|
|
||||||
if (ret != 0)
|
|
||||||
panic("avc_add_callback() failed, error %d\n", ret);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue