summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2019-08-01 17:55:06 -0400
committerPaul Moore <paul@paul-moore.com>2019-08-05 16:49:55 -0400
commit9b80c36353ed4cce324af21244a65984db21991b (patch)
tree31d6e45a4b934139eb50d51f76477ee38f5dbb28 /security
parentf07ea1d4eda2574c6b0f99576db61c86ec27ff5b (diff)
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: * https://github.com/SELinuxProject/selinux-kernel/issues/3 Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security')
-rw-r--r--security/selinux/netif.c31
-rw-r--r--security/selinux/netnode.c30
-rw-r--r--security/selinux/netport.c24
3 files changed, 38 insertions, 47 deletions
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index 8c738c189942..cbe6ec246412 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -135,9 +135,9 @@ static void sel_netif_destroy(struct sel_netif *netif)
135 */ 135 */
136static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid) 136static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
137{ 137{
138 int ret; 138 int ret = 0;
139 struct sel_netif *netif; 139 struct sel_netif *netif;
140 struct sel_netif *new = NULL; 140 struct sel_netif *new;
141 struct net_device *dev; 141 struct net_device *dev;
142 142
143 /* 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
@@ -154,32 +154,27 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid)
154 netif = sel_netif_find(ns, ifindex); 154 netif = sel_netif_find(ns, ifindex);
155 if (netif != NULL) { 155 if (netif != NULL) {
156 *sid = netif->nsec.sid; 156 *sid = netif->nsec.sid;
157 ret = 0;
158 goto out; 157 goto out;
159 } 158 }
160 new = kzalloc(sizeof(*new), GFP_ATOMIC); 159
161 if (new == NULL) { 160 ret = security_netif_sid(&selinux_state, dev->name, sid);
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);
171 if (ret != 0) 161 if (ret != 0)
172 goto out; 162 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 }
174 171
175out: 172out:
176 spin_unlock_bh(&sel_netif_lock); 173 spin_unlock_bh(&sel_netif_lock);
177 dev_put(dev); 174 dev_put(dev);
178 if (unlikely(ret)) { 175 if (unlikely(ret))
179 pr_warn("SELinux: failure in %s(), unable to determine network interface label (%d)\n", 176 pr_warn("SELinux: failure in %s(), unable to determine network interface label (%d)\n",
180 __func__, ifindex); 177 __func__, ifindex);
181 kfree(new);
182 }
183 return ret; 178 return ret;
184} 179}
185 180
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index afa0d432436b..df590aaa33f4 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -199,9 +199,9 @@ static void sel_netnode_insert(struct sel_netnode *node)
199 */ 199 */
200static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) 200static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
201{ 201{
202 int ret = -ENOMEM; 202 int ret;
203 struct sel_netnode *node; 203 struct sel_netnode *node;
204 struct sel_netnode *new = NULL; 204 struct sel_netnode *new;
205 205
206 spin_lock_bh(&sel_netnode_lock); 206 spin_lock_bh(&sel_netnode_lock);
207 node = sel_netnode_find(addr, family); 207 node = sel_netnode_find(addr, family);
@@ -210,38 +210,36 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
210 spin_unlock_bh(&sel_netnode_lock); 210 spin_unlock_bh(&sel_netnode_lock);
211 return 0; 211 return 0;
212 } 212 }
213
213 new = kzalloc(sizeof(*new), GFP_ATOMIC); 214 new = kzalloc(sizeof(*new), GFP_ATOMIC);
214 if (new == NULL)
215 goto out;
216 switch (family) { 215 switch (family) {
217 case PF_INET: 216 case PF_INET:
218 ret = security_node_sid(&selinux_state, PF_INET, 217 ret = security_node_sid(&selinux_state, PF_INET,
219 addr, sizeof(struct in_addr), sid); 218 addr, sizeof(struct in_addr), sid);
220 new->nsec.addr.ipv4 = *(__be32 *)addr; 219 if (new)
220 new->nsec.addr.ipv4 = *(__be32 *)addr;
221 break; 221 break;
222 case PF_INET6: 222 case PF_INET6:
223 ret = security_node_sid(&selinux_state, PF_INET6, 223 ret = security_node_sid(&selinux_state, PF_INET6,
224 addr, sizeof(struct in6_addr), sid); 224 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;
226 break; 227 break;
227 default: 228 default:
228 BUG(); 229 BUG();
229 ret = -EINVAL; 230 ret = -EINVAL;
230 } 231 }
231 if (ret != 0) 232 if (ret == 0 && new) {
232 goto out; 233 new->nsec.family = family;
233 234 new->nsec.sid = *sid;
234 new->nsec.family = family; 235 sel_netnode_insert(new);
235 new->nsec.sid = *sid; 236 } else
236 sel_netnode_insert(new); 237 kfree(new);
237 238
238out:
239 spin_unlock_bh(&sel_netnode_lock); 239 spin_unlock_bh(&sel_netnode_lock);
240 if (unlikely(ret)) { 240 if (unlikely(ret))
241 pr_warn("SELinux: failure in %s(), unable to determine network node label\n", 241 pr_warn("SELinux: failure in %s(), unable to determine network node label\n",
242 __func__); 242 __func__);
243 kfree(new);
244 }
245 return ret; 243 return ret;
246} 244}
247 245
diff --git a/security/selinux/netport.c b/security/selinux/netport.c
index 7a141cadbffc..936d630a938d 100644
--- a/security/selinux/netport.c
+++ b/security/selinux/netport.c
@@ -147,9 +147,9 @@ static void sel_netport_insert(struct sel_netport *port)
147 */ 147 */
148static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) 148static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
149{ 149{
150 int ret = -ENOMEM; 150 int ret;
151 struct sel_netport *port; 151 struct sel_netport *port;
152 struct sel_netport *new = NULL; 152 struct sel_netport *new;
153 153
154 spin_lock_bh(&sel_netport_lock); 154 spin_lock_bh(&sel_netport_lock);
155 port = sel_netport_find(protocol, pnum); 155 port = sel_netport_find(protocol, pnum);
@@ -158,25 +158,23 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid)
158 spin_unlock_bh(&sel_netport_lock); 158 spin_unlock_bh(&sel_netport_lock);
159 return 0; 159 return 0;
160 } 160 }
161 new = kzalloc(sizeof(*new), GFP_ATOMIC); 161
162 if (new == NULL)
163 goto out;
164 ret = security_port_sid(&selinux_state, protocol, pnum, sid); 162 ret = security_port_sid(&selinux_state, protocol, pnum, sid);
165 if (ret != 0) 163 if (ret != 0)
166 goto out; 164 goto out;
167 165 new = kzalloc(sizeof(*new), GFP_ATOMIC);
168 new->psec.port = pnum; 166 if (new) {
169 new->psec.protocol = protocol; 167 new->psec.port = pnum;
170 new->psec.sid = *sid; 168 new->psec.protocol = protocol;
171 sel_netport_insert(new); 169 new->psec.sid = *sid;
170 sel_netport_insert(new);
171 }
172 172
173out: 173out:
174 spin_unlock_bh(&sel_netport_lock); 174 spin_unlock_bh(&sel_netport_lock);
175 if (unlikely(ret)) { 175 if (unlikely(ret))
176 pr_warn("SELinux: failure in %s(), unable to determine network port label\n", 176 pr_warn("SELinux: failure in %s(), unable to determine network port label\n",
177 __func__); 177 __func__);
178 kfree(new);
179 }
180 return ret; 178 return ret;
181} 179}
182 180