aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/netif.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2015-02-10 14:35:36 -0500
commit4ba24fef3eb3b142197135223b90ced2f319cd53 (patch)
treea20c125b27740ec7b4c761b11d801108e1b316b2 /security/selinux/netif.c
parent47c1ffb2b6b630894e9a16442611c056ab21c057 (diff)
parent98a4a59ee31a12105a2b84f5b8b515ac2cb208ef (diff)
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.20.
Diffstat (limited to 'security/selinux/netif.c')
-rw-r--r--security/selinux/netif.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 50ce177d71a0..e607b4473ef6 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -45,6 +45,7 @@ static struct list_head sel_netif_hash[SEL_NETIF_HASH_SIZE];
45 45
46/** 46/**
47 * sel_netif_hashfn - Hashing function for the interface table 47 * sel_netif_hashfn - Hashing function for the interface table
48 * @ns: the network namespace
48 * @ifindex: the network interface 49 * @ifindex: the network interface
49 * 50 *
50 * Description: 51 * Description:
@@ -52,13 +53,14 @@ static struct list_head sel_netif_hash[SEL_NETIF_HASH_SIZE];
52 * bucket number for the given interface. 53 * bucket number for the given interface.
53 * 54 *
54 */ 55 */
55static inline u32 sel_netif_hashfn(int ifindex) 56static inline u32 sel_netif_hashfn(const struct net *ns, int ifindex)
56{ 57{
57 return (ifindex & (SEL_NETIF_HASH_SIZE - 1)); 58 return (((uintptr_t)ns + ifindex) & (SEL_NETIF_HASH_SIZE - 1));
58} 59}
59 60
60/** 61/**
61 * sel_netif_find - Search for an interface record 62 * sel_netif_find - Search for an interface record
63 * @ns: the network namespace
62 * @ifindex: the network interface 64 * @ifindex: the network interface
63 * 65 *
64 * Description: 66 * Description:
@@ -66,15 +68,15 @@ static inline u32 sel_netif_hashfn(int ifindex)
66 * If an entry can not be found in the table return NULL. 68 * If an entry can not be found in the table return NULL.
67 * 69 *
68 */ 70 */
69static inline struct sel_netif *sel_netif_find(int ifindex) 71static inline struct sel_netif *sel_netif_find(const struct net *ns,
72 int ifindex)
70{ 73{
71 int idx = sel_netif_hashfn(ifindex); 74 int idx = sel_netif_hashfn(ns, ifindex);
72 struct sel_netif *netif; 75 struct sel_netif *netif;
73 76
74 list_for_each_entry_rcu(netif, &sel_netif_hash[idx], list) 77 list_for_each_entry_rcu(netif, &sel_netif_hash[idx], list)
75 /* all of the devices should normally fit in the hash, so we 78 if (net_eq(netif->nsec.ns, ns) &&
76 * optimize for that case */ 79 netif->nsec.ifindex == ifindex)
77 if (likely(netif->nsec.ifindex == ifindex))
78 return netif; 80 return netif;
79 81
80 return NULL; 82 return NULL;
@@ -96,7 +98,7 @@ static int sel_netif_insert(struct sel_netif *netif)
96 if (sel_netif_total >= SEL_NETIF_HASH_MAX) 98 if (sel_netif_total >= SEL_NETIF_HASH_MAX)
97 return -ENOSPC; 99 return -ENOSPC;
98 100
99 idx = sel_netif_hashfn(netif->nsec.ifindex); 101 idx = sel_netif_hashfn(netif->nsec.ns, netif->nsec.ifindex);
100 list_add_rcu(&netif->list, &sel_netif_hash[idx]); 102 list_add_rcu(&netif->list, &sel_netif_hash[idx]);
101 sel_netif_total++; 103 sel_netif_total++;
102 104
@@ -120,6 +122,7 @@ static void sel_netif_destroy(struct sel_netif *netif)
120 122
121/** 123/**
122 * sel_netif_sid_slow - Lookup the SID of a network interface using the policy 124 * sel_netif_sid_slow - Lookup the SID of a network interface using the policy
125 * @ns: the network namespace
123 * @ifindex: the network interface 126 * @ifindex: the network interface
124 * @sid: interface SID 127 * @sid: interface SID
125 * 128 *
@@ -130,7 +133,7 @@ static void sel_netif_destroy(struct sel_netif *netif)
130 * failure. 133 * failure.
131 * 134 *
132 */ 135 */
133static int sel_netif_sid_slow(int ifindex, u32 *sid) 136static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
134{ 137{
135 int ret; 138 int ret;
136 struct sel_netif *netif; 139 struct sel_netif *netif;
@@ -140,7 +143,7 @@ static int sel_netif_sid_slow(int ifindex, u32 *sid)
140 /* NOTE: we always use init's network namespace since we don't 143 /* NOTE: we always use init's network namespace since we don't
141 * currently support containers */ 144 * currently support containers */
142 145
143 dev = dev_get_by_index(&init_net, ifindex); 146 dev = dev_get_by_index(ns, ifindex);
144 if (unlikely(dev == NULL)) { 147 if (unlikely(dev == NULL)) {
145 printk(KERN_WARNING 148 printk(KERN_WARNING
146 "SELinux: failure in sel_netif_sid_slow()," 149 "SELinux: failure in sel_netif_sid_slow(),"
@@ -149,7 +152,7 @@ static int sel_netif_sid_slow(int ifindex, u32 *sid)
149 } 152 }
150 153
151 spin_lock_bh(&sel_netif_lock); 154 spin_lock_bh(&sel_netif_lock);
152 netif = sel_netif_find(ifindex); 155 netif = sel_netif_find(ns, ifindex);
153 if (netif != NULL) { 156 if (netif != NULL) {
154 *sid = netif->nsec.sid; 157 *sid = netif->nsec.sid;
155 ret = 0; 158 ret = 0;
@@ -163,6 +166,7 @@ static int sel_netif_sid_slow(int ifindex, u32 *sid)
163 ret = security_netif_sid(dev->name, &new->nsec.sid); 166 ret = security_netif_sid(dev->name, &new->nsec.sid);
164 if (ret != 0) 167 if (ret != 0)
165 goto out; 168 goto out;
169 new->nsec.ns = ns;
166 new->nsec.ifindex = ifindex; 170 new->nsec.ifindex = ifindex;
167 ret = sel_netif_insert(new); 171 ret = sel_netif_insert(new);
168 if (ret != 0) 172 if (ret != 0)
@@ -184,6 +188,7 @@ out:
184 188
185/** 189/**
186 * sel_netif_sid - Lookup the SID of a network interface 190 * sel_netif_sid - Lookup the SID of a network interface
191 * @ns: the network namespace
187 * @ifindex: the network interface 192 * @ifindex: the network interface
188 * @sid: interface SID 193 * @sid: interface SID
189 * 194 *
@@ -195,12 +200,12 @@ out:
195 * on failure. 200 * on failure.
196 * 201 *
197 */ 202 */
198int sel_netif_sid(int ifindex, u32 *sid) 203int sel_netif_sid(struct net *ns, int ifindex, u32 *sid)
199{ 204{
200 struct sel_netif *netif; 205 struct sel_netif *netif;
201 206
202 rcu_read_lock(); 207 rcu_read_lock();
203 netif = sel_netif_find(ifindex); 208 netif = sel_netif_find(ns, ifindex);
204 if (likely(netif != NULL)) { 209 if (likely(netif != NULL)) {
205 *sid = netif->nsec.sid; 210 *sid = netif->nsec.sid;
206 rcu_read_unlock(); 211 rcu_read_unlock();
@@ -208,11 +213,12 @@ int sel_netif_sid(int ifindex, u32 *sid)
208 } 213 }
209 rcu_read_unlock(); 214 rcu_read_unlock();
210 215
211 return sel_netif_sid_slow(ifindex, sid); 216 return sel_netif_sid_slow(ns, ifindex, sid);
212} 217}
213 218
214/** 219/**
215 * sel_netif_kill - Remove an entry from the network interface table 220 * sel_netif_kill - Remove an entry from the network interface table
221 * @ns: the network namespace
216 * @ifindex: the network interface 222 * @ifindex: the network interface
217 * 223 *
218 * Description: 224 * Description:
@@ -220,13 +226,13 @@ int sel_netif_sid(int ifindex, u32 *sid)
220 * table if it exists. 226 * table if it exists.
221 * 227 *
222 */ 228 */
223static void sel_netif_kill(int ifindex) 229static void sel_netif_kill(const struct net *ns, int ifindex)
224{ 230{
225 struct sel_netif *netif; 231 struct sel_netif *netif;
226 232
227 rcu_read_lock(); 233 rcu_read_lock();
228 spin_lock_bh(&sel_netif_lock); 234 spin_lock_bh(&sel_netif_lock);
229 netif = sel_netif_find(ifindex); 235 netif = sel_netif_find(ns, ifindex);
230 if (netif) 236 if (netif)
231 sel_netif_destroy(netif); 237 sel_netif_destroy(netif);
232 spin_unlock_bh(&sel_netif_lock); 238 spin_unlock_bh(&sel_netif_lock);
@@ -257,11 +263,8 @@ static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
257{ 263{
258 struct net_device *dev = netdev_notifier_info_to_dev(ptr); 264 struct net_device *dev = netdev_notifier_info_to_dev(ptr);
259 265
260 if (dev_net(dev) != &init_net)
261 return NOTIFY_DONE;
262
263 if (event == NETDEV_DOWN) 266 if (event == NETDEV_DOWN)
264 sel_netif_kill(dev->ifindex); 267 sel_netif_kill(dev_net(dev), dev->ifindex);
265 268
266 return NOTIFY_DONE; 269 return NOTIFY_DONE;
267} 270}