~ubuntu-branches/ubuntu/quantal/linux-lowlatency/quantal-proposed

« back to all changes in this revision

Viewing changes to security/keys/gc.c

  • Committer: Package Import Robot
  • Author(s): Andy Whitcroft, Andy Whitcroft
  • Date: 2012-06-21 09:16:38 UTC
  • Revision ID: package-import@ubuntu.com-20120621091638-gubhv4nox8xez1ct
Tags: 3.5.0-1.1
[ Andy Whitcroft]

* Rebuild lowlatency against Ubuntu-3.5.0-1.1
* All new configuration system to allow configuration deltas to be
  exposed via debian.lowlatency/config-delta

Show diffs side-by-side

added added

removed removed

Lines of Context:
72
72
}
73
73
 
74
74
/*
 
75
 * Schedule a dead links collection run.
 
76
 */
 
77
void key_schedule_gc_links(void)
 
78
{
 
79
        set_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags);
 
80
        queue_work(system_nrt_wq, &key_gc_work);
 
81
}
 
82
 
 
83
/*
75
84
 * Some key's cleanup time was met after it expired, so we need to get the
76
85
 * reaper to go through a cycle finding expired keys.
77
86
 */
79
88
{
80
89
        kenter("");
81
90
        key_gc_next_run = LONG_MAX;
82
 
        set_bit(KEY_GC_KEY_EXPIRED, &key_gc_flags);
83
 
        queue_work(system_nrt_wq, &key_gc_work);
 
91
        key_schedule_gc_links();
84
92
}
85
93
 
86
94
/*
131
139
static void key_gc_keyring(struct key *keyring, time_t limit)
132
140
{
133
141
        struct keyring_list *klist;
134
 
        struct key *key;
135
142
        int loop;
136
143
 
137
144
        kenter("%x", key_serial(keyring));
138
145
 
139
 
        if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
 
146
        if (keyring->flags & ((1 << KEY_FLAG_INVALIDATED) |
 
147
                              (1 << KEY_FLAG_REVOKED)))
140
148
                goto dont_gc;
141
149
 
142
150
        /* scan the keyring looking for dead keys */
145
153
        if (!klist)
146
154
                goto unlock_dont_gc;
147
155
 
148
 
        for (loop = klist->nkeys - 1; loop >= 0; loop--) {
149
 
                key = klist->keys[loop];
150
 
                if (test_bit(KEY_FLAG_DEAD, &key->flags) ||
151
 
                    (key->expiry > 0 && key->expiry <= limit))
 
156
        loop = klist->nkeys;
 
157
        smp_rmb();
 
158
        for (loop--; loop >= 0; loop--) {
 
159
                struct key *key = rcu_dereference(klist->keys[loop]);
 
160
                if (key_is_dead(key, limit))
152
161
                        goto do_gc;
153
162
        }
154
163
 
166
175
}
167
176
 
168
177
/*
169
 
 * Garbage collect an unreferenced, detached key
 
178
 * Garbage collect a list of unreferenced, detached keys
170
179
 */
171
 
static noinline void key_gc_unused_key(struct key *key)
 
180
static noinline void key_gc_unused_keys(struct list_head *keys)
172
181
{
173
 
        key_check(key);
174
 
 
175
 
        security_key_free(key);
176
 
 
177
 
        /* deal with the user's key tracking and quota */
178
 
        if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
179
 
                spin_lock(&key->user->lock);
180
 
                key->user->qnkeys--;
181
 
                key->user->qnbytes -= key->quotalen;
182
 
                spin_unlock(&key->user->lock);
183
 
        }
184
 
 
185
 
        atomic_dec(&key->user->nkeys);
186
 
        if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
187
 
                atomic_dec(&key->user->nikeys);
188
 
 
189
 
        key_user_put(key->user);
190
 
 
191
 
        /* now throw away the key memory */
192
 
        if (key->type->destroy)
193
 
                key->type->destroy(key);
194
 
 
195
 
        kfree(key->description);
 
182
        while (!list_empty(keys)) {
 
183
                struct key *key =
 
184
                        list_entry(keys->next, struct key, graveyard_link);
 
185
                list_del(&key->graveyard_link);
 
186
 
 
187
                kdebug("- %u", key->serial);
 
188
                key_check(key);
 
189
 
 
190
                security_key_free(key);
 
191
 
 
192
                /* deal with the user's key tracking and quota */
 
193
                if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
 
194
                        spin_lock(&key->user->lock);
 
195
                        key->user->qnkeys--;
 
196
                        key->user->qnbytes -= key->quotalen;
 
197
                        spin_unlock(&key->user->lock);
 
198
                }
 
199
 
 
200
                atomic_dec(&key->user->nkeys);
 
201
                if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
 
202
                        atomic_dec(&key->user->nikeys);
 
203
 
 
204
                key_user_put(key->user);
 
205
 
 
206
                /* now throw away the key memory */
 
207
                if (key->type->destroy)
 
208
                        key->type->destroy(key);
 
209
 
 
210
                kfree(key->description);
196
211
 
197
212
#ifdef KEY_DEBUGGING
198
 
        key->magic = KEY_DEBUG_MAGIC_X;
 
213
                key->magic = KEY_DEBUG_MAGIC_X;
199
214
#endif
200
 
        kmem_cache_free(key_jar, key);
 
215
                kmem_cache_free(key_jar, key);
 
216
        }
201
217
}
202
218
 
203
219
/*
209
225
 */
210
226
static void key_garbage_collector(struct work_struct *work)
211
227
{
 
228
        static LIST_HEAD(graveyard);
212
229
        static u8 gc_state;             /* Internal persistent state */
213
230
#define KEY_GC_REAP_AGAIN       0x01    /* - Need another cycle */
214
231
#define KEY_GC_REAPING_LINKS    0x02    /* - We need to reap links */
314
331
                key_schedule_gc(new_timer);
315
332
        }
316
333
 
317
 
        if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2)) {
318
 
                /* Make sure everyone revalidates their keys if we marked a
319
 
                 * bunch as being dead and make sure all keyring ex-payloads
320
 
                 * are destroyed.
 
334
        if (unlikely(gc_state & KEY_GC_REAPING_DEAD_2) ||
 
335
            !list_empty(&graveyard)) {
 
336
                /* Make sure that all pending keyring payload destructions are
 
337
                 * fulfilled and that people aren't now looking at dead or
 
338
                 * dying keys that they don't have a reference upon or a link
 
339
                 * to.
321
340
                 */
322
 
                kdebug("dead sync");
 
341
                kdebug("gc sync");
323
342
                synchronize_rcu();
324
343
        }
325
344
 
 
345
        if (!list_empty(&graveyard)) {
 
346
                kdebug("gc keys");
 
347
                key_gc_unused_keys(&graveyard);
 
348
        }
 
349
 
326
350
        if (unlikely(gc_state & (KEY_GC_REAPING_DEAD_1 |
327
351
                                 KEY_GC_REAPING_DEAD_2))) {
328
352
                if (!(gc_state & KEY_GC_FOUND_DEAD_KEY)) {
357
381
        rb_erase(&key->serial_node, &key_serial_tree);
358
382
        spin_unlock(&key_serial_lock);
359
383
 
360
 
        key_gc_unused_key(key);
 
384
        list_add_tail(&key->graveyard_link, &graveyard);
361
385
        gc_state |= KEY_GC_REAP_AGAIN;
362
386
        goto maybe_resched;
363
387