.. | .. |
---|
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 | |
---|