aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2014-06-26 14:33:56 -0400
committerPaul Moore <pmoore@redhat.com>2014-06-26 14:33:56 -0400
commit615e51fdda6f274e94b1e905fcaf6111e0d9aa20 (patch)
treed0ce12f9f5e086c293a7255e3e712d2a42be02b9 /security
parentf31e799459659ae88c341aeac16a8a5efb1271d4 (diff)
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>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/hooks.c14
-rw-r--r--security/selinux/include/netif.h2
-rw-r--r--security/selinux/include/netnode.h2
-rw-r--r--security/selinux/include/netport.h2
-rw-r--r--security/selinux/netif.c15
-rw-r--r--security/selinux/netnode.c15
-rw-r--r--security/selinux/netport.c15
7 files changed, 23 insertions, 42 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 336f0a04450e..39bc8c94b969 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -161,6 +161,17 @@ static int selinux_peerlbl_enabled(void)
161 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled()); 161 return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
162} 162}
163 163
164static int selinux_netcache_avc_callback(u32 event)
165{
166 if (event == AVC_CALLBACK_RESET) {
167 sel_netif_flush();
168 sel_netnode_flush();
169 sel_netport_flush();
170 synchronize_net();
171 }
172 return 0;
173}
174
164/* 175/*
165 * initialise the security for the init task 176 * initialise the security for the init task
166 */ 177 */
@@ -5993,6 +6004,9 @@ static __init int selinux_init(void)
5993 if (register_security(&selinux_ops)) 6004 if (register_security(&selinux_ops))
5994 panic("SELinux: Unable to register with kernel.\n"); 6005 panic("SELinux: Unable to register with kernel.\n");
5995 6006
6007 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6008 panic("SELinux: Unable to register AVC netcache callback\n");
6009
5996 if (selinux_enforcing) 6010 if (selinux_enforcing)
5997 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); 6011 printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
5998 else 6012 else
diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h
index 43d507242b42..57c6eae81eac 100644
--- a/security/selinux/include/netif.h
+++ b/security/selinux/include/netif.h
@@ -17,6 +17,8 @@
17#ifndef _SELINUX_NETIF_H_ 17#ifndef _SELINUX_NETIF_H_
18#define _SELINUX_NETIF_H_ 18#define _SELINUX_NETIF_H_
19 19
20void sel_netif_flush(void);
21
20int sel_netif_sid(int ifindex, u32 *sid); 22int sel_netif_sid(int ifindex, u32 *sid);
21 23
22#endif /* _SELINUX_NETIF_H_ */ 24#endif /* _SELINUX_NETIF_H_ */
diff --git a/security/selinux/include/netnode.h b/security/selinux/include/netnode.h
index df7a5ed6c694..937668dd3024 100644
--- a/security/selinux/include/netnode.h
+++ b/security/selinux/include/netnode.h
@@ -27,6 +27,8 @@
27#ifndef _SELINUX_NETNODE_H 27#ifndef _SELINUX_NETNODE_H
28#define _SELINUX_NETNODE_H 28#define _SELINUX_NETNODE_H
29 29
30void sel_netnode_flush(void);
31
30int sel_netnode_sid(void *addr, u16 family, u32 *sid); 32int sel_netnode_sid(void *addr, u16 family, u32 *sid);
31 33
32#endif 34#endif
diff --git a/security/selinux/include/netport.h b/security/selinux/include/netport.h
index 4d965b83d735..d1ce896b2cb0 100644
--- a/security/selinux/include/netport.h
+++ b/security/selinux/include/netport.h
@@ -26,6 +26,8 @@
26#ifndef _SELINUX_NETPORT_H 26#ifndef _SELINUX_NETPORT_H
27#define _SELINUX_NETPORT_H 27#define _SELINUX_NETPORT_H
28 28
29void sel_netport_flush(void);
30
29int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid); 31int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
30 32
31#endif 33#endif
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 694e9e43855f..3c3de4ca0ebc 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -240,7 +240,7 @@ static void sel_netif_kill(int ifindex)
240 * Remove all entries from the network interface table. 240 * Remove all entries from the network interface table.
241 * 241 *
242 */ 242 */
243static void sel_netif_flush(void) 243void sel_netif_flush(void)
244{ 244{
245 int idx; 245 int idx;
246 struct sel_netif *netif; 246 struct sel_netif *netif;
@@ -252,15 +252,6 @@ static void sel_netif_flush(void)
252 spin_unlock_bh(&sel_netif_lock); 252 spin_unlock_bh(&sel_netif_lock);
253} 253}
254 254
255static int sel_netif_avc_callback(u32 event)
256{
257 if (event == AVC_CALLBACK_RESET) {
258 sel_netif_flush();
259 synchronize_net();
260 }
261 return 0;
262}
263
264static int sel_netif_netdev_notifier_handler(struct notifier_block *this, 255static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
265 unsigned long event, void *ptr) 256 unsigned long event, void *ptr)
266{ 257{
@@ -291,10 +282,6 @@ static __init int sel_netif_init(void)
291 282
292 register_netdevice_notifier(&sel_netif_netdev_notifier); 283 register_netdevice_notifier(&sel_netif_netdev_notifier);
293 284
294 err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET);
295 if (err)
296 panic("avc_add_callback() failed, error %d\n", err);
297
298 return err; 285 return err;
299} 286}
300 287
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 03a72c32afd7..ddf315260839 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -283,7 +283,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
283 * Remove all entries from the network address table. 283 * Remove all entries from the network address table.
284 * 284 *
285 */ 285 */
286static void sel_netnode_flush(void) 286void sel_netnode_flush(void)
287{ 287{
288 unsigned int idx; 288 unsigned int idx;
289 struct sel_netnode *node, *node_tmp; 289 struct sel_netnode *node, *node_tmp;
@@ -300,15 +300,6 @@ static void sel_netnode_flush(void)
300 spin_unlock_bh(&sel_netnode_lock); 300 spin_unlock_bh(&sel_netnode_lock);
301} 301}
302 302
303static int sel_netnode_avc_callback(u32 event)
304{
305 if (event == AVC_CALLBACK_RESET) {
306 sel_netnode_flush();
307 synchronize_net();
308 }
309 return 0;
310}
311
312static __init int sel_netnode_init(void) 303static __init int sel_netnode_init(void)
313{ 304{
314 int iter; 305 int iter;
@@ -322,10 +313,6 @@ static __init int sel_netnode_init(void)
322 sel_netnode_hash[iter].size = 0; 313 sel_netnode_hash[iter].size = 0;
323 } 314 }
324 315
325 ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET);
326 if (ret != 0)
327 panic("avc_add_callback() failed, error %d\n", ret);
328
329 return ret; 316 return ret;
330} 317}
331 318
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index d35379781c2c..73ac6784d091 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -217,7 +217,7 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
217 * Remove all entries from the network address table. 217 * Remove all entries from the network address table.
218 * 218 *
219 */ 219 */
220static void sel_netport_flush(void) 220void sel_netport_flush(void)
221{ 221{
222 unsigned int idx; 222 unsigned int idx;
223 struct sel_netport *port, *port_tmp; 223 struct sel_netport *port, *port_tmp;
@@ -234,15 +234,6 @@ static void sel_netport_flush(void)
234 spin_unlock_bh(&sel_netport_lock); 234 spin_unlock_bh(&sel_netport_lock);
235} 235}
236 236
237static int sel_netport_avc_callback(u32 event)
238{
239 if (event == AVC_CALLBACK_RESET) {
240 sel_netport_flush();
241 synchronize_net();
242 }
243 return 0;
244}
245
246static __init int sel_netport_init(void) 237static __init int sel_netport_init(void)
247{ 238{
248 int iter; 239 int iter;
@@ -256,10 +247,6 @@ static __init int sel_netport_init(void)
256 sel_netport_hash[iter].size = 0; 247 sel_netport_hash[iter].size = 0;
257 } 248 }
258 249
259 ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET);
260 if (ret != 0)
261 panic("avc_add_callback() failed, error %d\n", ret);
262
263 return ret; 250 return ret;
264} 251}
265 252