Lines Matching +full:keep +full:- +full:a +full:- +full:live
1 // SPDX-License-Identifier: GPL-2.0
33 #define sid_to_index(sid) ((sid) - (SECINITSID_NUM + 1))
39 memset(s->roots, 0, sizeof(s->roots));
42 s->isids[i].set = 0;
44 s->frozen = false;
45 s->count = 0;
46 s->convert = NULL;
47 hash_init(s->context_to_sid);
49 spin_lock_init(&s->lock);
52 s->cache_free_slots = CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE;
53 INIT_LIST_HEAD(&s->cache_lru_list);
54 spin_lock_init(&s->cache_lock);
66 hash_for_each_possible_rcu(s->context_to_sid, entry, list, hash) {
67 if (entry->hash != hash)
69 if (context_equal(&entry->context, context)) {
70 sid = entry->sid;
85 return -EINVAL;
87 isid = &s->isids[sid - 1];
89 rc = context_cpy(&isid->entry.context, context);
94 isid->entry.cache = NULL;
96 isid->set = 1;
107 isid->entry.sid = sid;
108 isid->entry.hash = hash;
109 hash_add(s->context_to_sid, &isid->entry.list, hash);
126 hash_for_each_rcu(sidtab->context_to_sid, i, entry, list) {
167 if (!s->roots[0].ptr_leaf) {
168 s->roots[0].ptr_leaf =
170 if (!s->roots[0].ptr_leaf)
171 return -ENOMEM;
174 if (!s->roots[l].ptr_inner) {
175 s->roots[l].ptr_inner =
177 if (!s->roots[l].ptr_inner)
178 return -ENOMEM;
179 s->roots[l].ptr_inner->entries[0] = s->roots[l - 1];
199 entry = &s->roots[level];
201 capacity_shift -= SIDTAB_INNER_SHIFT;
202 --level;
204 entry = &entry->ptr_inner->entries[leaf_index >> capacity_shift];
205 leaf_index &= ((u32)1 << capacity_shift) - 1;
207 if (!entry->ptr_inner) {
209 entry->ptr_inner = kzalloc(
211 if (!entry->ptr_inner)
215 if (!entry->ptr_leaf) {
217 entry->ptr_leaf =
219 if (!entry->ptr_leaf)
222 return &entry->ptr_leaf->entries[index % SIDTAB_LEAF_ENTRIES];
228 u32 count = smp_load_acquire(&s->count);
238 return s->isids[sid - 1].set ? &s->isids[sid - 1].entry : NULL;
251 if (entry && (!entry->context.len || force))
280 /* lock-free search failed: lock, re-search, and insert if not found */
281 spin_lock_irqsave(&s->lock, flags);
288 if (unlikely(s->frozen)) {
290 * This sidtab is now frozen - tell the caller to abort and
293 rc = -ESTALE;
297 count = s->count;
300 rc = -EOVERFLOW;
305 rc = -ENOMEM;
310 dst->sid = index_to_sid(count);
311 dst->hash = hash;
313 rc = context_cpy(&dst->context, context);
318 * if we are building a new sidtab, we need to convert the context
321 convert = s->convert;
323 struct sidtab *target = convert->target;
325 rc = -ENOMEM;
328 context_destroy(&dst->context);
332 rc = services_convert_context(convert->args, context,
333 &dst_convert->context,
336 context_destroy(&dst->context);
339 dst_convert->sid = index_to_sid(count);
340 dst_convert->hash = context_compute_hash(&dst_convert->context);
341 target->count = count + 1;
343 hash_add_rcu(target->context_to_sid, &dst_convert->list,
344 dst_convert->hash);
347 if (context->len)
349 context->str);
354 smp_store_release(&s->count, count + 1);
355 hash_add_rcu(s->context_to_sid, &dst->list, dst->hash);
359 spin_unlock_irqrestore(&s->lock, flags);
370 entry->sid = index_to_sid(i);
371 entry->hash = context_compute_hash(&entry->context);
373 hash_add_rcu(s->context_to_sid, &entry->list, entry->hash);
386 if (!edst->ptr_inner) {
387 edst->ptr_inner =
389 if (!edst->ptr_inner)
390 return -ENOMEM;
394 rc = sidtab_convert_tree(&edst->ptr_inner->entries[i],
395 &esrc->ptr_inner->entries[i],
396 pos, count, level - 1,
403 if (!edst->ptr_leaf) {
404 edst->ptr_leaf =
406 if (!edst->ptr_leaf)
407 return -ENOMEM;
412 convert->args,
413 &esrc->ptr_leaf->entries[i].context,
414 &edst->ptr_leaf->entries[i].context,
432 spin_lock_irqsave(&s->lock, flags);
435 if (s->convert) {
436 spin_unlock_irqrestore(&s->lock, flags);
437 return -EBUSY;
440 count = s->count;
444 * live convert)
446 rc = sidtab_do_lookup(params->target, count - 1, 1) ? 0 : -ENOMEM;
448 spin_unlock_irqrestore(&s->lock, flags);
453 params->target->count = count;
455 /* enable live convert of new entries */
456 s->convert = params;
459 spin_unlock_irqrestore(&s->lock, flags);
463 /* convert all entries not covered by live convert */
465 rc = sidtab_convert_tree(¶ms->target->roots[level],
466 &s->roots[level], &pos, count, level, params);
468 /* we need to keep the old table - disable live convert */
469 spin_lock_irqsave(&s->lock, flags);
470 s->convert = NULL;
471 spin_unlock_irqrestore(&s->lock, flags);
476 * so we must re-acquire the lock here.
478 spin_lock_irqsave(&s->lock, flags);
479 sidtab_convert_hashtable(params->target, count);
480 spin_unlock_irqrestore(&s->lock, flags);
489 /* cancelling policy load - disable live convert of sidtab */
490 spin_lock_irqsave(&s->lock, flags);
491 s->convert = NULL;
492 spin_unlock_irqrestore(&s->lock, flags);
496 __acquires(&s->lock)
498 spin_lock_irqsave(&s->lock, *flags);
499 s->frozen = true;
500 s->convert = NULL;
503 __releases(&s->lock)
505 spin_unlock_irqrestore(&s->lock, *flags);
510 context_destroy(&entry->context);
512 kfree(rcu_dereference_raw(entry->cache));
527 sidtab_destroy_tree(node->entries[i], level - 1);
536 sidtab_destroy_entry(&node->entries[i]);
546 if (s->isids[i].set)
547 sidtab_destroy_entry(&s->isids[i].entry);
550 while (level && !s->roots[level].ptr_inner)
551 --level;
553 sidtab_destroy_tree(s->roots[level], level);
570 if (entry->context.len)
573 spin_lock_irqsave(&s->cache_lock, flags);
575 cache = rcu_dereference_protected(entry->cache,
576 lockdep_is_held(&s->cache_lock));
578 /* entry in cache - just bump to the head of LRU list */
579 list_move(&cache->lru_member, &s->cache_lru_list);
587 if (s->cache_free_slots == 0) {
588 /* pop a cache entry from the tail and free it */
589 victim = container_of(s->cache_lru_list.prev,
591 list_del(&victim->lru_member);
592 rcu_assign_pointer(victim->parent->cache, NULL);
594 s->cache_free_slots--;
596 cache->parent = entry;
597 cache->len = str_len;
598 memcpy(cache->str, str, str_len);
599 list_add(&cache->lru_member, &s->cache_lru_list);
601 rcu_assign_pointer(entry->cache, cache);
604 spin_unlock_irqrestore(&s->cache_lock, flags);
614 if (entry->context.len)
615 return -ENOENT; /* do not cache invalid contexts */
619 cache = rcu_dereference(entry->cache);
621 rc = -ENOENT;
623 *out_len = cache->len;
625 *out = kmemdup(cache->str, cache->len, GFP_ATOMIC);
627 rc = -ENOMEM;