| .. | .. |
|---|
| 17 | 17 | |
|---|
| 18 | 18 | #include "context.h" |
|---|
| 19 | 19 | |
|---|
| 20 | | -struct sidtab_entry_leaf { |
|---|
| 20 | +struct sidtab_entry { |
|---|
| 21 | 21 | u32 sid; |
|---|
| 22 | + u32 hash; |
|---|
| 22 | 23 | struct context context; |
|---|
| 24 | +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 |
|---|
| 25 | + struct sidtab_str_cache __rcu *cache; |
|---|
| 26 | +#endif |
|---|
| 23 | 27 | struct hlist_node list; |
|---|
| 24 | 28 | }; |
|---|
| 25 | | - |
|---|
| 26 | | -struct sidtab_node_inner; |
|---|
| 27 | | -struct sidtab_node_leaf; |
|---|
| 28 | 29 | |
|---|
| 29 | 30 | union sidtab_entry_inner { |
|---|
| 30 | 31 | struct sidtab_node_inner *ptr_inner; |
|---|
| .. | .. |
|---|
| 41 | 42 | (SIDTAB_NODE_ALLOC_SHIFT - size_to_shift(sizeof(union sidtab_entry_inner))) |
|---|
| 42 | 43 | #define SIDTAB_INNER_ENTRIES ((size_t)1 << SIDTAB_INNER_SHIFT) |
|---|
| 43 | 44 | #define SIDTAB_LEAF_ENTRIES \ |
|---|
| 44 | | - (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry_leaf)) |
|---|
| 45 | + (SIDTAB_NODE_ALLOC_SIZE / sizeof(struct sidtab_entry)) |
|---|
| 45 | 46 | |
|---|
| 46 | 47 | #define SIDTAB_MAX_BITS 32 |
|---|
| 47 | 48 | #define SIDTAB_MAX U32_MAX |
|---|
| .. | .. |
|---|
| 51 | 52 | SIDTAB_INNER_SHIFT) |
|---|
| 52 | 53 | |
|---|
| 53 | 54 | struct sidtab_node_leaf { |
|---|
| 54 | | - struct sidtab_entry_leaf entries[SIDTAB_LEAF_ENTRIES]; |
|---|
| 55 | + struct sidtab_entry entries[SIDTAB_LEAF_ENTRIES]; |
|---|
| 55 | 56 | }; |
|---|
| 56 | 57 | |
|---|
| 57 | 58 | struct sidtab_node_inner { |
|---|
| .. | .. |
|---|
| 60 | 61 | |
|---|
| 61 | 62 | struct sidtab_isid_entry { |
|---|
| 62 | 63 | int set; |
|---|
| 63 | | - struct sidtab_entry_leaf leaf; |
|---|
| 64 | + struct sidtab_entry entry; |
|---|
| 64 | 65 | }; |
|---|
| 65 | 66 | |
|---|
| 66 | 67 | struct sidtab_convert_params { |
|---|
| 67 | | - int (*func)(struct context *oldc, struct context *newc, void *args); |
|---|
| 68 | + int (*func)(struct context *oldc, struct context *newc, void *args, gfp_t gfp_flags); |
|---|
| 68 | 69 | void *args; |
|---|
| 69 | 70 | struct sidtab *target; |
|---|
| 70 | 71 | }; |
|---|
| .. | .. |
|---|
| 85 | 86 | u32 count; |
|---|
| 86 | 87 | /* access only under spinlock */ |
|---|
| 87 | 88 | struct sidtab_convert_params *convert; |
|---|
| 89 | + bool frozen; |
|---|
| 88 | 90 | spinlock_t lock; |
|---|
| 91 | + |
|---|
| 92 | +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 |
|---|
| 93 | + /* SID -> context string cache */ |
|---|
| 94 | + u32 cache_free_slots; |
|---|
| 95 | + struct list_head cache_lru_list; |
|---|
| 96 | + spinlock_t cache_lock; |
|---|
| 97 | +#endif |
|---|
| 89 | 98 | |
|---|
| 90 | 99 | /* index == SID - 1 (no entry for SECSID_NULL) */ |
|---|
| 91 | 100 | struct sidtab_isid_entry isids[SECINITSID_NUM]; |
|---|
| .. | .. |
|---|
| 96 | 105 | |
|---|
| 97 | 106 | int sidtab_init(struct sidtab *s); |
|---|
| 98 | 107 | int sidtab_set_initial(struct sidtab *s, u32 sid, struct context *context); |
|---|
| 99 | | -struct context *sidtab_search(struct sidtab *s, u32 sid); |
|---|
| 100 | | -struct context *sidtab_search_force(struct sidtab *s, u32 sid); |
|---|
| 108 | +struct sidtab_entry *sidtab_search_entry(struct sidtab *s, u32 sid); |
|---|
| 109 | +struct sidtab_entry *sidtab_search_entry_force(struct sidtab *s, u32 sid); |
|---|
| 110 | + |
|---|
| 111 | +static inline struct context *sidtab_search(struct sidtab *s, u32 sid) |
|---|
| 112 | +{ |
|---|
| 113 | + struct sidtab_entry *entry = sidtab_search_entry(s, sid); |
|---|
| 114 | + |
|---|
| 115 | + return entry ? &entry->context : NULL; |
|---|
| 116 | +} |
|---|
| 117 | + |
|---|
| 118 | +static inline struct context *sidtab_search_force(struct sidtab *s, u32 sid) |
|---|
| 119 | +{ |
|---|
| 120 | + struct sidtab_entry *entry = sidtab_search_entry_force(s, sid); |
|---|
| 121 | + |
|---|
| 122 | + return entry ? &entry->context : NULL; |
|---|
| 123 | +} |
|---|
| 101 | 124 | |
|---|
| 102 | 125 | int sidtab_convert(struct sidtab *s, struct sidtab_convert_params *params); |
|---|
| 126 | + |
|---|
| 127 | +void sidtab_cancel_convert(struct sidtab *s); |
|---|
| 128 | + |
|---|
| 129 | +void sidtab_freeze_begin(struct sidtab *s, unsigned long *flags) __acquires(&s->lock); |
|---|
| 130 | +void sidtab_freeze_end(struct sidtab *s, unsigned long *flags) __releases(&s->lock); |
|---|
| 103 | 131 | |
|---|
| 104 | 132 | int sidtab_context_to_sid(struct sidtab *s, struct context *context, u32 *sid); |
|---|
| 105 | 133 | |
|---|
| .. | .. |
|---|
| 107 | 135 | |
|---|
| 108 | 136 | int sidtab_hash_stats(struct sidtab *sidtab, char *page); |
|---|
| 109 | 137 | |
|---|
| 138 | +#if CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 |
|---|
| 139 | +void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, |
|---|
| 140 | + const char *str, u32 str_len); |
|---|
| 141 | +int sidtab_sid2str_get(struct sidtab *s, struct sidtab_entry *entry, |
|---|
| 142 | + char **out, u32 *out_len); |
|---|
| 143 | +#else |
|---|
| 144 | +static inline void sidtab_sid2str_put(struct sidtab *s, |
|---|
| 145 | + struct sidtab_entry *entry, |
|---|
| 146 | + const char *str, u32 str_len) |
|---|
| 147 | +{ |
|---|
| 148 | +} |
|---|
| 149 | +static inline int sidtab_sid2str_get(struct sidtab *s, |
|---|
| 150 | + struct sidtab_entry *entry, |
|---|
| 151 | + char **out, u32 *out_len) |
|---|
| 152 | +{ |
|---|
| 153 | + return -ENOENT; |
|---|
| 154 | +} |
|---|
| 155 | +#endif /* CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE > 0 */ |
|---|
| 156 | + |
|---|
| 110 | 157 | #endif /* _SS_SIDTAB_H_ */ |
|---|
| 111 | 158 | |
|---|
| 112 | 159 | |
|---|