diff options
Diffstat (limited to 'security/selinux/ss/sidtab.h')
-rw-r--r-- | security/selinux/ss/sidtab.h | 96 |
1 files changed, 68 insertions, 28 deletions
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index a1a1d2617b6f..bbd5c0d1f3bd 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -1,56 +1,96 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * A security identifier table (sidtab) is a hash table + * A security identifier table (sidtab) is a lookup table * of security context structures indexed by SID value. * - * Author : Stephen Smalley, <sds@tycho.nsa.gov> + * Original author: Stephen Smalley, <sds@tycho.nsa.gov> + * Author: Ondrej Mosnacek, <omosnacek@gmail.com> + * + * Copyright (C) 2018 Red Hat, Inc. */ #ifndef _SS_SIDTAB_H_ #define _SS_SIDTAB_H_ +#include <linux/spinlock_types.h> +#include <linux/log2.h> + #include "context.h" -struct sidtab_node { - u32 sid; /* security identifier */ - struct context context; /* security context structure */ - struct sidtab_node *next; +struct sidtab_entry_leaf { + struct context context; +}; + +struct sidtab_node_inner; +struct sidtab_node_leaf; + +union sidtab_entry_inner { + struct sidtab_node_inner *ptr_inner; + struct sidtab_node_leaf *ptr_leaf; +}; + +/* align node size to page boundary */ +#define SIDTAB_NODE_ALLOC_SHIFT PAGE_SHIFT +#define SIDTAB_NODE_ALLOC_SIZE PAGE_SIZE + +#define size_to_shift(size) ((size) == 1 ? 1 : (const_ilog2((size) - 1) + 1)) + +#define SIDTAB_INNER_SHIFT \ + (SIDTAB_NODE_ALLOC_SHIFT - size_to_shift(sizeof(union sidtab_entry_inner))) +#define SIDTAB_INNER_ENTRIES ((size_t)1 << SIDTAB_INNER_SHIFT) +#define SIDTAB_LEAF_ENTRIES \ + (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry_leaf)) + +#define SIDTAB_MAX_BITS 31 /* limited to INT_MAX due to atomic_t range */ +#define SIDTAB_MAX (((u32)1 << SIDTAB_MAX_BITS) - 1) +/* ensure enough tree levels for SIDTAB_MAX entries */ +#define SIDTAB_MAX_LEVEL \ + DIV_ROUND_UP(SIDTAB_MAX_BITS - size_to_shift(SIDTAB_LEAF_ENTRIES), \ + SIDTAB_INNER_SHIFT) + +struct sidtab_node_leaf { + struct sidtab_entry_leaf entries[SIDTAB_LEAF_ENTRIES]; }; -#define SIDTAB_HASH_BITS 7 -#define SIDTAB_HASH_BUCKETS (1 << SIDTAB_HASH_BITS) -#define SIDTAB_HASH_MASK (SIDTAB_HASH_BUCKETS-1) +struct sidtab_node_inner { + union sidtab_entry_inner entries[SIDTAB_INNER_ENTRIES]; +}; -#define SIDTAB_SIZE SIDTAB_HASH_BUCKETS +struct sidtab_isid_entry { + int set; + struct context context; +}; + +struct sidtab_convert_params { + int (*func)(struct context *oldc, struct context *newc, void *args); + void *args; + struct sidtab *target; +}; + +#define SIDTAB_RCACHE_SIZE 3 struct sidtab { - struct sidtab_node **htable; - unsigned int nel; /* number of elements */ - unsigned int next_sid; /* next SID to allocate */ - unsigned char shutdown; -#define SIDTAB_CACHE_LEN 3 - struct sidtab_node *cache[SIDTAB_CACHE_LEN]; + union sidtab_entry_inner roots[SIDTAB_MAX_LEVEL + 1]; + atomic_t count; + struct sidtab_convert_params *convert; spinlock_t lock; + + /* reverse lookup cache */ + atomic_t rcache[SIDTAB_RCACHE_SIZE]; + + /* index == SID - 1 (no entry for SECSID_NULL) */ + struct sidtab_isid_entry isids[SECINITSID_NUM]; }; int sidtab_init(struct sidtab *s); -int sidtab_insert(struct sidtab *s, u32 sid, struct context *context); +int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context); struct context *sidtab_search(struct sidtab *s, u32 sid); struct context *sidtab_search_force(struct sidtab *s, u32 sid); -int sidtab_map(struct sidtab *s, - int (*apply) (u32 sid, - struct context *context, - void *args), - void *args); +int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params); -int sidtab_context_to_sid(struct sidtab *s, - struct context *context, - u32 *sid); +int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid); -void sidtab_hash_eval(struct sidtab *h, char *tag); void sidtab_destroy(struct sidtab *s); -void sidtab_set(struct sidtab *dst, struct sidtab *src); -void sidtab_shutdown(struct sidtab *s); #endif /* _SS_SIDTAB_H_ */ |