aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/selinux/ss/sidtab.c39
-rw-r--r--security/selinux/ss/sidtab.h2
2 files changed, 39 insertions, 2 deletions
diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
index e817989764cd..5840a35155fc 100644
--- a/security/selinux/ss/sidtab.c
+++ b/security/selinux/ss/sidtab.c
@@ -147,6 +147,17 @@ out:
147 return rc; 147 return rc;
148} 148}
149 149
150static void sidtab_update_cache(struct sidtab *s, struct sidtab_node *n, int loc)
151{
152 BUG_ON(loc >= SIDTAB_CACHE_LEN);
153
154 while (loc > 0) {
155 s->cache[loc] = s->cache[loc - 1];
156 loc--;
157 }
158 s->cache[0] = n;
159}
160
150static inline u32 sidtab_search_context(struct sidtab *s, 161static inline u32 sidtab_search_context(struct sidtab *s,
151 struct context *context) 162 struct context *context)
152{ 163{
@@ -156,14 +167,33 @@ static inline u32 sidtab_search_context(struct sidtab *s,
156 for (i = 0; i < SIDTAB_SIZE; i++) { 167 for (i = 0; i < SIDTAB_SIZE; i++) {
157 cur = s->htable[i]; 168 cur = s->htable[i];
158 while (cur) { 169 while (cur) {
159 if (context_cmp(&cur->context, context)) 170 if (context_cmp(&cur->context, context)) {
171 sidtab_update_cache(s, cur, SIDTAB_CACHE_LEN - 1);
160 return cur->sid; 172 return cur->sid;
173 }
161 cur = cur->next; 174 cur = cur->next;
162 } 175 }
163 } 176 }
164 return 0; 177 return 0;
165} 178}
166 179
180static inline u32 sidtab_search_cache(struct sidtab *s, struct context *context)
181{
182 int i;
183 struct sidtab_node *node;
184
185 for (i = 0; i < SIDTAB_CACHE_LEN; i++) {
186 node = s->cache[i];
187 if (unlikely(!node))
188 return 0;
189 if (context_cmp(&node->context, context)) {
190 sidtab_update_cache(s, node, i);
191 return node->sid;
192 }
193 }
194 return 0;
195}
196
167int sidtab_context_to_sid(struct sidtab *s, 197int sidtab_context_to_sid(struct sidtab *s,
168 struct context *context, 198 struct context *context,
169 u32 *out_sid) 199 u32 *out_sid)
@@ -174,7 +204,9 @@ int sidtab_context_to_sid(struct sidtab *s,
174 204
175 *out_sid = SECSID_NULL; 205 *out_sid = SECSID_NULL;
176 206
177 sid = sidtab_search_context(s, context); 207 sid = sidtab_search_cache(s, context);
208 if (!sid)
209 sid = sidtab_search_context(s, context);
178 if (!sid) { 210 if (!sid) {
179 spin_lock_irqsave(&s->lock, flags); 211 spin_lock_irqsave(&s->lock, flags);
180 /* Rescan now that we hold the lock. */ 212 /* Rescan now that we hold the lock. */
@@ -259,12 +291,15 @@ void sidtab_destroy(struct sidtab *s)
259void sidtab_set(struct sidtab *dst, struct sidtab *src) 291void sidtab_set(struct sidtab *dst, struct sidtab *src)
260{ 292{
261 unsigned long flags; 293 unsigned long flags;
294 int i;
262 295
263 spin_lock_irqsave(&src->lock, flags); 296 spin_lock_irqsave(&src->lock, flags);
264 dst->htable = src->htable; 297 dst->htable = src->htable;
265 dst->nel = src->nel; 298 dst->nel = src->nel;
266 dst->next_sid = src->next_sid; 299 dst->next_sid = src->next_sid;
267 dst->shutdown = 0; 300 dst->shutdown = 0;
301 for (i = 0; i < SIDTAB_CACHE_LEN; i++)
302 dst->cache[i] = NULL;
268 spin_unlock_irqrestore(&src->lock, flags); 303 spin_unlock_irqrestore(&src->lock, flags);
269} 304}
270 305
diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
index 64ea5b1cdea4..84dc154d9389 100644
--- a/security/selinux/ss/sidtab.h
+++ b/security/selinux/ss/sidtab.h
@@ -26,6 +26,8 @@ struct sidtab {
26 unsigned int nel; /* number of elements */ 26 unsigned int nel; /* number of elements */
27 unsigned int next_sid; /* next SID to allocate */ 27 unsigned int next_sid; /* next SID to allocate */
28 unsigned char shutdown; 28 unsigned char shutdown;
29#define SIDTAB_CACHE_LEN 3
30 struct sidtab_node *cache[SIDTAB_CACHE_LEN];
29 spinlock_t lock; 31 spinlock_t lock;
30}; 32};
31 33