Skip to content

Commit 9b80c36

Browse files
committed
selinux: always return a secid from the network caches if we find one
Previously if we couldn't find an entry in the cache and we failed to allocate memory for a new cache entry we would fail the network object label lookup; this is obviously not ideal. This patch fixes this so that we return the object label even if we can't cache the object at this point in time due to memory pressure. The GitHub issue tracker is below: * SELinuxProject/selinux-kernel#3 Signed-off-by: Paul Moore <[email protected]>
1 parent f07ea1d commit 9b80c36

File tree

3 files changed

+38
-47
lines changed

3 files changed

+38
-47
lines changed

security/selinux/netif.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ static void sel_netif_destroy(struct sel_netif *netif)
135135
*/
136136
static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
137137
{
138-
int ret;
138+
int ret = 0;
139139
struct sel_netif *netif;
140-
struct sel_netif *new = NULL;
140+
struct sel_netif *new;
141141
struct net_device *dev;
142142

143143
/* NOTE: we always use init's network namespace since we don't
@@ -154,32 +154,27 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
154154
netif = sel_netif_find(ns, ifindex);
155155
if (netif != NULL) {
156156
*sid = netif->nsec.sid;
157-
ret = 0;
158157
goto out;
159158
}
160-
new = kzalloc(sizeof(*new), GFP_ATOMIC);
161-
if (new == NULL) {
162-
ret = -ENOMEM;
163-
goto out;
164-
}
165-
ret = security_netif_sid(&selinux_state, dev->name, &new->nsec.sid);
166-
if (ret != 0)
167-
goto out;
168-
new->nsec.ns = ns;
169-
new->nsec.ifindex = ifindex;
170-
ret = sel_netif_insert(new);
159+
160+
ret = security_netif_sid(&selinux_state, dev->name, sid);
171161
if (ret != 0)
172162
goto out;
173-
*sid = new->nsec.sid;
163+
new = kzalloc(sizeof(*new), GFP_ATOMIC);
164+
if (new) {
165+
new->nsec.ns = ns;
166+
new->nsec.ifindex = ifindex;
167+
new->nsec.sid = *sid;
168+
if (sel_netif_insert(new))
169+
kfree(new);
170+
}
174171

175172
out:
176173
spin_unlock_bh(&sel_netif_lock);
177174
dev_put(dev);
178-
if (unlikely(ret)) {
175+
if (unlikely(ret))
179176
pr_warn("SELinux: failure in %s(), unable to determine network interface label (%d)\n",
180177
__func__, ifindex);
181-
kfree(new);
182-
}
183178
return ret;
184179
}
185180

security/selinux/netnode.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ static void sel_netnode_insert(struct sel_netnode *node)
199199
*/
200200
static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
201201
{
202-
int ret = -ENOMEM;
202+
int ret;
203203
struct sel_netnode *node;
204-
struct sel_netnode *new = NULL;
204+
struct sel_netnode *new;
205205

206206
spin_lock_bh(&sel_netnode_lock);
207207
node = sel_netnode_find(addr, family);
@@ -210,38 +210,36 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
210210
spin_unlock_bh(&sel_netnode_lock);
211211
return 0;
212212
}
213+
213214
new = kzalloc(sizeof(*new), GFP_ATOMIC);
214-
if (new == NULL)
215-
goto out;
216215
switch (family) {
217216
case PF_INET:
218217
ret = security_node_sid(&selinux_state, PF_INET,
219218
addr, sizeof(struct in_addr), sid);
220-
new->nsec.addr.ipv4 = *(__be32 *)addr;
219+
if (new)
220+
new->nsec.addr.ipv4 = *(__be32 *)addr;
221221
break;
222222
case PF_INET6:
223223
ret = security_node_sid(&selinux_state, PF_INET6,
224224
addr, sizeof(struct in6_addr), sid);
225-
new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
225+
if (new)
226+
new->nsec.addr.ipv6 = *(struct in6_addr *)addr;
226227
break;
227228
default:
228229
BUG();
229230
ret = -EINVAL;
230231
}
231-
if (ret != 0)
232-
goto out;
233-
234-
new->nsec.family = family;
235-
new->nsec.sid = *sid;
236-
sel_netnode_insert(new);
232+
if (ret == 0 && new) {
233+
new->nsec.family = family;
234+
new->nsec.sid = *sid;
235+
sel_netnode_insert(new);
236+
} else
237+
kfree(new);
237238

238-
out:
239239
spin_unlock_bh(&sel_netnode_lock);
240-
if (unlikely(ret)) {
240+
if (unlikely(ret))
241241
pr_warn("SELinux: failure in %s(), unable to determine network node label\n",
242242
__func__);
243-
kfree(new);
244-
}
245243
return ret;
246244
}
247245

security/selinux/netport.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ static void sel_netport_insert(struct sel_netport *port)
147147
*/
148148
static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
149149
{
150-
int ret = -ENOMEM;
150+
int ret;
151151
struct sel_netport *port;
152-
struct sel_netport *new = NULL;
152+
struct sel_netport *new;
153153

154154
spin_lock_bh(&sel_netport_lock);
155155
port = sel_netport_find(protocol, pnum);
@@ -158,25 +158,23 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
158158
spin_unlock_bh(&sel_netport_lock);
159159
return 0;
160160
}
161-
new = kzalloc(sizeof(*new), GFP_ATOMIC);
162-
if (new == NULL)
163-
goto out;
161+
164162
ret = security_port_sid(&selinux_state, protocol, pnum, sid);
165163
if (ret != 0)
166164
goto out;
167-
168-
new->psec.port = pnum;
169-
new->psec.protocol = protocol;
170-
new->psec.sid = *sid;
171-
sel_netport_insert(new);
165+
new = kzalloc(sizeof(*new), GFP_ATOMIC);
166+
if (new) {
167+
new->psec.port = pnum;
168+
new->psec.protocol = protocol;
169+
new->psec.sid = *sid;
170+
sel_netport_insert(new);
171+
}
172172

173173
out:
174174
spin_unlock_bh(&sel_netport_lock);
175-
if (unlikely(ret)) {
175+
if (unlikely(ret))
176176
pr_warn("SELinux: failure in %s(), unable to determine network port label\n",
177177
__func__);
178-
kfree(new);
179-
}
180178
return ret;
181179
}
182180

0 commit comments

Comments
 (0)