Branch data Line data Source code
1 : : /*
2 : : * Implementation of the kernel access vector cache (AVC).
3 : : *
4 : : * Authors: Stephen Smalley, <sds@epoch.ncsc.mil>
5 : : * James Morris <jmorris@redhat.com>
6 : : *
7 : : * Update: KaiGai, Kohei <kaigai@ak.jp.nec.com>
8 : : * Replaced the avc_lock spinlock by RCU.
9 : : *
10 : : * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
11 : : *
12 : : * This program is free software; you can redistribute it and/or modify
13 : : * it under the terms of the GNU General Public License version 2,
14 : : * as published by the Free Software Foundation.
15 : : */
16 : : #include <linux/types.h>
17 : : #include <linux/stddef.h>
18 : : #include <linux/kernel.h>
19 : : #include <linux/slab.h>
20 : : #include <linux/fs.h>
21 : : #include <linux/dcache.h>
22 : : #include <linux/init.h>
23 : : #include <linux/skbuff.h>
24 : : #include <linux/percpu.h>
25 : : #include <net/sock.h>
26 : : #include <linux/un.h>
27 : : #include <net/af_unix.h>
28 : : #include <linux/ip.h>
29 : : #include <linux/audit.h>
30 : : #include <linux/ipv6.h>
31 : : #include <net/ipv6.h>
32 : : #include "avc.h"
33 : : #include "avc_ss.h"
34 : : #include "classmap.h"
35 : :
36 : : #define AVC_CACHE_SLOTS 512
37 : : #define AVC_DEF_CACHE_THRESHOLD 512
38 : : #define AVC_CACHE_RECLAIM 16
39 : :
40 : : #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
41 : : #define avc_cache_stats_incr(field) this_cpu_inc(avc_cache_stats.field)
42 : : #else
43 : : #define avc_cache_stats_incr(field) do {} while (0)
44 : : #endif
45 : :
46 : : struct avc_entry {
47 : : u32 ssid;
48 : : u32 tsid;
49 : : u16 tclass;
50 : : struct av_decision avd;
51 : : };
52 : :
53 : : struct avc_node {
54 : : struct avc_entry ae;
55 : : struct hlist_node list; /* anchored in avc_cache->slots[i] */
56 : : struct rcu_head rhead;
57 : : };
58 : :
59 : : struct avc_cache {
60 : : struct hlist_head slots[AVC_CACHE_SLOTS]; /* head for avc_node->list */
61 : : spinlock_t slots_lock[AVC_CACHE_SLOTS]; /* lock for writes */
62 : : atomic_t lru_hint; /* LRU hint for reclaim scan */
63 : : atomic_t active_nodes;
64 : : u32 latest_notif; /* latest revocation notification */
65 : : };
66 : :
67 : : struct avc_callback_node {
68 : : int (*callback) (u32 event);
69 : : u32 events;
70 : : struct avc_callback_node *next;
71 : : };
72 : :
73 : : /* Exported via selinufs */
74 : : unsigned int avc_cache_threshold = AVC_DEF_CACHE_THRESHOLD;
75 : :
76 : : #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS
77 : : DEFINE_PER_CPU(struct avc_cache_stats, avc_cache_stats) = { 0 };
78 : : #endif
79 : :
80 : : static struct avc_cache avc_cache;
81 : : static struct avc_callback_node *avc_callbacks;
82 : : static struct kmem_cache *avc_node_cachep;
83 : :
84 : : static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass)
85 : : {
86 : 0 : return (ssid ^ (tsid<<2) ^ (tclass<<4)) & (AVC_CACHE_SLOTS - 1);
87 : : }
88 : :
89 : : /**
90 : : * avc_dump_av - Display an access vector in human-readable form.
91 : : * @tclass: target security class
92 : : * @av: access vector
93 : : */
94 : 0 : static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av)
95 : : {
96 : : const char **perms;
97 : : int i, perm;
98 : :
99 [ # # ]: 0 : if (av == 0) {
100 : 0 : audit_log_format(ab, " null");
101 : 0 : return;
102 : : }
103 : :
104 : 0 : perms = secclass_map[tclass-1].perms;
105 : :
106 : 0 : audit_log_format(ab, " {");
107 : : i = 0;
108 : : perm = 1;
109 [ # # ]: 0 : while (i < (sizeof(av) * 8)) {
110 [ # # ][ # # ]: 0 : if ((perm & av) && perms[i]) {
111 : 0 : audit_log_format(ab, " %s", perms[i]);
112 : 0 : av &= ~perm;
113 : : }
114 : 0 : i++;
115 : 0 : perm <<= 1;
116 : : }
117 : :
118 [ # # ]: 0 : if (av)
119 : 0 : audit_log_format(ab, " 0x%x", av);
120 : :
121 : 0 : audit_log_format(ab, " }");
122 : : }
123 : :
124 : : /**
125 : : * avc_dump_query - Display a SID pair and a class in human-readable form.
126 : : * @ssid: source security identifier
127 : : * @tsid: target security identifier
128 : : * @tclass: target security class
129 : : */
130 : 0 : static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tclass)
131 : : {
132 : : int rc;
133 : : char *scontext;
134 : : u32 scontext_len;
135 : :
136 : 0 : rc = security_sid_to_context(ssid, &scontext, &scontext_len);
137 [ # # ]: 0 : if (rc)
138 : 0 : audit_log_format(ab, "ssid=%d", ssid);
139 : : else {
140 : 0 : audit_log_format(ab, "scontext=%s", scontext);
141 : 0 : kfree(scontext);
142 : : }
143 : :
144 : 0 : rc = security_sid_to_context(tsid, &scontext, &scontext_len);
145 [ # # ]: 0 : if (rc)
146 : 0 : audit_log_format(ab, " tsid=%d", tsid);
147 : : else {
148 : 0 : audit_log_format(ab, " tcontext=%s", scontext);
149 : 0 : kfree(scontext);
150 : : }
151 : :
152 [ # # ]: 0 : BUG_ON(tclass >= ARRAY_SIZE(secclass_map));
153 : 0 : audit_log_format(ab, " tclass=%s", secclass_map[tclass-1].name);
154 : 0 : }
155 : :
156 : : /**
157 : : * avc_init - Initialize the AVC.
158 : : *
159 : : * Initialize the access vector cache.
160 : : */
161 : 0 : void __init avc_init(void)
162 : : {
163 : : int i;
164 : :
165 [ # # ]: 0 : for (i = 0; i < AVC_CACHE_SLOTS; i++) {
166 : 0 : INIT_HLIST_HEAD(&avc_cache.slots[i]);
167 : 0 : spin_lock_init(&avc_cache.slots_lock[i]);
168 : : }
169 : 0 : atomic_set(&avc_cache.active_nodes, 0);
170 : 0 : atomic_set(&avc_cache.lru_hint, 0);
171 : :
172 : 0 : avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
173 : : 0, SLAB_PANIC, NULL);
174 : :
175 : 0 : audit_log(current->audit_context, GFP_KERNEL, AUDIT_KERNEL, "AVC INITIALIZED\n");
176 : 0 : }
177 : :
178 : 0 : int avc_get_hash_stats(char *page)
179 : : {
180 : : int i, chain_len, max_chain_len, slots_used;
181 : : struct avc_node *node;
182 : : struct hlist_head *head;
183 : :
184 : : rcu_read_lock();
185 : :
186 : : slots_used = 0;
187 : : max_chain_len = 0;
188 [ # # ]: 0 : for (i = 0; i < AVC_CACHE_SLOTS; i++) {
189 : 0 : head = &avc_cache.slots[i];
190 [ # # ]: 0 : if (!hlist_empty(head)) {
191 : 0 : slots_used++;
192 : : chain_len = 0;
193 [ # # ][ # # ]: 0 : hlist_for_each_entry_rcu(node, head, list)
[ # # ]
194 : 0 : chain_len++;
195 [ # # ]: 0 : if (chain_len > max_chain_len)
196 : : max_chain_len = chain_len;
197 : : }
198 : : }
199 : :
200 : : rcu_read_unlock();
201 : :
202 : 0 : return scnprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
203 : : "longest chain: %d\n",
204 : : atomic_read(&avc_cache.active_nodes),
205 : : slots_used, AVC_CACHE_SLOTS, max_chain_len);
206 : : }
207 : :
208 : 0 : static void avc_node_free(struct rcu_head *rhead)
209 : : {
210 : 0 : struct avc_node *node = container_of(rhead, struct avc_node, rhead);
211 : 0 : kmem_cache_free(avc_node_cachep, node);
212 : 0 : avc_cache_stats_incr(frees);
213 : 0 : }
214 : :
215 : 0 : static void avc_node_delete(struct avc_node *node)
216 : : {
217 : : hlist_del_rcu(&node->list);
218 : 0 : call_rcu(&node->rhead, avc_node_free);
219 : : atomic_dec(&avc_cache.active_nodes);
220 : 0 : }
221 : :
222 : 0 : static void avc_node_kill(struct avc_node *node)
223 : : {
224 : 0 : kmem_cache_free(avc_node_cachep, node);
225 : 0 : avc_cache_stats_incr(frees);
226 : : atomic_dec(&avc_cache.active_nodes);
227 : 0 : }
228 : :
229 : 0 : static void avc_node_replace(struct avc_node *new, struct avc_node *old)
230 : : {
231 : 0 : hlist_replace_rcu(&old->list, &new->list);
232 : 0 : call_rcu(&old->rhead, avc_node_free);
233 : : atomic_dec(&avc_cache.active_nodes);
234 : 0 : }
235 : :
236 : : static inline int avc_reclaim_node(void)
237 : : {
238 : : struct avc_node *node;
239 : : int hvalue, try, ecx;
240 : : unsigned long flags;
241 : : struct hlist_head *head;
242 : : spinlock_t *lock;
243 : :
244 [ # # ]: 0 : for (try = 0, ecx = 0; try < AVC_CACHE_SLOTS; try++) {
245 : 0 : hvalue = atomic_inc_return(&avc_cache.lru_hint) & (AVC_CACHE_SLOTS - 1);
246 : 0 : head = &avc_cache.slots[hvalue];
247 : 0 : lock = &avc_cache.slots_lock[hvalue];
248 : :
249 [ # # ][ # # ]: 0 : if (!spin_trylock_irqsave(lock, flags))
[ # # ]
250 : 0 : continue;
251 : :
252 : : rcu_read_lock();
253 [ # # ][ # # ]: 0 : hlist_for_each_entry(node, head, list) {
[ # # ]
254 : 0 : avc_node_delete(node);
255 : 0 : avc_cache_stats_incr(reclaims);
256 : 0 : ecx++;
257 [ # # ]: 0 : if (ecx >= AVC_CACHE_RECLAIM) {
258 : : rcu_read_unlock();
259 : : spin_unlock_irqrestore(lock, flags);
260 : : goto out;
261 : : }
262 : : }
263 : : rcu_read_unlock();
264 : : spin_unlock_irqrestore(lock, flags);
265 : : }
266 : : out:
267 : : return ecx;
268 : : }
269 : :
270 : 0 : static struct avc_node *avc_alloc_node(void)
271 : : {
272 : : struct avc_node *node;
273 : :
274 : 0 : node = kmem_cache_zalloc(avc_node_cachep, GFP_ATOMIC|__GFP_NOMEMALLOC);
275 [ # # ]: 0 : if (!node)
276 : : goto out;
277 : :
278 : : INIT_HLIST_NODE(&node->list);
279 : 0 : avc_cache_stats_incr(allocations);
280 : :
281 [ # # ]: 0 : if (atomic_inc_return(&avc_cache.active_nodes) > avc_cache_threshold)
282 : : avc_reclaim_node();
283 : :
284 : : out:
285 : 0 : return node;
286 : : }
287 : :
288 : : static void avc_node_populate(struct avc_node *node, u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
289 : : {
290 : 0 : node->ae.ssid = ssid;
291 : 0 : node->ae.tsid = tsid;
292 : 0 : node->ae.tclass = tclass;
293 : 0 : memcpy(&node->ae.avd, avd, sizeof(node->ae.avd));
294 : : }
295 : :
296 : : static inline struct avc_node *avc_search_node(u32 ssid, u32 tsid, u16 tclass)
297 : : {
298 : : struct avc_node *node, *ret = NULL;
299 : : int hvalue;
300 : : struct hlist_head *head;
301 : :
302 : : hvalue = avc_hash(ssid, tsid, tclass);
303 : 0 : head = &avc_cache.slots[hvalue];
304 [ # # ][ # # ]: 0 : hlist_for_each_entry_rcu(node, head, list) {
[ # # ]
305 [ # # ][ # # ]: 0 : if (ssid == node->ae.ssid &&
306 [ # # ]: 0 : tclass == node->ae.tclass &&
307 : 0 : tsid == node->ae.tsid) {
308 : : ret = node;
309 : : break;
310 : : }
311 : : }
312 : :
313 : : return ret;
314 : : }
315 : :
316 : : /**
317 : : * avc_lookup - Look up an AVC entry.
318 : : * @ssid: source security identifier
319 : : * @tsid: target security identifier
320 : : * @tclass: target security class
321 : : *
322 : : * Look up an AVC entry that is valid for the
323 : : * (@ssid, @tsid), interpreting the permissions
324 : : * based on @tclass. If a valid AVC entry exists,
325 : : * then this function returns the avc_node.
326 : : * Otherwise, this function returns NULL.
327 : : */
328 : 0 : static struct avc_node *avc_lookup(u32 ssid, u32 tsid, u16 tclass)
329 : : {
330 : : struct avc_node *node;
331 : :
332 : 0 : avc_cache_stats_incr(lookups);
333 : : node = avc_search_node(ssid, tsid, tclass);
334 : :
335 [ # # ]: 0 : if (node)
336 : : return node;
337 : :
338 : 0 : avc_cache_stats_incr(misses);
339 : 0 : return NULL;
340 : : }
341 : :
342 : 0 : static int avc_latest_notif_update(int seqno, int is_insert)
343 : : {
344 : : int ret = 0;
345 : : static DEFINE_SPINLOCK(notif_lock);
346 : : unsigned long flag;
347 : :
348 : 0 : spin_lock_irqsave(¬if_lock, flag);
349 [ # # ]: 0 : if (is_insert) {
350 [ # # ]: 0 : if (seqno < avc_cache.latest_notif) {
351 : 0 : printk(KERN_WARNING "SELinux: avc: seqno %d < latest_notif %d\n",
352 : : seqno, avc_cache.latest_notif);
353 : : ret = -EAGAIN;
354 : : }
355 : : } else {
356 [ # # ]: 0 : if (seqno > avc_cache.latest_notif)
357 : 0 : avc_cache.latest_notif = seqno;
358 : : }
359 : : spin_unlock_irqrestore(¬if_lock, flag);
360 : :
361 : 0 : return ret;
362 : : }
363 : :
364 : : /**
365 : : * avc_insert - Insert an AVC entry.
366 : : * @ssid: source security identifier
367 : : * @tsid: target security identifier
368 : : * @tclass: target security class
369 : : * @avd: resulting av decision
370 : : *
371 : : * Insert an AVC entry for the SID pair
372 : : * (@ssid, @tsid) and class @tclass.
373 : : * The access vectors and the sequence number are
374 : : * normally provided by the security server in
375 : : * response to a security_compute_av() call. If the
376 : : * sequence number @avd->seqno is not less than the latest
377 : : * revocation notification, then the function copies
378 : : * the access vectors into a cache entry, returns
379 : : * avc_node inserted. Otherwise, this function returns NULL.
380 : : */
381 : 0 : static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_decision *avd)
382 : : {
383 : : struct avc_node *pos, *node = NULL;
384 : : int hvalue;
385 : : unsigned long flag;
386 : :
387 [ # # ]: 0 : if (avc_latest_notif_update(avd->seqno, 1))
388 : : goto out;
389 : :
390 : 0 : node = avc_alloc_node();
391 [ # # ]: 0 : if (node) {
392 : : struct hlist_head *head;
393 : : spinlock_t *lock;
394 : :
395 : : hvalue = avc_hash(ssid, tsid, tclass);
396 : : avc_node_populate(node, ssid, tsid, tclass, avd);
397 : :
398 : 0 : head = &avc_cache.slots[hvalue];
399 : 0 : lock = &avc_cache.slots_lock[hvalue];
400 : :
401 : 0 : spin_lock_irqsave(lock, flag);
402 [ # # ][ # # ]: 0 : hlist_for_each_entry(pos, head, list) {
[ # # ]
403 [ # # ][ # # ]: 0 : if (pos->ae.ssid == ssid &&
404 [ # # ]: 0 : pos->ae.tsid == tsid &&
405 : 0 : pos->ae.tclass == tclass) {
406 : 0 : avc_node_replace(node, pos);
407 : 0 : goto found;
408 : : }
409 : : }
410 : 0 : hlist_add_head_rcu(&node->list, head);
411 : : found:
412 : : spin_unlock_irqrestore(lock, flag);
413 : : }
414 : : out:
415 : 0 : return node;
416 : : }
417 : :
418 : : /**
419 : : * avc_audit_pre_callback - SELinux specific information
420 : : * will be called by generic audit code
421 : : * @ab: the audit buffer
422 : : * @a: audit_data
423 : : */
424 : 0 : static void avc_audit_pre_callback(struct audit_buffer *ab, void *a)
425 : : {
426 : : struct common_audit_data *ad = a;
427 [ # # ]: 0 : audit_log_format(ab, "avc: %s ",
428 : 0 : ad->selinux_audit_data->denied ? "denied" : "granted");
429 : 0 : avc_dump_av(ab, ad->selinux_audit_data->tclass,
430 : : ad->selinux_audit_data->audited);
431 : 0 : audit_log_format(ab, " for ");
432 : 0 : }
433 : :
434 : : /**
435 : : * avc_audit_post_callback - SELinux specific information
436 : : * will be called by generic audit code
437 : : * @ab: the audit buffer
438 : : * @a: audit_data
439 : : */
440 : 0 : static void avc_audit_post_callback(struct audit_buffer *ab, void *a)
441 : : {
442 : : struct common_audit_data *ad = a;
443 : 0 : audit_log_format(ab, " ");
444 : 0 : avc_dump_query(ab, ad->selinux_audit_data->ssid,
445 : : ad->selinux_audit_data->tsid,
446 : : ad->selinux_audit_data->tclass);
447 : 0 : }
448 : :
449 : : /* This is the slow part of avc audit with big stack footprint */
450 : 0 : noinline int slow_avc_audit(u32 ssid, u32 tsid, u16 tclass,
451 : : u32 requested, u32 audited, u32 denied,
452 : : struct common_audit_data *a,
453 : : unsigned flags)
454 : : {
455 : : struct common_audit_data stack_data;
456 : : struct selinux_audit_data sad;
457 : :
458 [ # # ]: 0 : if (!a) {
459 : : a = &stack_data;
460 : 0 : a->type = LSM_AUDIT_DATA_NONE;
461 : : }
462 : :
463 : : /*
464 : : * When in a RCU walk do the audit on the RCU retry. This is because
465 : : * the collection of the dname in an inode audit message is not RCU
466 : : * safe. Note this may drop some audits when the situation changes
467 : : * during retry. However this is logically just as if the operation
468 : : * happened a little later.
469 : : */
470 [ # # ][ # # ]: 0 : if ((a->type == LSM_AUDIT_DATA_INODE) &&
471 : 0 : (flags & MAY_NOT_BLOCK))
472 : : return -ECHILD;
473 : :
474 : 0 : sad.tclass = tclass;
475 : 0 : sad.requested = requested;
476 : 0 : sad.ssid = ssid;
477 : 0 : sad.tsid = tsid;
478 : 0 : sad.audited = audited;
479 : 0 : sad.denied = denied;
480 : :
481 : 0 : a->selinux_audit_data = &sad;
482 : :
483 : 0 : common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback);
484 : 0 : return 0;
485 : : }
486 : :
487 : : /**
488 : : * avc_add_callback - Register a callback for security events.
489 : : * @callback: callback function
490 : : * @events: security events
491 : : *
492 : : * Register a callback function for events in the set @events.
493 : : * Returns %0 on success or -%ENOMEM if insufficient memory
494 : : * exists to add the callback.
495 : : */
496 : 0 : int __init avc_add_callback(int (*callback)(u32 event), u32 events)
497 : : {
498 : : struct avc_callback_node *c;
499 : : int rc = 0;
500 : :
501 : : c = kmalloc(sizeof(*c), GFP_KERNEL);
502 [ # # ]: 0 : if (!c) {
503 : : rc = -ENOMEM;
504 : : goto out;
505 : : }
506 : :
507 : 0 : c->callback = callback;
508 : 0 : c->events = events;
509 : 0 : c->next = avc_callbacks;
510 : 0 : avc_callbacks = c;
511 : : out:
512 : 0 : return rc;
513 : : }
514 : :
515 : : static inline int avc_sidcmp(u32 x, u32 y)
516 : : {
517 : : return (x == y || x == SECSID_WILD || y == SECSID_WILD);
518 : : }
519 : :
520 : : /**
521 : : * avc_update_node Update an AVC entry
522 : : * @event : Updating event
523 : : * @perms : Permission mask bits
524 : : * @ssid,@tsid,@tclass : identifier of an AVC entry
525 : : * @seqno : sequence number when decision was made
526 : : *
527 : : * if a valid AVC entry doesn't exist,this function returns -ENOENT.
528 : : * if kmalloc() called internal returns NULL, this function returns -ENOMEM.
529 : : * otherwise, this function updates the AVC entry. The original AVC-entry object
530 : : * will release later by RCU.
531 : : */
532 : 0 : static int avc_update_node(u32 event, u32 perms, u32 ssid, u32 tsid, u16 tclass,
533 : : u32 seqno)
534 : : {
535 : : int hvalue, rc = 0;
536 : : unsigned long flag;
537 : : struct avc_node *pos, *node, *orig = NULL;
538 : : struct hlist_head *head;
539 : : spinlock_t *lock;
540 : :
541 : 0 : node = avc_alloc_node();
542 [ # # ]: 0 : if (!node) {
543 : : rc = -ENOMEM;
544 : : goto out;
545 : : }
546 : :
547 : : /* Lock the target slot */
548 : : hvalue = avc_hash(ssid, tsid, tclass);
549 : :
550 : 0 : head = &avc_cache.slots[hvalue];
551 : 0 : lock = &avc_cache.slots_lock[hvalue];
552 : :
553 : 0 : spin_lock_irqsave(lock, flag);
554 : :
555 [ # # ][ # # ]: 0 : hlist_for_each_entry(pos, head, list) {
[ # # ]
556 [ # # ][ # # ]: 0 : if (ssid == pos->ae.ssid &&
557 [ # # ]: 0 : tsid == pos->ae.tsid &&
558 [ # # ]: 0 : tclass == pos->ae.tclass &&
559 : 0 : seqno == pos->ae.avd.seqno){
560 : : orig = pos;
561 : : break;
562 : : }
563 : : }
564 : :
565 [ # # ]: 0 : if (!orig) {
566 : : rc = -ENOENT;
567 : 0 : avc_node_kill(node);
568 : 0 : goto out_unlock;
569 : : }
570 : :
571 : : /*
572 : : * Copy and replace original node.
573 : : */
574 : :
575 : 0 : avc_node_populate(node, ssid, tsid, tclass, &orig->ae.avd);
576 : :
577 [ # # # # : 0 : switch (event) {
# # # ]
578 : : case AVC_CALLBACK_GRANT:
579 : 0 : node->ae.avd.allowed |= perms;
580 : 0 : break;
581 : : case AVC_CALLBACK_TRY_REVOKE:
582 : : case AVC_CALLBACK_REVOKE:
583 : 0 : node->ae.avd.allowed &= ~perms;
584 : 0 : break;
585 : : case AVC_CALLBACK_AUDITALLOW_ENABLE:
586 : 0 : node->ae.avd.auditallow |= perms;
587 : 0 : break;
588 : : case AVC_CALLBACK_AUDITALLOW_DISABLE:
589 : 0 : node->ae.avd.auditallow &= ~perms;
590 : 0 : break;
591 : : case AVC_CALLBACK_AUDITDENY_ENABLE:
592 : 0 : node->ae.avd.auditdeny |= perms;
593 : 0 : break;
594 : : case AVC_CALLBACK_AUDITDENY_DISABLE:
595 : 0 : node->ae.avd.auditdeny &= ~perms;
596 : 0 : break;
597 : : }
598 : 0 : avc_node_replace(node, orig);
599 : : out_unlock:
600 : : spin_unlock_irqrestore(lock, flag);
601 : : out:
602 : 0 : return rc;
603 : : }
604 : :
605 : : /**
606 : : * avc_flush - Flush the cache
607 : : */
608 : 0 : static void avc_flush(void)
609 : : {
610 : : struct hlist_head *head;
611 : : struct avc_node *node;
612 : : spinlock_t *lock;
613 : : unsigned long flag;
614 : : int i;
615 : :
616 [ # # ]: 0 : for (i = 0; i < AVC_CACHE_SLOTS; i++) {
617 : 0 : head = &avc_cache.slots[i];
618 : 0 : lock = &avc_cache.slots_lock[i];
619 : :
620 : 0 : spin_lock_irqsave(lock, flag);
621 : : /*
622 : : * With preemptable RCU, the outer spinlock does not
623 : : * prevent RCU grace periods from ending.
624 : : */
625 : : rcu_read_lock();
626 [ # # ][ # # ]: 0 : hlist_for_each_entry(node, head, list)
[ # # ]
627 : 0 : avc_node_delete(node);
628 : : rcu_read_unlock();
629 : : spin_unlock_irqrestore(lock, flag);
630 : : }
631 : 0 : }
632 : :
633 : : /**
634 : : * avc_ss_reset - Flush the cache and revalidate migrated permissions.
635 : : * @seqno: policy sequence number
636 : : */
637 : 0 : int avc_ss_reset(u32 seqno)
638 : : {
639 : : struct avc_callback_node *c;
640 : : int rc = 0, tmprc;
641 : :
642 : 0 : avc_flush();
643 : :
644 [ # # ]: 0 : for (c = avc_callbacks; c; c = c->next) {
645 [ # # ]: 0 : if (c->events & AVC_CALLBACK_RESET) {
646 : 0 : tmprc = c->callback(AVC_CALLBACK_RESET);
647 : : /* save the first error encountered for the return
648 : : value and continue processing the callbacks */
649 [ # # ]: 0 : if (!rc)
650 : : rc = tmprc;
651 : : }
652 : : }
653 : :
654 : 0 : avc_latest_notif_update(seqno, 0);
655 : 0 : return rc;
656 : : }
657 : :
658 : : /*
659 : : * Slow-path helper function for avc_has_perm_noaudit,
660 : : * when the avc_node lookup fails. We get called with
661 : : * the RCU read lock held, and need to return with it
662 : : * still held, but drop if for the security compute.
663 : : *
664 : : * Don't inline this, since it's the slow-path and just
665 : : * results in a bigger stack frame.
666 : : */
667 : 0 : static noinline struct avc_node *avc_compute_av(u32 ssid, u32 tsid,
668 : : u16 tclass, struct av_decision *avd)
669 : : {
670 : : rcu_read_unlock();
671 : 0 : security_compute_av(ssid, tsid, tclass, avd);
672 : : rcu_read_lock();
673 : 0 : return avc_insert(ssid, tsid, tclass, avd);
674 : : }
675 : :
676 : 0 : static noinline int avc_denied(u32 ssid, u32 tsid,
677 : : u16 tclass, u32 requested,
678 : : unsigned flags,
679 : : struct av_decision *avd)
680 : : {
681 [ # # ]: 0 : if (flags & AVC_STRICT)
682 : : return -EACCES;
683 : :
684 [ # # ][ # # ]: 0 : if (selinux_enforcing && !(avd->flags & AVD_FLAGS_PERMISSIVE))
685 : : return -EACCES;
686 : :
687 : 0 : avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
688 : : tsid, tclass, avd->seqno);
689 : : return 0;
690 : : }
691 : :
692 : :
693 : : /**
694 : : * avc_has_perm_noaudit - Check permissions but perform no auditing.
695 : : * @ssid: source security identifier
696 : : * @tsid: target security identifier
697 : : * @tclass: target security class
698 : : * @requested: requested permissions, interpreted based on @tclass
699 : : * @flags: AVC_STRICT or 0
700 : : * @avd: access vector decisions
701 : : *
702 : : * Check the AVC to determine whether the @requested permissions are granted
703 : : * for the SID pair (@ssid, @tsid), interpreting the permissions
704 : : * based on @tclass, and call the security server on a cache miss to obtain
705 : : * a new decision and add it to the cache. Return a copy of the decisions
706 : : * in @avd. Return %0 if all @requested permissions are granted,
707 : : * -%EACCES if any permissions are denied, or another -errno upon
708 : : * other errors. This function is typically called by avc_has_perm(),
709 : : * but may also be called directly to separate permission checking from
710 : : * auditing, e.g. in cases where a lock must be held for the check but
711 : : * should be released for the auditing.
712 : : */
713 : 0 : inline int avc_has_perm_noaudit(u32 ssid, u32 tsid,
714 : : u16 tclass, u32 requested,
715 : : unsigned flags,
716 : : struct av_decision *avd)
717 : : {
718 : : struct avc_node *node;
719 : : int rc = 0;
720 : : u32 denied;
721 : :
722 [ # # ][ # # ]: 0 : BUG_ON(!requested);
723 : :
724 : : rcu_read_lock();
725 : :
726 : 0 : node = avc_lookup(ssid, tsid, tclass);
727 [ # # # # ]: 0 : if (unlikely(!node)) {
728 : 0 : node = avc_compute_av(ssid, tsid, tclass, avd);
729 : : } else {
730 : 0 : memcpy(avd, &node->ae.avd, sizeof(*avd));
731 : : avd = &node->ae.avd;
732 : : }
733 : :
734 : 0 : denied = requested & ~(avd->allowed);
735 [ # # ][ # # ]: 0 : if (unlikely(denied))
736 : 0 : rc = avc_denied(ssid, tsid, tclass, requested, flags, avd);
737 : :
738 : : rcu_read_unlock();
739 : 0 : return rc;
740 : : }
741 : :
742 : : /**
743 : : * avc_has_perm - Check permissions and perform any appropriate auditing.
744 : : * @ssid: source security identifier
745 : : * @tsid: target security identifier
746 : : * @tclass: target security class
747 : : * @requested: requested permissions, interpreted based on @tclass
748 : : * @auditdata: auxiliary audit data
749 : : *
750 : : * Check the AVC to determine whether the @requested permissions are granted
751 : : * for the SID pair (@ssid, @tsid), interpreting the permissions
752 : : * based on @tclass, and call the security server on a cache miss to obtain
753 : : * a new decision and add it to the cache. Audit the granting or denial of
754 : : * permissions in accordance with the policy. Return %0 if all @requested
755 : : * permissions are granted, -%EACCES if any permissions are denied, or
756 : : * another -errno upon other errors.
757 : : */
758 : 0 : int avc_has_perm(u32 ssid, u32 tsid, u16 tclass,
759 : : u32 requested, struct common_audit_data *auditdata)
760 : : {
761 : : struct av_decision avd;
762 : : int rc, rc2;
763 : :
764 : : rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd);
765 : :
766 : : rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
767 [ # # ]: 0 : if (rc2)
768 : : return rc2;
769 : 0 : return rc;
770 : : }
771 : :
772 : 0 : u32 avc_policy_seqno(void)
773 : : {
774 : 0 : return avc_cache.latest_notif;
775 : : }
776 : :
777 : 0 : void avc_disable(void)
778 : : {
779 : : /*
780 : : * If you are looking at this because you have realized that we are
781 : : * not destroying the avc_node_cachep it might be easy to fix, but
782 : : * I don't know the memory barrier semantics well enough to know. It's
783 : : * possible that some other task dereferenced security_ops when
784 : : * it still pointed to selinux operations. If that is the case it's
785 : : * possible that it is about to use the avc and is about to need the
786 : : * avc_node_cachep. I know I could wrap the security.c security_ops call
787 : : * in an rcu_lock, but seriously, it's not worth it. Instead I just flush
788 : : * the cache and get that memory back.
789 : : */
790 [ # # ]: 0 : if (avc_node_cachep) {
791 : 0 : avc_flush();
792 : : /* kmem_cache_destroy(avc_node_cachep); */
793 : : }
794 : 0 : }
|