Skip to content

Commit 615e51f

Browse files
committed
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 <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent f31e799 commit 615e51f

File tree

7 files changed

+23
-42
lines changed

7 files changed

+23
-42
lines changed

security/selinux/hooks.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ static int selinux_peerlbl_enabled(void)
161161
return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
162162
}
163163

164+
static 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+
164175
/*
165176
* initialise the security for the init task
166177
*/
@@ -5993,6 +6004,9 @@ static __init int selinux_init(void)
59936004
if (register_security(&selinux_ops))
59946005
panic("SELinux: Unable to register with kernel.\n");
59956006

6007+
if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
6008+
panic("SELinux: Unable to register AVC netcache callback\n");
6009+
59966010
if (selinux_enforcing)
59976011
printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
59986012
else

security/selinux/include/netif.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#ifndef _SELINUX_NETIF_H_
1818
#define _SELINUX_NETIF_H_
1919

20+
void sel_netif_flush(void);
21+
2022
int sel_netif_sid(int ifindex, u32 *sid);
2123

2224
#endif /* _SELINUX_NETIF_H_ */

security/selinux/include/netnode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#ifndef _SELINUX_NETNODE_H
2828
#define _SELINUX_NETNODE_H
2929

30+
void sel_netnode_flush(void);
31+
3032
int sel_netnode_sid(void *addr, u16 family, u32 *sid);
3133

3234
#endif

security/selinux/include/netport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#ifndef _SELINUX_NETPORT_H
2727
#define _SELINUX_NETPORT_H
2828

29+
void sel_netport_flush(void);
30+
2931
int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
3032

3133
#endif

security/selinux/netif.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ static void sel_netif_kill(int ifindex)
240240
* Remove all entries from the network interface table.
241241
*
242242
*/
243-
static void sel_netif_flush(void)
243+
void sel_netif_flush(void)
244244
{
245245
int idx;
246246
struct sel_netif *netif;
@@ -252,15 +252,6 @@ static void sel_netif_flush(void)
252252
spin_unlock_bh(&sel_netif_lock);
253253
}
254254

255-
static 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-
264255
static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
265256
unsigned long event, void *ptr)
266257
{
@@ -291,10 +282,6 @@ static __init int sel_netif_init(void)
291282

292283
register_netdevice_notifier(&sel_netif_netdev_notifier);
293284

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-
298285
return err;
299286
}
300287

security/selinux/netnode.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
283283
* Remove all entries from the network address table.
284284
*
285285
*/
286-
static void sel_netnode_flush(void)
286+
void sel_netnode_flush(void)
287287
{
288288
unsigned int idx;
289289
struct sel_netnode *node, *node_tmp;
@@ -300,15 +300,6 @@ static void sel_netnode_flush(void)
300300
spin_unlock_bh(&sel_netnode_lock);
301301
}
302302

303-
static 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-
312303
static __init int sel_netnode_init(void)
313304
{
314305
int iter;
@@ -322,10 +313,6 @@ static __init int sel_netnode_init(void)
322313
sel_netnode_hash[iter].size = 0;
323314
}
324315

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-
329316
return ret;
330317
}
331318

security/selinux/netport.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
217217
* Remove all entries from the network address table.
218218
*
219219
*/
220-
static void sel_netport_flush(void)
220+
void sel_netport_flush(void)
221221
{
222222
unsigned int idx;
223223
struct sel_netport *port, *port_tmp;
@@ -234,15 +234,6 @@ static void sel_netport_flush(void)
234234
spin_unlock_bh(&sel_netport_lock);
235235
}
236236

237-
static 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-
246237
static __init int sel_netport_init(void)
247238
{
248239
int iter;
@@ -256,10 +247,6 @@ static __init int sel_netport_init(void)
256247
sel_netport_hash[iter].size = 0;
257248
}
258249

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-
263250
return ret;
264251
}
265252

0 commit comments

Comments
 (0)