diff options
Diffstat (limited to 'security/selinux/netnode.c')
| -rw-r--r-- | security/selinux/netnode.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 4a7d2ab5b960..9b3da5ce8d39 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -30,6 +30,7 @@ #include <net/ip.h> #include <net/ipv6.h> +#include "initcalls.h" #include "netnode.h" #include "objsec.h" @@ -107,7 +108,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) switch (family) { case PF_INET: - idx = sel_netnode_hashfn_ipv4(*(__be32 *)addr); + idx = sel_netnode_hashfn_ipv4(*(const __be32 *)addr); break; case PF_INET6: idx = sel_netnode_hashfn_ipv6(addr); @@ -121,7 +122,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) if (node->nsec.family == family) switch (family) { case PF_INET: - if (node->nsec.addr.ipv4 == *(__be32 *)addr) + if (node->nsec.addr.ipv4 == *(const __be32 *)addr) return node; break; case PF_INET6: @@ -164,8 +165,9 @@ static void sel_netnode_insert(struct sel_netnode *node) if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { struct sel_netnode *tail; tail = list_entry( - rcu_dereference_protected(sel_netnode_hash[idx].list.prev, - lockdep_is_held(&sel_netnode_lock)), + rcu_dereference_protected( + list_tail_rcu(&sel_netnode_hash[idx].list), + lockdep_is_held(&sel_netnode_lock)), struct sel_netnode, list); list_del_rcu(&tail->list); kfree_rcu(tail, rcu); @@ -186,7 +188,7 @@ static void sel_netnode_insert(struct sel_netnode *node) * failure. * */ -static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) +static int sel_netnode_sid_slow(const void *addr, u16 family, u32 *sid) { int ret; struct sel_netnode *node; @@ -200,19 +202,22 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) return 0; } - new = kzalloc(sizeof(*new), GFP_ATOMIC); + /* If this memory allocation fails still return 0. The SID + * is valid, it just won't be added to the cache. + */ + new = kmalloc(sizeof(*new), GFP_ATOMIC); switch (family) { case PF_INET: - ret = security_node_sid(&selinux_state, PF_INET, + ret = security_node_sid(PF_INET, addr, sizeof(struct in_addr), sid); if (new) - new->nsec.addr.ipv4 = *(__be32 *)addr; + new->nsec.addr.ipv4 = *(const __be32 *)addr; break; case PF_INET6: - ret = security_node_sid(&selinux_state, PF_INET6, + ret = security_node_sid(PF_INET6, addr, sizeof(struct in6_addr), sid); if (new) - new->nsec.addr.ipv6 = *(struct in6_addr *)addr; + new->nsec.addr.ipv6 = *(const struct in6_addr *)addr; break; default: BUG(); @@ -246,13 +251,13 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) * on failure. * */ -int sel_netnode_sid(void *addr, u16 family, u32 *sid) +int sel_netnode_sid(const void *addr, u16 family, u32 *sid) { struct sel_netnode *node; rcu_read_lock(); node = sel_netnode_find(addr, family); - if (node != NULL) { + if (likely(node != NULL)) { *sid = node->nsec.sid; rcu_read_unlock(); return 0; @@ -286,7 +291,7 @@ void sel_netnode_flush(void) spin_unlock_bh(&sel_netnode_lock); } -static __init int sel_netnode_init(void) +int __init sel_netnode_init(void) { int iter; @@ -300,5 +305,3 @@ static __init int sel_netnode_init(void) return 0; } - -__initcall(sel_netnode_init); |
