diff options
Diffstat (limited to 'security/selinux/ss/sidtab.h')
-rw-r--r-- | security/selinux/ss/sidtab.h | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 1f4763141aa1..3311d9f236c0 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -13,16 +13,19 @@ #include <linux/spinlock_types.h> #include <linux/log2.h> +#include <linux/hashtable.h> #include "context.h" -struct sidtab_entry_leaf { +struct sidtab_entry { + u32 sid; struct context context; +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + struct sidtab_str_cache __rcu *cache; +#endif + struct hlist_node list; }; -struct sidtab_node_inner; -struct sidtab_node_leaf; - union sidtab_entry_inner { struct sidtab_node_inner *ptr_inner; struct sidtab_node_leaf *ptr_leaf; @@ -38,7 +41,7 @@ union sidtab_entry_inner { (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)) + (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry)) #define SIDTAB_MAX_BITS 32 #define SIDTAB_MAX U32_MAX @@ -48,7 +51,7 @@ union sidtab_entry_inner { SIDTAB_INNER_SHIFT) struct sidtab_node_leaf { - struct sidtab_entry_leaf entries[SIDTAB_LEAF_ENTRIES]; + struct sidtab_entry entries[SIDTAB_LEAF_ENTRIES]; }; struct sidtab_node_inner { @@ -57,7 +60,7 @@ struct sidtab_node_inner { struct sidtab_isid_entry { int set; - struct context context; + struct sidtab_entry entry; }; struct sidtab_convert_params { @@ -66,7 +69,8 @@ struct sidtab_convert_params { struct sidtab *target; }; -#define SIDTAB_RCACHE_SIZE 3 +#define SIDTAB_HASH_BITS CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS +#define SIDTAB_HASH_BUCKETS (1 << SIDTAB_HASH_BITS) struct sidtab { /* @@ -83,17 +87,38 @@ struct sidtab { struct sidtab_convert_params *convert; spinlock_t lock; - /* reverse lookup cache - access atomically via {READ|WRITE}_ONCE() */ - u32 rcache[SIDTAB_RCACHE_SIZE]; +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 + /* SID -> context string cache */ + u32 cache_free_slots; + struct list_head cache_lru_list; + spinlock_t cache_lock; +#endif /* index == SID - 1 (no entry for SECSID_NULL) */ struct sidtab_isid_entry isids[SECINITSID_NUM]; + + /* Hash table for fast reverse context-to-sid lookups. */ + DECLARE_HASHTABLE(context_to_sid, SIDTAB_HASH_BITS); }; int sidtab_init(struct sidtab *s); 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); +struct sidtab_entry *sidtab_search_entry(struct sidtab *s, u32 sid); +struct sidtab_entry *sidtab_search_entry_force(struct sidtab *s, u32 sid); + +static inline struct context *sidtab_search(struct sidtab *s, u32 sid) +{ + struct sidtab_entry *entry = sidtab_search_entry(s, sid); + + return entry ? &entry->context : NULL; +} + +static inline struct context *sidtab_search_force(struct sidtab *s, u32 sid) +{ + struct sidtab_entry *entry = sidtab_search_entry_force(s, sid); + + return entry ? &entry->context : NULL; +} int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params); @@ -101,6 +126,27 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid); void sidtab_destroy(struct sidtab *s); +int sidtab_hash_stats(struct sidtab *sidtab, char *page); + +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 +void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, + const char *str, u32 str_len); +int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, + char **out, u32 *out_len); +#else +static inline void sidtab_sid2str_put(struct sidtab *s, + struct sidtab_entry *entry, + const char *str, u32 str_len) +{ +} +static inline int sidtab_sid2str_get(struct sidtab *s, + struct sidtab_entry *entry, + char **out, u32 *out_len) +{ + return -ENOENT; +} +#endif /* CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 */ + #endif /* _SS_SIDTAB_H_ */ |