Blame view
security/selinux/netif.c
6.76 KB
d2912cb15 treewide: Replace... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 5 6 7 8 9 10 |
/* * Network interface table. * * Network interfaces (devices) do not have a security field, so we * maintain a table associating each interface with a SID. * * Author: James Morris <jmorris@redhat.com> * * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> |
e8bfdb9d0 SELinux: Convert ... |
11 |
* Copyright (C) 2007 Hewlett-Packard Development Company, L.P. |
82c21bfab doc: Update the e... |
12 |
* Paul Moore <paul@paul-moore.com> |
1da177e4c Linux-2.6.12-rc2 |
13 14 15 |
*/ #include <linux/init.h> #include <linux/types.h> |
5a0e3ad6a include cleanup: ... |
16 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
17 18 19 20 21 22 |
#include <linux/stddef.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/notifier.h> #include <linux/netdevice.h> #include <linux/rcupdate.h> |
e9dc86534 [NET]: Make devic... |
23 |
#include <net/net_namespace.h> |
1da177e4c Linux-2.6.12-rc2 |
24 25 26 27 28 29 30 |
#include "security.h" #include "objsec.h" #include "netif.h" #define SEL_NETIF_HASH_SIZE 64 #define SEL_NETIF_HASH_MAX 1024 |
338366cbb SELinux: netif.c ... |
31 |
struct sel_netif { |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 39 40 |
struct list_head list; struct netif_security_struct nsec; struct rcu_head rcu_head; }; static u32 sel_netif_total; static LIST_HEAD(sel_netif_list); static DEFINE_SPINLOCK(sel_netif_lock); static struct list_head sel_netif_hash[SEL_NETIF_HASH_SIZE]; |
e8bfdb9d0 SELinux: Convert ... |
41 42 |
/** * sel_netif_hashfn - Hashing function for the interface table |
cbe0d6e87 selinux: make the... |
43 |
* @ns: the network namespace |
e8bfdb9d0 SELinux: Convert ... |
44 45 46 47 48 49 50 |
* @ifindex: the network interface * * Description: * This is the hashing function for the network interface table, it returns the * bucket number for the given interface. * */ |
cbe0d6e87 selinux: make the... |
51 |
static inline u32 sel_netif_hashfn(const struct net *ns, int ifindex) |
1da177e4c Linux-2.6.12-rc2 |
52 |
{ |
cbe0d6e87 selinux: make the... |
53 |
return (((uintptr_t)ns + ifindex) & (SEL_NETIF_HASH_SIZE - 1)); |
1da177e4c Linux-2.6.12-rc2 |
54 |
} |
e8bfdb9d0 SELinux: Convert ... |
55 56 |
/** * sel_netif_find - Search for an interface record |
cbe0d6e87 selinux: make the... |
57 |
* @ns: the network namespace |
e8bfdb9d0 SELinux: Convert ... |
58 59 60 61 62 63 |
* @ifindex: the network interface * * Description: * Search the network interface table and return the record matching @ifindex. * If an entry can not be found in the table return NULL. * |
1da177e4c Linux-2.6.12-rc2 |
64 |
*/ |
cbe0d6e87 selinux: make the... |
65 66 |
static inline struct sel_netif *sel_netif_find(const struct net *ns, int ifindex) |
1da177e4c Linux-2.6.12-rc2 |
67 |
{ |
cbe0d6e87 selinux: make the... |
68 |
int idx = sel_netif_hashfn(ns, ifindex); |
e8bfdb9d0 SELinux: Convert ... |
69 |
struct sel_netif *netif; |
1da177e4c Linux-2.6.12-rc2 |
70 |
|
e8bfdb9d0 SELinux: Convert ... |
71 |
list_for_each_entry_rcu(netif, &sel_netif_hash[idx], list) |
cbe0d6e87 selinux: make the... |
72 73 |
if (net_eq(netif->nsec.ns, ns) && netif->nsec.ifindex == ifindex) |
1da177e4c Linux-2.6.12-rc2 |
74 |
return netif; |
e8bfdb9d0 SELinux: Convert ... |
75 |
|
1da177e4c Linux-2.6.12-rc2 |
76 77 |
return NULL; } |
e8bfdb9d0 SELinux: Convert ... |
78 79 80 81 82 83 84 85 86 |
/** * sel_netif_insert - Insert a new interface into the table * @netif: the new interface record * * Description: * Add a new interface record to the network interface hash table. Returns * zero on success, negative values on failure. * */ |
1da177e4c Linux-2.6.12-rc2 |
87 88 |
static int sel_netif_insert(struct sel_netif *netif) { |
e8bfdb9d0 SELinux: Convert ... |
89 |
int idx; |
338366cbb SELinux: netif.c ... |
90 |
|
e8bfdb9d0 SELinux: Convert ... |
91 92 |
if (sel_netif_total >= SEL_NETIF_HASH_MAX) return -ENOSPC; |
338366cbb SELinux: netif.c ... |
93 |
|
cbe0d6e87 selinux: make the... |
94 |
idx = sel_netif_hashfn(netif->nsec.ns, netif->nsec.ifindex); |
1da177e4c Linux-2.6.12-rc2 |
95 96 |
list_add_rcu(&netif->list, &sel_netif_hash[idx]); sel_netif_total++; |
e8bfdb9d0 SELinux: Convert ... |
97 98 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
99 |
} |
e8bfdb9d0 SELinux: Convert ... |
100 |
/** |
e8bfdb9d0 SELinux: Convert ... |
101 102 103 104 105 106 107 |
* sel_netif_destroy - Remove an interface record from the table * @netif: the existing interface record * * Description: * Remove an existing interface record from the network interface table. * */ |
1da177e4c Linux-2.6.12-rc2 |
108 109 |
static void sel_netif_destroy(struct sel_netif *netif) { |
1da177e4c Linux-2.6.12-rc2 |
110 111 |
list_del_rcu(&netif->list); sel_netif_total--; |
690273fc7 security,rcu: con... |
112 |
kfree_rcu(netif, rcu_head); |
1da177e4c Linux-2.6.12-rc2 |
113 |
} |
e8bfdb9d0 SELinux: Convert ... |
114 115 |
/** * sel_netif_sid_slow - Lookup the SID of a network interface using the policy |
cbe0d6e87 selinux: make the... |
116 |
* @ns: the network namespace |
e8bfdb9d0 SELinux: Convert ... |
117 118 119 120 121 122 123 124 125 126 |
* @ifindex: the network interface * @sid: interface SID * * Description: * This function determines the SID of a network interface by quering the * security policy. The result is added to the network interface table to * speedup future queries. Returns zero on success, negative values on * failure. * */ |
cbe0d6e87 selinux: make the... |
127 |
static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid) |
1da177e4c Linux-2.6.12-rc2 |
128 |
{ |
9b80c3635 selinux: always r... |
129 |
int ret = 0; |
e8bfdb9d0 SELinux: Convert ... |
130 |
struct sel_netif *netif; |
9b80c3635 selinux: always r... |
131 |
struct sel_netif *new; |
e8bfdb9d0 SELinux: Convert ... |
132 |
struct net_device *dev; |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
e8bfdb9d0 SELinux: Convert ... |
134 135 |
/* NOTE: we always use init's network namespace since we don't * currently support containers */ |
1da177e4c Linux-2.6.12-rc2 |
136 |
|
cbe0d6e87 selinux: make the... |
137 |
dev = dev_get_by_index(ns, ifindex); |
71f1cb05f SELinux: Add warn... |
138 |
if (unlikely(dev == NULL)) { |
0d3a11542 selinux: Cleanup ... |
139 140 141 |
pr_warn("SELinux: failure in %s(), invalid network interface (%d) ", __func__, ifindex); |
e8bfdb9d0 SELinux: Convert ... |
142 |
return -ENOENT; |
71f1cb05f SELinux: Add warn... |
143 |
} |
1da177e4c Linux-2.6.12-rc2 |
144 |
|
1da177e4c Linux-2.6.12-rc2 |
145 |
spin_lock_bh(&sel_netif_lock); |
cbe0d6e87 selinux: make the... |
146 |
netif = sel_netif_find(ns, ifindex); |
e8bfdb9d0 SELinux: Convert ... |
147 148 |
if (netif != NULL) { *sid = netif->nsec.sid; |
1da177e4c Linux-2.6.12-rc2 |
149 150 |
goto out; } |
9b80c3635 selinux: always r... |
151 152 |
ret = security_netif_sid(&selinux_state, dev->name, sid); |
e8bfdb9d0 SELinux: Convert ... |
153 154 |
if (ret != 0) goto out; |
9b80c3635 selinux: always r... |
155 156 157 158 159 160 161 162 |
new = kzalloc(sizeof(*new), GFP_ATOMIC); if (new) { new->nsec.ns = ns; new->nsec.ifindex = ifindex; new->nsec.sid = *sid; if (sel_netif_insert(new)) kfree(new); } |
1da177e4c Linux-2.6.12-rc2 |
163 |
|
1da177e4c Linux-2.6.12-rc2 |
164 |
out: |
e8bfdb9d0 SELinux: Convert ... |
165 166 |
spin_unlock_bh(&sel_netif_lock); dev_put(dev); |
9b80c3635 selinux: always r... |
167 |
if (unlikely(ret)) |
0d3a11542 selinux: Cleanup ... |
168 169 170 |
pr_warn("SELinux: failure in %s(), unable to determine network interface label (%d) ", __func__, ifindex); |
1da177e4c Linux-2.6.12-rc2 |
171 172 |
return ret; } |
e8bfdb9d0 SELinux: Convert ... |
173 174 |
/** * sel_netif_sid - Lookup the SID of a network interface |
cbe0d6e87 selinux: make the... |
175 |
* @ns: the network namespace |
e8bfdb9d0 SELinux: Convert ... |
176 177 178 179 180 181 182 183 184 185 186 |
* @ifindex: the network interface * @sid: interface SID * * Description: * This function determines the SID of a network interface using the fastest * method possible. First the interface table is queried, but if an entry * can't be found then the policy is queried and the result is added to the * table to speedup future queries. Returns zero on success, negative values * on failure. * */ |
cbe0d6e87 selinux: make the... |
187 |
int sel_netif_sid(struct net *ns, int ifindex, u32 *sid) |
1da177e4c Linux-2.6.12-rc2 |
188 |
{ |
1da177e4c Linux-2.6.12-rc2 |
189 190 191 |
struct sel_netif *netif; rcu_read_lock(); |
cbe0d6e87 selinux: make the... |
192 |
netif = sel_netif_find(ns, ifindex); |
e8bfdb9d0 SELinux: Convert ... |
193 194 |
if (likely(netif != NULL)) { *sid = netif->nsec.sid; |
1da177e4c Linux-2.6.12-rc2 |
195 |
rcu_read_unlock(); |
e8bfdb9d0 SELinux: Convert ... |
196 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
197 |
} |
1da177e4c Linux-2.6.12-rc2 |
198 |
rcu_read_unlock(); |
e8bfdb9d0 SELinux: Convert ... |
199 |
|
cbe0d6e87 selinux: make the... |
200 |
return sel_netif_sid_slow(ns, ifindex, sid); |
1da177e4c Linux-2.6.12-rc2 |
201 |
} |
e8bfdb9d0 SELinux: Convert ... |
202 203 |
/** * sel_netif_kill - Remove an entry from the network interface table |
cbe0d6e87 selinux: make the... |
204 |
* @ns: the network namespace |
e8bfdb9d0 SELinux: Convert ... |
205 206 207 208 209 210 211 |
* @ifindex: the network interface * * Description: * This function removes the entry matching @ifindex from the network interface * table if it exists. * */ |
cbe0d6e87 selinux: make the... |
212 |
static void sel_netif_kill(const struct net *ns, int ifindex) |
1da177e4c Linux-2.6.12-rc2 |
213 214 |
{ struct sel_netif *netif; |
618442509 SELinux fixups ne... |
215 |
rcu_read_lock(); |
1da177e4c Linux-2.6.12-rc2 |
216 |
spin_lock_bh(&sel_netif_lock); |
cbe0d6e87 selinux: make the... |
217 |
netif = sel_netif_find(ns, ifindex); |
1da177e4c Linux-2.6.12-rc2 |
218 219 220 |
if (netif) sel_netif_destroy(netif); spin_unlock_bh(&sel_netif_lock); |
618442509 SELinux fixups ne... |
221 |
rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
222 |
} |
e8bfdb9d0 SELinux: Convert ... |
223 224 225 226 227 228 229 |
/** * sel_netif_flush - Flush the entire network interface table * * Description: * Remove all entries from the network interface table. * */ |
615e51fdd selinux: reduce t... |
230 |
void sel_netif_flush(void) |
1da177e4c Linux-2.6.12-rc2 |
231 232 |
{ int idx; |
e8bfdb9d0 SELinux: Convert ... |
233 |
struct sel_netif *netif; |
1da177e4c Linux-2.6.12-rc2 |
234 235 |
spin_lock_bh(&sel_netif_lock); |
e8bfdb9d0 SELinux: Convert ... |
236 |
for (idx = 0; idx < SEL_NETIF_HASH_SIZE; idx++) |
1da177e4c Linux-2.6.12-rc2 |
237 238 |
list_for_each_entry(netif, &sel_netif_hash[idx], list) sel_netif_destroy(netif); |
1da177e4c Linux-2.6.12-rc2 |
239 240 |
spin_unlock_bh(&sel_netif_lock); } |
1da177e4c Linux-2.6.12-rc2 |
241 |
static int sel_netif_netdev_notifier_handler(struct notifier_block *this, |
338366cbb SELinux: netif.c ... |
242 |
unsigned long event, void *ptr) |
1da177e4c Linux-2.6.12-rc2 |
243 |
{ |
351638e7d net: pass info st... |
244 |
struct net_device *dev = netdev_notifier_info_to_dev(ptr); |
1da177e4c Linux-2.6.12-rc2 |
245 246 |
if (event == NETDEV_DOWN) |
cbe0d6e87 selinux: make the... |
247 |
sel_netif_kill(dev_net(dev), dev->ifindex); |
1da177e4c Linux-2.6.12-rc2 |
248 249 250 251 252 253 254 255 256 257 |
return NOTIFY_DONE; } static struct notifier_block sel_netif_netdev_notifier = { .notifier_call = sel_netif_netdev_notifier_handler, }; static __init int sel_netif_init(void) { |
942ba3646 selinux: remove u... |
258 |
int i; |
338366cbb SELinux: netif.c ... |
259 |
|
6c5a682e6 selinux: clean up... |
260 |
if (!selinux_enabled_boot) |
e8bfdb9d0 SELinux: Convert ... |
261 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
262 263 264 265 266 |
for (i = 0; i < SEL_NETIF_HASH_SIZE; i++) INIT_LIST_HEAD(&sel_netif_hash[i]); register_netdevice_notifier(&sel_netif_netdev_notifier); |
338366cbb SELinux: netif.c ... |
267 |
|
942ba3646 selinux: remove u... |
268 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
269 270 271 |
} __initcall(sel_netif_init); |